From: Greg Kroah-Hartman gregkh@linuxfoundation.org
This is the start of the stable review cycle for the 5.10.24 release. There are 290 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 Wed, 17 Mar 2021 13:55:02 +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.10.24-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.10.y and the diffstat can be found below.
thanks,
greg k-h
------------- Pseudo-Shortlog of commits:
Greg Kroah-Hartman gregkh@linuxfoundation.org Linux 5.10.24-rc1
Christoph Hellwig hch@lst.de RDMA/umem: Use ib_dma_max_seg_size instead of dma_get_max_seg_size
Andrew Scull ascull@google.com KVM: arm64: Fix nVHE hyp panic host context restore
Juergen Gross jgross@suse.com xen/events: avoid handling the same event on two cpus at the same time
Juergen Gross jgross@suse.com xen/events: don't unmask an event channel when an eoi is pending
Mike Rapoport rppt@kernel.org mm/page_alloc.c: refactor initialization of struct page for holes in memory layout
Marc Zyngier maz@kernel.org KVM: arm64: Ensure I-cache isolation between vcpus of a same VM
Suren Baghdasaryan surenb@google.com mm/madvise: replace ptrace attach requirement for process_madvise
Nadav Amit namit@vmware.com mm/userfaultfd: fix memory corruption due to writeprotect
Marc Zyngier maz@kernel.org KVM: arm64: Fix exclusive limit for IPA size
Marc Zyngier maz@kernel.org KVM: arm64: Reject VM creation when the default IPA size is unsupported
Suzuki K Poulose suzuki.poulose@arm.com KVM: arm64: nvhe: Save the SPE context early
Will Deacon will@kernel.org KVM: arm64: Avoid corrupting vCPU context register in guest exit
Jia He justin.he@arm.com KVM: arm64: Fix range alignment when walking page tables
Wanpeng Li wanpengli@tencent.com KVM: kvmclock: Fix vCPUs > 64 can't be online/hotpluged
Sean Christopherson seanjc@google.com KVM: x86: Ensure deadline timer has truly expired before posting its IRQ
Andy Lutomirski luto@kernel.org x86/entry: Fix entry/exit mismatch on failed fast 32-bit syscalls
Joerg Roedel jroedel@suse.de x86/sev-es: Use __copy_from_user_inatomic()
Joerg Roedel jroedel@suse.de x86/sev-es: Correctly track IRQ states in runtime #VC handler
Thomas Gleixner tglx@linutronix.de x86/entry: Move nmi entry/exit into common code
Joerg Roedel jroedel@suse.de x86/sev-es: Check regs->sp is trusted before adjusting #VC IST stack
Joerg Roedel jroedel@suse.de x86/sev-es: Introduce ip_within_syscall_gap() helper
Josh Poimboeuf jpoimboe@redhat.com x86/unwind/orc: Disable KASAN checking in the ORC unwinder, part 2
Lior Ribak liorribak@gmail.com binfmt_misc: fix possible deadlock in bm_register_write
Christophe Leroy christophe.leroy@csgroup.eu powerpc: Fix missing declaration of [en/dis]able_kernel_vsx()
Nicholas Piggin npiggin@gmail.com powerpc: Fix inverted SET_FULL_REGS bitop
Naveen N. Rao naveen.n.rao@linux.vnet.ibm.com powerpc/64s: Fix instruction encoding for lis in ppc_function_entry()
Ard Biesheuvel ardb@kernel.org efi: stub: omit SetVirtualAddressMap() if marked unsupported in RT_PROP table
Mathieu Desnoyers mathieu.desnoyers@efficios.com sched/membarrier: fix missing local execution of ipi_sync_rq_state()
Arnd Bergmann arnd@arndb.de linux/compiler-clang.h: define HAVE_BUILTIN_BSWAP*
Minchan Kim minchan@kernel.org zram: fix return value on writeback_store
Alexey Dobriyan adobriyan@gmail.com prctl: fix PR_SET_MM_AUXV kernel stack leak
Matthew Wilcox (Oracle) willy@infradead.org include/linux/sched/mm.h: use rcu_dereference in in_vfork()
Arnd Bergmann arnd@arndb.de stop_machine: mark helpers __always_inline
Peter Zijlstra peterz@infradead.org seqlock,lockdep: Fix seqcount_latch_init()
Daniel Axtens dja@axtens.net powerpc/64s/exception: Clean up a missed SRR specifier
Anna-Maria Behnsen anna-maria@linutronix.de hrtimer: Update softirq_expires_next correctly after __hrtimer_get_next_event()
Kan Liang kan.liang@linux.intel.com perf/x86/intel: Set PERF_ATTACH_SCHED_CB for large PEBS and LBR
Kan Liang kan.liang@linux.intel.com perf/core: Flush PMU internal buffers for per-CPU events
Ard Biesheuvel ardb@kernel.org arm64: mm: use a 48-bit ID map when possible on 52-bit VA builds
Daiyue Zhang zhangdaiyue1@huawei.com configfs: fix a use-after-free in __configfs_open_file
James Smart jsmart2021@gmail.com nvme-fc: fix racing controller reset and create association
Jia-Ju Bai baijiaju1990@gmail.com block: rsxx: fix error return code of rsxx_pci_probe()
Ondrej Mosnacek omosnace@redhat.com NFSv4.2: fix return value of _nfs4_get_security_label()
Trond Myklebust trond.myklebust@hammerspace.com NFS: Don't gratuitously clear the inode cache when lookup failed
Trond Myklebust trond.myklebust@hammerspace.com NFS: Don't revalidate the directory permissions on a lookup failure
Benjamin Coddington bcodding@redhat.com SUNRPC: Set memalloc_nofs_save() for sync tasks
Anshuman Khandual anshuman.khandual@arm.com arm64/mm: Fix pfn_valid() for ZONE_DEVICE based memory
Wei Yongjun weiyongjun1@huawei.com cpufreq: qcom-hw: Fix return value check in qcom_cpufreq_hw_cpu_init()
Shawn Guo shawn.guo@linaro.org cpufreq: qcom-hw: fix dereferencing freed memory 'data'
Sergey Shtylyov s.shtylyov@omprussia.ru sh_eth: fix TRSCER mask for R7S72100
Ian Abbott abbotti@mev.co.uk staging: comedi: pcl818: Fix endian problem for AI command data
Ian Abbott abbotti@mev.co.uk staging: comedi: pcl711: Fix endian problem for AI command data
Ian Abbott abbotti@mev.co.uk staging: comedi: me4000: Fix endian problem for AI command data
Ian Abbott abbotti@mev.co.uk staging: comedi: dmm32at: Fix endian problem for AI command data
Ian Abbott abbotti@mev.co.uk staging: comedi: das800: Fix endian problem for AI command data
Ian Abbott abbotti@mev.co.uk staging: comedi: das6402: Fix endian problem for AI command data
Ian Abbott abbotti@mev.co.uk staging: comedi: adv_pci1710: Fix endian problem for AI command data
Ian Abbott abbotti@mev.co.uk staging: comedi: addi_apci_1500: Fix endian problem for command sample
Ian Abbott abbotti@mev.co.uk staging: comedi: addi_apci_1032: Fix endian problem for COS sample
Lee Gibson leegib@gmail.com staging: rtl8192e: Fix possible buffer overflow in _rtl92e_wx_set_scan
Lee Gibson leegib@gmail.com staging: rtl8712: Fix possible buffer overflow in r8712_sitesurvey_cmd
Dan Carpenter dan.carpenter@oracle.com staging: ks7010: prevent buffer overflow in ks_wlan_set_scan()
Dan Carpenter dan.carpenter@oracle.com staging: rtl8188eu: fix potential memory corruption in rtw_check_beacon_data()
Dan Carpenter dan.carpenter@oracle.com staging: rtl8712: unterminated string leads to read overflow
Dan Carpenter dan.carpenter@oracle.com staging: rtl8188eu: prevent ->ssid overflow in rtw_wx_set_scan()
Dan Carpenter dan.carpenter@oracle.com staging: rtl8192u: fix ->ssid overflow in r8192_wx_set_scan()
Dmitry Baryshkov dmitry.baryshkov@linaro.org misc: fastrpc: restrict user apps from sending kernel RPC messages
Shile Zhang shile.zhang@linux.alibaba.com misc/pvpanic: Export module FDT device table
Alexander Shiyan shc_work@mail.ru Revert "serial: max310x: rework RX interrupt handling"
Shuah Khan skhan@linuxfoundation.org usbip: fix vudc usbip_sockfd_store races leading to gpf
Shuah Khan skhan@linuxfoundation.org usbip: fix vhci_hcd attach_store() races leading to gpf
Shuah Khan skhan@linuxfoundation.org usbip: fix stub_dev usbip_sockfd_store() races leading to gpf
Shuah Khan skhan@linuxfoundation.org usbip: fix vudc to check for stream socket
Shuah Khan skhan@linuxfoundation.org usbip: fix vhci_hcd to check for stream socket
Shuah Khan skhan@linuxfoundation.org usbip: fix stub_dev to check for stream socket
Sebastian Reichel sebastian.reichel@collabora.com USB: serial: cp210x: add some more GE USB IDs
Karan Singhal karan.singhal@acuitybrands.com USB: serial: cp210x: add ID for Acuity Brands nLight Air Adapter
Niv Sardi xaiki@evilgiggle.com USB: serial: ch341: add new Product ID
Pavel Skripkin paskripkin@gmail.com USB: serial: io_edgeport: fix memory leak in edge_startup
Mathias Nyman mathias.nyman@linux.intel.com xhci: Fix repeated xhci wake after suspend due to uncleared internal wake state
Forest Crossman cyrozap@gmail.com usb: xhci: Fix ASMedia ASM1042A and ASM3242 DMA addressing
Mathias Nyman mathias.nyman@linux.intel.com xhci: Improve detection of device initiated wake signal.
Stanislaw Gruszka stf_xl@wp.pl usb: xhci: do not perform Soft Retry for some xHCI hosts
Yoshihiro Shimoda yoshihiro.shimoda.uh@renesas.com usb: renesas_usbhs: Clear PIPECFG for re-enabling pipe with other EPNUM
Pete Zaitcev zaitcev@redhat.com USB: usblp: fix a hang in poll() if disconnected
Matthias Kaehlcke mka@chromium.org usb: dwc3: qcom: Honor wakeup enabled/disabled state
Shawn Guo shawn.guo@linaro.org usb: dwc3: qcom: add ACPI device id for sc8180x
Shawn Guo shawn.guo@linaro.org usb: dwc3: qcom: add URS Host support for sdm845 ACPI boot
Serge Semin Sergey.Semin@baikalelectronics.ru usb: dwc3: qcom: Add missing DWC3 OF node refcount decrement
Ruslan Bilovol ruslan.bilovol@gmail.com usb: gadget: f_uac1: stop playback on function disable
Ruslan Bilovol ruslan.bilovol@gmail.com usb: gadget: f_uac2: always increase endpoint max_packet_size by one audio slot
Dan Carpenter dan.carpenter@oracle.com USB: gadget: u_ether: Fix a configfs return code
Wei Yongjun weiyongjun1@huawei.com USB: gadget: udc: s3c2410_udc: fix return value check in s3c2410_udc_probe()
Yorick de Wid ydewid@gmail.com Goodix Fingerprint device is not a modem
Paulo Alcantara pc@cjr.nz cifs: do not send close in compound create+close requests
Frank Li lznuaa@gmail.com mmc: cqhci: Fix random crash when remove mmc module/card
Adrian Hunter adrian.hunter@intel.com mmc: core: Fix partition switch time for eMMC
Yann Gautier yann.gautier@foss.st.com mmc: mmci: Add MMC_CAP_NEED_RSP_BUSY for the stm32 variants
Juergen Gross jgross@suse.com xen/events: reset affinity of 2-level event when tearing it down
Heikki Krogerus heikki.krogerus@linux.intel.com software node: Fix node registration
Stefan Haberland sth@linux.ibm.com s390/dasd: fix hanging IO request during DASD driver unbind
Stefan Haberland sth@linux.ibm.com s390/dasd: fix hanging DASD driver unbind
Rob Herring robh@kernel.org arm64: perf: Fix 64-bit event counter read truncation
Catalin Marinas catalin.marinas@arm.com arm64: mte: Map hotplugged memory as Normal Tagged
Andrey Konovalov andreyknvl@google.com arm64: kasan: fix page_alloc tagging with DEBUG_VIRTUAL
Jan Kara jack@suse.cz block: Try to handle busy underlying device on discard
Shin'ichiro Kawasaki shinichiro.kawasaki@wdc.com block: Discard page cache of zone reset target range
Eric W. Biederman ebiederm@xmission.com Revert 95ebabde382c ("capabilities: Don't allow writing ambiguous v3 file capabilities")
Pavel Skripkin paskripkin@gmail.com ALSA: usb-audio: fix use after free in usb_audio_disconnect
Pavel Skripkin paskripkin@gmail.com ALSA: usb-audio: fix NULL ptr dereference in usb_audio_probe
Kai-Heng Feng kai.heng.feng@canonical.com ALSA: usb-audio: Disable USB autosuspend properly in setup_disable_autosuspend()
Takashi Iwai tiwai@suse.de ALSA: usb-audio: Apply the control quirk to Plantronics headsets
Takashi Iwai tiwai@suse.de ALSA: usb-audio: Fix "cannot get freq eq" errors on Dell AE515 sound bar
Takashi Iwai tiwai@suse.de ALSA: hda: Avoid spurious unsol event handling during S3/S4
Takashi Iwai tiwai@suse.de ALSA: hda: Flush pending unsolicited events before suspend
Takashi Iwai tiwai@suse.de ALSA: hda: Drop the BATCH workaround for AMD controllers
Simeon Simeonoff sim.simeonoff@gmail.com ALSA: hda/ca0132: Add Sound BlasterX AE-5 Plus support
Takashi Iwai tiwai@suse.de ALSA: hda/conexant: Add quirk for mute LED control on HP ZBook G5
Takashi Iwai tiwai@suse.de ALSA: hda/hdmi: Cancel pending works before suspend
John Ernberg john.ernberg@actia.se ALSA: usb: Add Plantronics C320-M USB ctrl msg delay quirk
Ard Biesheuvel ardb@kernel.org ARM: efistub: replace adrl pseudo-op with adr_l macro invocation
Ard Biesheuvel ardb@kernel.org ARM: assembler: introduce adr_l, ldr_l and str_l macros
Jian Cai jiancai@google.com ARM: 9029/1: Make iwmmxt.S support Clang's integrated assembler
Jeremy Linton jeremy.linton@arm.com mmc: sdhci: Update firmware interface API
AngeloGioacchino Del Regno angelogioacchino.delregno@somainline.org clk: qcom: gpucc-msm8998: Add resets, cxc, fix flags on gpu_gx_gdsc
Aleksandr Miloserdov a.miloserdov@yadro.com scsi: target: core: Prevent underflow for service actions
Aleksandr Miloserdov a.miloserdov@yadro.com scsi: target: core: Add cmd length set before cmd complete
Mike Christie michael.christie@oracle.com scsi: libiscsi: Fix iscsi_prep_scsi_cmd_pdu() error handling
Lin Feng linf@wangsu.com sysctl.c: fix underflow value setting risk in vm_table
David Hildenbrand david@redhat.com drivers/base/memory: don't store phys_device in memory blocks
Heiko Carstens hca@linux.ibm.com s390/smp: __smp_rescan_cpus() - move cpumask away from stack
Andrey Konovalov andreyknvl@google.com kasan: fix memory corruption in kasan_bitops_tags test
Keita Suzuki keitasuzuki.park@sslab.ics.keio.ac.jp i40e: Fix memory leak in i40e_probe
Geert Uytterhoeven geert+renesas@glider.be PCI: Fix pci_register_io_range() memory leak
Sasha Levin sashal@kernel.org kbuild: clamp SUBLEVEL to 255
Theodore Ts'o tytso@mit.edu ext4: don't try to processed freed blocks until mballoc is initialized
Bjorn Helgaas bhelgaas@google.com PCI/LINK: Remove bandwidth notification
Arnd Bergmann arnd@arndb.de drivers/base: build kunit tests without structleak plugin
Krzysztof Wilczyński kw@linux.com PCI: mediatek: Add missing of_node_put() to fix reference leak
Martin Kaiser martin@kaiser.cx PCI: xgene-msi: Fix race in installing chained irq handler
Ronald Tschalär ronald@innovation.ch Input: applespi - don't wait for responses to commands indefinitely.
Khalid Aziz khalid.aziz@oracle.com sparc64: Use arch_validate_flags() to validate ADI flag
Andreas Larsson andreas@gaisler.com sparc32: Limit memblock allocation to low memory
AngeloGioacchino Del Regno angelogioacchino.delregno@somainline.org clk: qcom: gdsc: Implement NO_RET_PERIPH flag
Suravee Suthikulpanit suravee.suthikulpanit@amd.com iommu/amd: Fix performance counter initialization
Michael Ellerman mpe@ellerman.id.au powerpc/64: Fix stack trace not displaying final frame
Filipe Laíns lains@riseup.net HID: logitech-dj: add support for the new lightspeed connection iteration
Athira Rajeev atrajeev@linux.vnet.ibm.com powerpc/perf: Record counter overflow always if SAMPLE_IP is unset
Nicholas Piggin npiggin@gmail.com powerpc: improve handling of unrecoverable system reset
Alain Volmat alain.volmat@foss.st.com spi: stm32: make spurious and overrun interrupts visible
Oliver O'Halloran oohall@gmail.com powerpc/pci: Add ppc_md.discover_phbs()
Lubomir Rintel lkundrak@v3.sk Platform: OLPC: Fix probe error handling
Jeremy Linton jeremy.linton@arm.com mmc: sdhci-iproc: Add ACPI bindings for the RPi
Chaotian Jing chaotian.jing@mediatek.com mmc: mediatek: fix race condition between msdc_request_timeout and irq
Christophe JAILLET christophe.jaillet@wanadoo.fr mmc: mxs-mmc: Fix a resource leak in an error handling path in 'mxs_mmc_probe()'
Lu Baolu baolu.lu@linux.intel.com iommu/vt-d: Clear PRQ overflow only when PRQ is empty
Steven J. Magnani magnani@ieee.org udf: fix silent AED tagLocation corruption
Jaegeuk Kim jaegeuk@kernel.org scsi: ufs: WB is only available on LUN #0 to #7
Wolfram Sang wsa+renesas@sang-engineering.com i2c: rcar: optimize cacheline to minimize HW race condition
Wolfram Sang wsa+renesas@sang-engineering.com i2c: rcar: faster irq code to minimize HW race condition
Kalle Valo kvalo@codeaurora.org ath11k: fix AP mode for QCA6390
Carl Huang cjhuang@codeaurora.org ath11k: start vdev if a bss peer is already created
Ritesh Singh ritesi@codeaurora.org ath11k: peer delete synchronization with firmware
Vladimir Oltean vladimir.oltean@nxp.com net: enetc: initialize RFS/RSS memories for unused ports too
Arnd Bergmann arnd@arndb.de enetc: Fix unused var build warning for CONFIG_OF
DENG Qingfang dqfext@gmail.com net: dsa: tag_mtk: fix 802.1ad VLAN egress
Vladimir Oltean vladimir.oltean@nxp.com net: dsa: tag_ar9331: let DSA core deal with TX reallocation
Vladimir Oltean vladimir.oltean@nxp.com net: dsa: tag_gswip: let DSA core deal with TX reallocation
Vladimir Oltean vladimir.oltean@nxp.com net: dsa: tag_dsa: let DSA core deal with TX reallocation
Vladimir Oltean vladimir.oltean@nxp.com net: dsa: tag_brcm: let DSA core deal with TX reallocation
Vladimir Oltean vladimir.oltean@nxp.com net: dsa: tag_edsa: let DSA core deal with TX reallocation
Vladimir Oltean vladimir.oltean@nxp.com net: dsa: tag_lan9303: let DSA core deal with TX reallocation
Vladimir Oltean vladimir.oltean@nxp.com net: dsa: tag_mtk: let DSA core deal with TX reallocation
Vladimir Oltean vladimir.oltean@nxp.com net: dsa: tag_ocelot: let DSA core deal with TX reallocation
Vladimir Oltean vladimir.oltean@nxp.com net: dsa: tag_qca: let DSA core deal with TX reallocation
Christian Eggers ceggers@arri.de net: dsa: trailer: don't allocate additional memory for padding/tagging
Christian Eggers ceggers@arri.de net: dsa: tag_ksz: don't allocate additional memory for padding/tagging
Vladimir Oltean vladimir.oltean@nxp.com net: dsa: implement a central TX reallocation procedure
Julian Wiedmann jwi@linux.ibm.com s390/qeth: fix notification for pending buffers during teardown
Julian Wiedmann jwi@linux.ibm.com s390/qeth: improve completion of pending TX buffers
Julian Wiedmann jwi@linux.ibm.com s390/qeth: remove QETH_QDIO_BUF_HANDLED_DELAYED state
Julian Wiedmann jwi@linux.ibm.com s390/qeth: don't replace a fully completed async TX buffer
Jian Shen shenjian15@huawei.com net: hns3: fix error mask definition of flow director
Aurelien Aptel aaptel@suse.com cifs: fix credit accounting for extra channel
Hans Verkuil hverkuil@xs4all.nl media: rc: compile rc-cec.c into rc-core
Biju Das biju.das.jz@bp.renesas.com media: v4l: vsp1: Fix bru null pointer access
Biju Das biju.das.jz@bp.renesas.com media: v4l: vsp1: Fix uif null pointer access
Dafna Hirschfeld dafna.hirschfeld@collabora.com media: rkisp1: params: fix wrong bits settings
Maxim Mikityanskiy maxtram95@gmail.com media: usbtv: Fix deadlock on suspend
Sergey Shtylyov s.shtylyov@omprussia.ru sh_eth: fix TRSCER mask for R7S9210
Colin Ian King colin.king@canonical.com qxl: Fix uninitialised struct field head.surface_id
Wang Qing wangqing@vivo.com s390/crypto: return -EFAULT if copy_to_user() fails
Eric Farman farman@linux.ibm.com s390/cio: return -EFAULT if copy_to_user() fails
Tvrtko Ursulin tvrtko.ursulin@intel.com drm/i915: Wedge the GPU if command parser setup fails
Noralf Trønnes noralf@tronnes.org drm/shmem-helpers: vunmap: Don't put pages for dma-buf
Artem Lapkin art@khadas.com drm: meson_drv add shutdown function
Thomas Zimmermann tzimmermann@suse.de drm: Use USB controller's DMA mask when importing dmabufs
Neil Roberts nroberts@igalia.com drm/shmem-helper: Don't remove the offset in vm_area_struct pgoff
Neil Roberts nroberts@igalia.com drm/shmem-helper: Check for purged buffers in fault handler
Alex Deucher alexander.deucher@amd.com drm/amdgpu/display: handle aux backlight in backlight_get_brightness
Alex Deucher alexander.deucher@amd.com drm/amdgpu/display: don't assert in set backlight function
Alex Deucher alexander.deucher@amd.com drm/amdgpu/display: simplify backlight setting
Kenneth Feng kenneth.feng@amd.com drm/amd/pm: bug fix for pcie dpm
Holger Hoffstätte holger@applied-asynchrony.com drm/amd/display: Fix nested FPU context in dcn21_validate_bandwidth()
Holger Hoffstätte holger@applied-asynchrony.com drm/amdgpu/display: use GFP_ATOMIC in dcn21_validate_bandwidth_fp()
Takashi Iwai tiwai@suse.de drm/amd/display: Add a backlight module option
Daniel Vetter daniel.vetter@ffwll.ch drm/compat: Clear bounce structures
Johan Hovold johan@kernel.org gpio: fix gpio-device list corruption
Andy Shevchenko andriy.shevchenko@linux.intel.com gpio: pca953x: Set IRQ type when handle Intel Galileo Gen 2
Andy Shevchenko andriy.shevchenko@linux.intel.com gpiolib: Read "gpio-line-names" from a firmware node
Andy Shevchenko andriy.shevchenko@linux.intel.com gpiolib: acpi: Allow to find GpioInt() resource by name and index
Andy Shevchenko andriy.shevchenko@linux.intel.com gpiolib: acpi: Add ACPI_GPIO_QUIRK_ABSOLUTE_NUMBER quirk
Edwin Peer edwin.peer@broadcom.com bnxt_en: reliably allocate IRQ table on reset to avoid crash
Wang Qing wangqing@vivo.com s390/cio: return -EFAULT if copy_to_user() fails again
Jian Shen shenjian15@huawei.com net: hns3: fix bug when calculating the TCAM table info
Jian Shen shenjian15@huawei.com net: hns3: fix query vlan mask value error for flow director
Ravi Bangoria ravi.bangoria@linux.ibm.com perf report: Fix -F for branch & mem modes
Ian Rogers irogers@google.com perf traceevent: Ensure read cmdlines are null terminated.
Danielle Ratson danieller@nvidia.com mlxsw: spectrum_ethtool: Add an external speed to PTYS register
Danielle Ratson danieller@nvidia.com selftests: forwarding: Fix race condition in mirror installation
Arnd Bergmann arnd@arndb.de net: phy: make mdio_bus_phy_suspend/resume as __maybe_unused
Yinjun Zhang yinjun.zhang@corigine.com ethtool: fix the check logic of at least one channel for RX/TX
Joakim Zhang qiangqing.zhang@nxp.com net: stmmac: fix wrongly set buffer2 valid when sph unsupport
Joakim Zhang qiangqing.zhang@nxp.com net: stmmac: fix watchdog timeout during suspend/resume stress test
Joakim Zhang qiangqing.zhang@nxp.com net: stmmac: stop each tx channel independently
Antonio Terceiro antonio.terceiro@linaro.org perf build: Fix ccache usage in $(CC) when generating arch errno table
Kun-Chuan Hsieh jetswayss@gmail.com tools/resolve_btfids: Fix build error with older host toolchains
Antony Antony antony@phenome.org ixgbe: fail to create xfrm offload of IPsec tunnel mode SA
Hayes Wang hayeswang@realtek.com r8169: fix r8168fp_adjust_ocp_cmd function
Julian Wiedmann jwi@linux.ibm.com s390/qeth: fix memory leak after failed TX Buffer allocation
Jia-Ju Bai baijiaju1990@gmail.com net: qrtr: fix error return code of qrtr_sendmsg()
Vladimir Oltean vladimir.oltean@nxp.com net: enetc: allow hardware timestamping on TX queues with tc-etf enabled
Paul Cercueil paul@crapouillou.net net: davicom: Fix regulator not turned off on driver removal
Paul Cercueil paul@crapouillou.net net: davicom: Fix regulator not turned off on failed probe
Xie He xie.he.0141@gmail.com net: lapbether: Remove netif_start_queue / netif_stop_queue
Wong Vee Khee vee.khee.wong@intel.com stmmac: intel: Fixes clock registration error seen for multiple interfaces
Ong Boon Leong boon.leong.ong@intel.com net: stmmac: Fix VLAN filter delete timeout issue in Intel mGBE SGMII
Paul Moore paul@paul-moore.com cipso,calipso: resolve a number of problems with the DOI refcounts
Hillf Danton hdanton@sina.com netdevsim: init u64 stats for 32bit hardware
Daniele Palmas dnlplm@gmail.com net: usb: qmi_wwan: allow qmimux add/del with master up
Vladimir Oltean vladimir.oltean@nxp.com net: dsa: sja1105: fix SGMII PCS being forced to SPEED_UNKNOWN instead of SPEED_10
Vladimir Oltean vladimir.oltean@nxp.com net: mscc: ocelot: properly reject destination IP keys in VCAP IS1
Maximilian Heyne mheyne@amazon.de net: sched: avoid duplicates in classes dump
Ido Schimmel idosch@nvidia.com nexthop: Do not flush blackhole nexthops when loopback goes down
Ong Boon Leong boon.leong.ong@intel.com net: stmmac: fix incorrect DMA channel intr enable setting of EQoS v4.10
Kevin(Yudong) Yang yyd@google.com net/mlx4_en: update moderation when config reset
Biao Huang biao.huang@mediatek.com net: ethernet: mtk-star-emac: fix wrong unmap in RX handling
Vladimir Oltean vladimir.oltean@nxp.com net: enetc: keep RX ring consumer index in sync with hardware
Vladimir Oltean vladimir.oltean@nxp.com net: enetc: remove bogus write to SIRXIDR from enetc_setup_rxbdr
Vladimir Oltean vladimir.oltean@nxp.com net: enetc: force the RGMII speed and duplex instead of operating in inband mode
Vladimir Oltean vladimir.oltean@nxp.com net: enetc: don't disable VLAN filtering in IFF_PROMISC mode
Vladimir Oltean vladimir.oltean@nxp.com net: enetc: fix incorrect TPID when receiving 802.1ad tagged packets
Vladimir Oltean vladimir.oltean@nxp.com net: enetc: take the MDIO lock only once per NAPI poll cycle
Vladimir Oltean vladimir.oltean@nxp.com net: enetc: don't overwrite the RSS indirection table when initializing
Sergey Shtylyov s.shtylyov@omprussia.ru sh_eth: fix TRSCER mask for SH771x
DENG Qingfang dqfext@gmail.com net: dsa: tag_rtl4_a: fix egress tags
Jakub Kicinski kuba@kernel.org docs: networking: drop special stable handling
Linus Torvalds torvalds@linux-foundation.org Revert "mm, slub: consider rest of partial list if acquire_slab() fails"
Paulo Alcantara pc@cjr.nz cifs: return proper error code in statfs(2)
Christian Brauner christian.brauner@ubuntu.com mount: fix mounting of detached mounts onto targets that reside on shared mounts
Christophe Leroy christophe.leroy@csgroup.eu powerpc/603: Fix protection of user pages mapped with PROT_NONE
Lorenzo Bianconi lorenzo@kernel.org mt76: dma: do not report truncated frames to mac80211
Jiri Wiesner jwiesner@suse.com ibmvnic: always store valid MAC address
Michal Suchanek msuchanek@suse.de ibmvnic: Fix possibly uninitialized old_num_tx_queues variable warning.
Maciej Fijalkowski maciej.fijalkowski@intel.com libbpf: Clear map_info before each bpf_obj_get_info_by_fd
Maciej Fijalkowski maciej.fijalkowski@intel.com samples, bpf: Add missing munmap in xdpsock
Yauheni Kaliuta yauheni.kaliuta@redhat.com selftests/bpf: Mask bpf_csum_diff() return value to 16 bits in test_verifier
Hangbin Liu liuhangbin@gmail.com selftests/bpf: No need to drop the packet when there is no geneve opt
Ilya Leoshkevich iii@linux.ibm.com selftests/bpf: Use the last page in test_snprintf_btf on s390
Guangbin Huang huangguangbin2@huawei.com net: phy: fix save wrong speed and duplex problem if autoneg is on
Jason A. Donenfeld Jason@zx2c4.com net: always use icmp{,v6}_ndo_send from ndo_start_xmit
Vasily Averin vvs@virtuozzo.com netfilter: x_tables: gpf inside xt_find_revision()
Florian Westphal fw@strlen.de netfilter: nf_nat: undo erroneous tcp edemux lookup
Eric Dumazet edumazet@google.com tcp: add sanity tests to TCP_QUEUE_SEQ
Arjun Roy arjunroy@google.com tcp: Fix sign comparison bug in getsockopt(TCP_ZEROCOPY_RECEIVE)
Torin Cooper-Bennun torin@maxiluxsystems.com can: tcan4x5x: tcan4x5x_init(): fix initialization - clear MRAM before entering Normal Mode
Joakim Zhang qiangqing.zhang@nxp.com can: flexcan: invoke flexcan_chip_freeze() to enter freeze mode
Joakim Zhang qiangqing.zhang@nxp.com can: flexcan: enable RX FIFO after FRZ/HALT valid
Joakim Zhang qiangqing.zhang@nxp.com can: flexcan: assert FRZ bit in flexcan_chip_freeze()
Oleksij Rempel linux@rempel-privat.de can: skb: can_skb_set_owner(): fix ref counting if socket was closed before setting skb ownership
Matthias Schiffer mschiffer@universe-factory.net net: l2tp: reduce log level of messages in receive path, add counter instead
Balazs Nemeth bnemeth@redhat.com net: avoid infinite loop in mpls_gso_segment when mpls_hlen == 0
Balazs Nemeth bnemeth@redhat.com net: check if protocol extracted by virtio_net_hdr_set_proto is correct
Daniel Borkmann daniel@iogearbox.net net: Fix gro aggregation for udp encaps with zero csum
Felix Fietkau nbd@nbd.name ath9k: fix transmitting to stations in dynamic SMPS mode
Maciej W. Rozycki macro@orcam.me.uk crypto: mips/poly1305 - enable for all MIPS processors
Jakub Kicinski kuba@kernel.org ethernet: alx: fix order of calls on resume
Greg Kurz groug@kaod.org powerpc/pseries: Don't enforce MSI affinity with kdump
Athira Rajeev atrajeev@linux.vnet.ibm.com powerpc/perf: Fix handling of privilege level checks in perf interrupt context
Dmitry V. Levin ldv@altlinux.org uapi: nfnetlink_cthelper.h: fix userspace compilation error
-------------
Diffstat:
Documentation/ABI/testing/sysfs-devices-memory | 5 +- Documentation/admin-guide/mm/memory-hotplug.rst | 4 +- Documentation/gpu/todo.rst | 21 +++ Documentation/networking/netdev-FAQ.rst | 78 +------- Documentation/process/stable-kernel-rules.rst | 6 - Documentation/process/submitting-patches.rst | 5 - Documentation/virt/kvm/api.rst | 3 + Makefile | 16 +- arch/arm/boot/compressed/head.S | 3 +- arch/arm/include/asm/assembler.h | 84 +++++++++ arch/arm/kernel/iwmmxt.S | 89 ++++----- arch/arm/kernel/iwmmxt.h | 47 +++++ arch/arm64/include/asm/kvm_asm.h | 4 +- arch/arm64/include/asm/kvm_hyp.h | 8 +- arch/arm64/include/asm/memory.h | 5 + arch/arm64/include/asm/mmu_context.h | 5 +- arch/arm64/include/asm/pgtable-prot.h | 1 - arch/arm64/include/asm/pgtable.h | 3 + arch/arm64/kernel/head.S | 2 +- arch/arm64/kernel/perf_event.c | 2 +- arch/arm64/kvm/arm.c | 7 +- arch/arm64/kvm/hyp/entry.S | 2 +- arch/arm64/kvm/hyp/nvhe/debug-sr.c | 12 +- arch/arm64/kvm/hyp/nvhe/host.S | 20 +-- arch/arm64/kvm/hyp/nvhe/hyp-main.c | 4 +- arch/arm64/kvm/hyp/nvhe/switch.c | 14 +- arch/arm64/kvm/hyp/nvhe/tlb.c | 3 +- arch/arm64/kvm/hyp/pgtable.c | 1 + arch/arm64/kvm/hyp/vhe/tlb.c | 3 +- arch/arm64/kvm/mmu.c | 3 +- arch/arm64/kvm/reset.c | 12 +- arch/arm64/mm/init.c | 12 ++ arch/arm64/mm/mmu.c | 5 +- arch/mips/crypto/Makefile | 4 +- arch/powerpc/include/asm/code-patching.h | 2 +- arch/powerpc/include/asm/machdep.h | 3 + arch/powerpc/include/asm/ptrace.h | 7 +- arch/powerpc/include/asm/switch_to.h | 10 ++ arch/powerpc/kernel/asm-offsets.c | 2 +- arch/powerpc/kernel/exceptions-64s.S | 2 +- arch/powerpc/kernel/head_book3s_32.S | 9 +- arch/powerpc/kernel/pci-common.c | 10 ++ arch/powerpc/kernel/process.c | 2 +- arch/powerpc/kernel/traps.c | 5 +- arch/powerpc/perf/core-book3s.c | 23 ++- arch/powerpc/platforms/pseries/msi.c | 25 ++- arch/s390/kernel/smp.c | 2 +- arch/sparc/include/asm/mman.h | 54 +++--- arch/sparc/mm/init_32.c | 3 + arch/x86/entry/common.c | 37 +--- arch/x86/entry/entry_64_compat.S | 2 + arch/x86/events/intel/core.c | 5 +- arch/x86/include/asm/idtentry.h | 3 - arch/x86/include/asm/insn-eval.h | 2 + arch/x86/include/asm/proto.h | 1 + arch/x86/include/asm/ptrace.h | 15 ++ arch/x86/kernel/cpu/mce/core.c | 6 +- arch/x86/kernel/kvmclock.c | 19 +- arch/x86/kernel/nmi.c | 6 +- arch/x86/kernel/sev-es.c | 22 ++- arch/x86/kernel/traps.c | 16 +- arch/x86/kernel/unwind_orc.c | 12 +- arch/x86/kvm/lapic.c | 11 +- arch/x86/lib/insn-eval.c | 66 +++++-- block/blk-zoned.c | 38 +++- crypto/Kconfig | 2 +- drivers/base/memory.c | 25 +-- drivers/base/swnode.c | 3 + drivers/base/test/Makefile | 1 + drivers/block/rsxx/core.c | 1 + drivers/block/zram/zram_drv.c | 11 +- drivers/clk/qcom/gdsc.c | 10 +- drivers/clk/qcom/gdsc.h | 3 +- drivers/clk/qcom/gpucc-msm8998.c | 8 +- drivers/cpufreq/qcom-cpufreq-hw.c | 6 +- drivers/firmware/efi/libstub/efi-stub.c | 16 ++ drivers/gpio/gpio-pca953x.c | 78 +++----- drivers/gpio/gpiolib-acpi.c | 19 +- drivers/gpio/gpiolib.c | 16 +- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 4 + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 49 ++--- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 1 - .../gpu/drm/amd/display/dc/dcn21/dcn21_resource.c | 6 +- .../gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c | 48 +++++ .../gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c | 66 +++++++ .../gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c | 48 ++--- drivers/gpu/drm/drm_gem_shmem_helper.c | 32 ++-- drivers/gpu/drm/drm_ioc32.c | 11 ++ drivers/gpu/drm/i915/gt/intel_engine_cs.c | 7 +- drivers/gpu/drm/i915/i915_cmd_parser.c | 19 +- drivers/gpu/drm/i915/i915_drv.h | 2 +- drivers/gpu/drm/meson/meson_drv.c | 11 ++ drivers/gpu/drm/qxl/qxl_display.c | 1 + drivers/gpu/drm/tiny/gm12u320.c | 44 ++++- drivers/gpu/drm/udl/udl_drv.c | 17 ++ drivers/gpu/drm/udl/udl_drv.h | 1 + drivers/gpu/drm/udl/udl_main.c | 10 ++ drivers/hid/hid-logitech-dj.c | 7 +- drivers/i2c/busses/i2c-rcar.c | 13 +- drivers/infiniband/core/umem.c | 8 +- drivers/input/keyboard/applespi.c | 21 ++- drivers/iommu/amd/init.c | 45 +++-- drivers/iommu/intel/svm.c | 13 +- drivers/media/platform/vsp1/vsp1_drm.c | 6 +- drivers/media/rc/Makefile | 1 + drivers/media/rc/keymaps/Makefile | 1 - drivers/media/rc/keymaps/rc-cec.c | 28 ++- drivers/media/rc/rc-main.c | 6 + drivers/media/usb/usbtv/usbtv-audio.c | 2 +- drivers/misc/fastrpc.c | 5 + drivers/misc/pvpanic.c | 1 + drivers/mmc/core/bus.c | 11 +- drivers/mmc/core/mmc.c | 15 +- drivers/mmc/host/mmci.c | 10 +- drivers/mmc/host/mtk-sd.c | 18 +- drivers/mmc/host/mxs-mmc.c | 2 +- drivers/mmc/host/sdhci-iproc.c | 18 ++ drivers/mmc/host/sdhci.c | 8 +- drivers/net/Kconfig | 2 +- drivers/net/can/flexcan.c | 24 ++- drivers/net/can/m_can/tcan4x5x.c | 6 +- drivers/net/dsa/sja1105/sja1105_main.c | 2 +- drivers/net/ethernet/atheros/alx/main.c | 7 +- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 14 +- drivers/net/ethernet/davicom/dm9000.c | 21 ++- drivers/net/ethernet/freescale/enetc/enetc.c | 93 +++++----- drivers/net/ethernet/freescale/enetc/enetc.h | 5 + drivers/net/ethernet/freescale/enetc/enetc_hw.h | 18 +- drivers/net/ethernet/freescale/enetc/enetc_pf.c | 117 +++++++++--- drivers/net/ethernet/freescale/enetc/enetc_vf.c | 7 + .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h | 6 +- .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 7 +- drivers/net/ethernet/ibm/ibmvnic.c | 13 +- drivers/net/ethernet/intel/i40e/i40e_main.c | 2 + drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c | 5 + drivers/net/ethernet/intel/ixgbevf/ipsec.c | 5 + drivers/net/ethernet/mediatek/mtk_star_emac.c | 5 +- drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 2 +- drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 2 + drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 1 + drivers/net/ethernet/mellanox/mlxsw/reg.h | 1 + .../net/ethernet/mellanox/mlxsw/spectrum_ethtool.c | 5 + drivers/net/ethernet/mellanox/mlxsw/switchx2.c | 3 +- drivers/net/ethernet/mscc/ocelot_flower.c | 3 +- drivers/net/ethernet/realtek/r8169_main.c | 2 +- drivers/net/ethernet/renesas/sh_eth.c | 7 + drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c | 5 +- drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c | 9 +- drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c | 19 +- drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c | 4 - .../net/ethernet/stmicro/stmmac/dwxgmac2_descs.c | 2 +- drivers/net/ethernet/stmicro/stmmac/hwif.h | 2 +- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 19 +- drivers/net/netdevsim/netdev.c | 1 + drivers/net/phy/phy.c | 6 +- drivers/net/phy/phy_device.c | 6 +- drivers/net/usb/qmi_wwan.c | 14 -- drivers/net/wan/lapbether.c | 3 - drivers/net/wireless/ath/ath11k/core.c | 1 + drivers/net/wireless/ath/ath11k/core.h | 1 + drivers/net/wireless/ath/ath11k/mac.c | 25 ++- drivers/net/wireless/ath/ath11k/peer.c | 61 ++++++- drivers/net/wireless/ath/ath11k/peer.h | 4 + drivers/net/wireless/ath/ath11k/wmi.c | 17 +- drivers/net/wireless/ath/ath9k/ath9k.h | 3 +- drivers/net/wireless/ath/ath9k/xmit.c | 6 + drivers/net/wireless/mediatek/mt76/dma.c | 11 +- drivers/nvme/host/fc.c | 2 +- drivers/pci/controller/pci-xgene-msi.c | 10 +- drivers/pci/controller/pcie-mediatek.c | 7 +- drivers/pci/pci.c | 4 + drivers/pci/pcie/Kconfig | 8 - drivers/pci/pcie/Makefile | 1 - drivers/pci/pcie/bw_notification.c | 138 -------------- drivers/pci/pcie/portdrv.h | 6 - drivers/pci/pcie/portdrv_pci.c | 1 - drivers/platform/olpc/olpc-ec.c | 15 +- drivers/s390/block/dasd.c | 6 +- drivers/s390/cio/vfio_ccw_ops.c | 6 +- drivers/s390/crypto/vfio_ap_ops.c | 2 +- drivers/s390/net/qeth_core.h | 5 +- drivers/s390/net/qeth_core_main.c | 200 ++++++++++----------- drivers/scsi/libiscsi.c | 11 +- drivers/scsi/ufs/ufs-sysfs.c | 3 +- drivers/scsi/ufs/ufs.h | 6 +- drivers/scsi/ufs/ufshcd.c | 2 +- drivers/spi/spi-stm32.c | 15 +- drivers/staging/comedi/drivers/addi_apci_1032.c | 4 +- drivers/staging/comedi/drivers/addi_apci_1500.c | 18 +- drivers/staging/comedi/drivers/adv_pci1710.c | 10 +- drivers/staging/comedi/drivers/das6402.c | 2 +- drivers/staging/comedi/drivers/das800.c | 2 +- drivers/staging/comedi/drivers/dmm32at.c | 2 +- drivers/staging/comedi/drivers/me4000.c | 2 +- drivers/staging/comedi/drivers/pcl711.c | 2 +- drivers/staging/comedi/drivers/pcl818.c | 2 +- drivers/staging/ks7010/ks_wlan_net.c | 6 +- drivers/staging/media/rkisp1/rkisp1-params.c | 1 - drivers/staging/rtl8188eu/core/rtw_ap.c | 5 + drivers/staging/rtl8188eu/os_dep/ioctl_linux.c | 6 +- drivers/staging/rtl8192e/rtl8192e/rtl_wx.c | 7 +- drivers/staging/rtl8192u/r8192U_wx.c | 6 +- drivers/staging/rtl8712/rtl871x_cmd.c | 6 +- drivers/staging/rtl8712/rtl871x_ioctl_linux.c | 2 +- drivers/target/target_core_pr.c | 15 +- drivers/target/target_core_transport.c | 15 +- drivers/tty/serial/max310x.c | 29 +-- drivers/usb/class/cdc-acm.c | 5 + drivers/usb/class/usblp.c | 16 +- drivers/usb/core/usb.c | 32 ++++ drivers/usb/dwc3/dwc3-qcom.c | 77 +++++++- drivers/usb/gadget/function/f_uac1.c | 1 + drivers/usb/gadget/function/f_uac2.c | 2 +- drivers/usb/gadget/function/u_ether_configfs.h | 5 +- drivers/usb/gadget/udc/s3c2410_udc.c | 4 +- drivers/usb/host/xhci-pci.c | 13 +- drivers/usb/host/xhci-ring.c | 3 +- drivers/usb/host/xhci.c | 78 ++++---- drivers/usb/host/xhci.h | 1 + drivers/usb/renesas_usbhs/pipe.c | 2 + drivers/usb/serial/ch341.c | 1 + drivers/usb/serial/cp210x.c | 3 + drivers/usb/serial/io_edgeport.c | 26 +-- drivers/usb/usbip/stub_dev.c | 42 ++++- drivers/usb/usbip/vhci_sysfs.c | 39 +++- drivers/usb/usbip/vudc_sysfs.c | 49 ++++- drivers/xen/events/events_2l.c | 22 ++- drivers/xen/events/events_base.c | 140 +++++++++++---- drivers/xen/events/events_fifo.c | 7 - drivers/xen/events/events_internal.h | 14 +- fs/binfmt_misc.c | 29 ++- fs/block_dev.c | 11 +- fs/cifs/cifsfs.c | 2 +- fs/cifs/cifsglob.h | 11 +- fs/cifs/connect.c | 10 +- fs/cifs/sess.c | 1 + fs/cifs/smb2inode.c | 1 + fs/cifs/smb2misc.c | 8 +- fs/cifs/smb2ops.c | 10 +- fs/cifs/smb2proto.h | 3 +- fs/cifs/transport.c | 2 +- fs/configfs/file.c | 6 +- fs/ext4/super.c | 9 +- fs/nfs/dir.c | 40 +++-- fs/nfs/nfs4proc.c | 2 +- fs/pnode.h | 2 +- fs/udf/inode.c | 9 +- include/linux/acpi.h | 10 +- include/linux/can/skb.h | 8 +- include/linux/compiler-clang.h | 6 + include/linux/entry-common.h | 39 +++- include/linux/gpio/consumer.h | 2 + include/linux/memory.h | 3 +- include/linux/perf_event.h | 2 + include/linux/pgtable.h | 4 + include/linux/sched/mm.h | 3 +- include/linux/seqlock.h | 5 +- include/linux/stop_machine.h | 11 +- include/linux/usb.h | 2 + include/linux/virtio_net.h | 7 +- include/media/rc-map.h | 7 + include/target/target_core_backend.h | 1 + include/uapi/linux/l2tp.h | 1 + include/uapi/linux/netfilter/nfnetlink_cthelper.h | 2 +- kernel/entry/common.c | 36 ++++ kernel/events/core.c | 42 ++++- kernel/sched/membarrier.c | 4 +- kernel/sys.c | 2 +- kernel/sysctl.c | 8 +- kernel/time/hrtimer.c | 60 ++++--- lib/logic_pio.c | 3 + lib/test_kasan.c | 10 +- mm/madvise.c | 13 +- mm/memory.c | 8 + mm/memory_hotplug.c | 2 +- mm/page_alloc.c | 158 ++++++++-------- mm/slub.c | 2 +- net/dsa/slave.c | 45 +++++ net/dsa/tag_ar9331.c | 3 - net/dsa/tag_brcm.c | 3 - net/dsa/tag_dsa.c | 5 - net/dsa/tag_edsa.c | 4 - net/dsa/tag_gswip.c | 5 - net/dsa/tag_ksz.c | 73 +------- net/dsa/tag_lan9303.c | 9 - net/dsa/tag_mtk.c | 22 ++- net/dsa/tag_ocelot.c | 7 - net/dsa/tag_qca.c | 3 - net/dsa/tag_rtl4_a.c | 12 +- net/dsa/tag_trailer.c | 31 +--- net/ethtool/channels.c | 26 +-- net/ipv4/cipso_ipv4.c | 11 +- net/ipv4/ip_tunnel.c | 5 +- net/ipv4/ip_vti.c | 6 +- net/ipv4/nexthop.c | 10 +- net/ipv4/tcp.c | 26 ++- net/ipv4/udp_offload.c | 2 +- net/ipv6/calipso.c | 14 +- net/ipv6/ip6_gre.c | 16 +- net/ipv6/ip6_tunnel.c | 10 +- net/ipv6/ip6_vti.c | 6 +- net/ipv6/sit.c | 2 +- net/l2tp/l2tp_core.c | 41 +++-- net/l2tp/l2tp_core.h | 1 + net/l2tp/l2tp_netlink.c | 6 + net/mpls/mpls_gso.c | 3 + net/netfilter/nf_nat_proto.c | 25 ++- net/netfilter/x_tables.c | 6 +- net/netlabel/netlabel_cipso_v4.c | 3 + net/qrtr/qrtr.c | 4 +- net/sched/sch_api.c | 8 +- net/sunrpc/sched.c | 5 +- samples/bpf/xdpsock_user.c | 2 + security/commoncap.c | 12 +- sound/pci/hda/hda_bind.c | 4 + sound/pci/hda/hda_controller.c | 7 - sound/pci/hda/hda_intel.c | 2 + sound/pci/hda/patch_ca0132.c | 1 + sound/pci/hda/patch_conexant.c | 62 +++++-- sound/pci/hda/patch_hdmi.c | 13 ++ sound/usb/card.c | 6 + sound/usb/quirks.c | 11 +- sound/usb/usbaudio.h | 1 + tools/bpf/resolve_btfids/main.c | 5 + tools/lib/bpf/xsk.c | 5 +- tools/perf/Makefile.perf | 2 +- tools/perf/util/sort.c | 4 +- tools/perf/util/trace-event-read.c | 1 + .../selftests/bpf/progs/netif_receive_skb.c | 13 +- .../testing/selftests/bpf/progs/test_tunnel_kern.c | 6 +- .../testing/selftests/bpf/verifier/array_access.c | 3 +- .../net/forwarding/mirror_gre_bridge_1d_vlan.sh | 9 + 333 files changed, 3007 insertions(+), 1742 deletions(-)
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Dmitry V. Levin ldv@altlinux.org
commit c33cb0020ee6dd96cc9976d6085a7d8422f6dbed upstream.
Apparently, <linux/netfilter/nfnetlink_cthelper.h> and <linux/netfilter/nfnetlink_acct.h> could not be included into the same compilation unit because of a cut-and-paste typo in the former header.
Fixes: 12f7a505331e6 ("netfilter: add user-space connection tracking helper infrastructure") Cc: stable@vger.kernel.org # v3.6 Signed-off-by: Dmitry V. Levin ldv@altlinux.org Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- include/uapi/linux/netfilter/nfnetlink_cthelper.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/include/uapi/linux/netfilter/nfnetlink_cthelper.h +++ b/include/uapi/linux/netfilter/nfnetlink_cthelper.h @@ -5,7 +5,7 @@ #define NFCT_HELPER_STATUS_DISABLED 0 #define NFCT_HELPER_STATUS_ENABLED 1
-enum nfnl_acct_msg_types { +enum nfnl_cthelper_msg_types { NFNL_MSG_CTHELPER_NEW, NFNL_MSG_CTHELPER_GET, NFNL_MSG_CTHELPER_DEL,
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Athira Rajeev atrajeev@linux.vnet.ibm.com
commit 5ae5fbd2107959b68ac69a8b75412208663aea88 upstream.
Running "perf mem record" in powerpc platforms with selinux enabled resulted in soft lockup's. Below call-trace was seen in the logs:
CPU: 58 PID: 3751 Comm: sssd_nss Not tainted 5.11.0-rc7+ #2 NIP: c000000000dff3d4 LR: c000000000dff3d0 CTR: 0000000000000000 REGS: c000007fffab7d60 TRAP: 0100 Not tainted (5.11.0-rc7+) ... NIP _raw_spin_lock_irqsave+0x94/0x120 LR _raw_spin_lock_irqsave+0x90/0x120 Call Trace: 0xc00000000fd47260 (unreliable) skb_queue_tail+0x3c/0x90 audit_log_end+0x6c/0x180 common_lsm_audit+0xb0/0xe0 slow_avc_audit+0xa4/0x110 avc_has_perm+0x1c4/0x260 selinux_perf_event_open+0x74/0xd0 security_perf_event_open+0x68/0xc0 record_and_restart+0x6e8/0x7f0 perf_event_interrupt+0x22c/0x560 performance_monitor_exception0x4c/0x60 performance_monitor_common_virt+0x1c8/0x1d0 interrupt: f00 at _raw_spin_lock_irqsave+0x38/0x120 NIP: c000000000dff378 LR: c000000000b5fbbc CTR: c0000000007d47f0 REGS: c00000000fd47860 TRAP: 0f00 Not tainted (5.11.0-rc7+) ... NIP _raw_spin_lock_irqsave+0x38/0x120 LR skb_queue_tail+0x3c/0x90 interrupt: f00 0x38 (unreliable) 0xc00000000aae6200 audit_log_end+0x6c/0x180 audit_log_exit+0x344/0xf80 __audit_syscall_exit+0x2c0/0x320 do_syscall_trace_leave+0x148/0x200 syscall_exit_prepare+0x324/0x390 system_call_common+0xfc/0x27c
The above trace shows that while the CPU was handling a performance monitor exception, there was a call to security_perf_event_open() function. In powerpc core-book3s, this function is called from perf_allow_kernel() check during recording of data address in the sample via perf_get_data_addr().
Commit da97e18458fb ("perf_event: Add support for LSM and SELinux checks") introduced security enhancements to perf. As part of this commit, the new security hook for perf_event_open() was added in all places where perf paranoid check was previously used. In powerpc core-book3s code, originally had paranoid checks in perf_get_data_addr() and power_pmu_bhrb_read(). So perf_paranoid_kernel() checks were replaced with perf_allow_kernel() in these PMU helper functions as well.
The intention of paranoid checks in core-book3s was to verify privilege access before capturing some of the sample data. Along with paranoid checks, perf_allow_kernel() also does a security_perf_event_open(). Since these functions are accessed while recording a sample, we end up calling selinux_perf_event_open() in PMI context. Some of the security functions use spinlock like sidtab_sid2str_put(). If a perf interrupt hits under a spin lock and if we end up in calling selinux hook functions in PMI handler, this could cause a dead lock.
Since the purpose of this security hook is to control access to perf_event_open(), it is not right to call this in interrupt context.
The paranoid checks in powerpc core-book3s were done at interrupt time which is also not correct.
Reference commits: Commit cd1231d7035f ("powerpc/perf: Prevent kernel address leak via perf_get_data_addr()") Commit bb19af816025 ("powerpc/perf: Prevent kernel address leak to userspace via BHRB buffer")
We only allow creation of events that have already passed the privilege checks in perf_event_open(). So these paranoid checks are not needed at event time. As a fix, patch uses 'event->attr.exclude_kernel' check to prevent exposing kernel address for userspace only sampling.
Fixes: cd1231d7035f ("powerpc/perf: Prevent kernel address leak via perf_get_data_addr()") Cc: stable@vger.kernel.org # v4.17+ Suggested-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Athira Rajeev atrajeev@linux.vnet.ibm.com Acked-by: Peter Zijlstra (Intel) peterz@infradead.org Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/1614247839-1428-1-git-send-email-atrajeev@linux.vn... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/powerpc/perf/core-book3s.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/arch/powerpc/perf/core-book3s.c +++ b/arch/powerpc/perf/core-book3s.c @@ -211,7 +211,7 @@ static inline void perf_get_data_addr(st if (!(mmcra & MMCRA_SAMPLE_ENABLE) || sdar_valid) *addrp = mfspr(SPRN_SDAR);
- if (is_kernel_addr(mfspr(SPRN_SDAR)) && perf_allow_kernel(&event->attr) != 0) + if (is_kernel_addr(mfspr(SPRN_SDAR)) && event->attr.exclude_kernel) *addrp = 0; }
@@ -477,7 +477,7 @@ static void power_pmu_bhrb_read(struct p * addresses, hence include a check before filtering code */ if (!(ppmu->flags & PPMU_ARCH_31) && - is_kernel_addr(addr) && perf_allow_kernel(&event->attr) != 0) + is_kernel_addr(addr) && event->attr.exclude_kernel) continue;
/* Branches are read most recent first (ie. mfbhrb 0 is
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Greg Kurz groug@kaod.org
commit f9619d5e5174867536b7e558683bc4408eab833f upstream.
Depending on the number of online CPUs in the original kernel, it is likely for CPU #0 to be offline in a kdump kernel. The associated IRQs in the affinity mappings provided by irq_create_affinity_masks() are thus not started by irq_startup(), as per-design with managed IRQs.
This can be a problem with multi-queue block devices driven by blk-mq : such a non-started IRQ is very likely paired with the single queue enforced by blk-mq during kdump (see blk_mq_alloc_tag_set()). This causes the device to remain silent and likely hangs the guest at some point.
This is a regression caused by commit 9ea69a55b3b9 ("powerpc/pseries: Pass MSI affinity to irq_create_mapping()"). Note that this only happens with the XIVE interrupt controller because XICS has a workaround to bypass affinity, which is activated during kdump with the "noirqdistrib" kernel parameter.
The issue comes from a combination of factors: - discrepancy between the number of queues detected by the multi-queue block driver, that was used to create the MSI vectors, and the single queue mode enforced later on by blk-mq because of kdump (i.e. keeping all queues fixes the issue) - CPU#0 offline (i.e. kdump always succeed with CPU#0)
Given that I couldn't reproduce on x86, which seems to always have CPU#0 online even during kdump, I'm not sure where this should be fixed. Hence going for another approach : fine-grained affinity is for performance and we don't really care about that during kdump. Simply revert to the previous working behavior of ignoring affinity masks in this case only.
Fixes: 9ea69a55b3b9 ("powerpc/pseries: Pass MSI affinity to irq_create_mapping()") Cc: stable@vger.kernel.org # v5.10+ Signed-off-by: Greg Kurz groug@kaod.org Reviewed-by: Laurent Vivier lvivier@redhat.com Reviewed-by: Cédric Le Goater clg@kaod.org Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20210215094506.1196119-1-groug@kaod.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/powerpc/platforms/pseries/msi.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-)
--- a/arch/powerpc/platforms/pseries/msi.c +++ b/arch/powerpc/platforms/pseries/msi.c @@ -4,6 +4,7 @@ * Copyright 2006-2007 Michael Ellerman, IBM Corp. */
+#include <linux/crash_dump.h> #include <linux/device.h> #include <linux/irq.h> #include <linux/msi.h> @@ -458,8 +459,28 @@ again: return hwirq; }
- virq = irq_create_mapping_affinity(NULL, hwirq, - entry->affinity); + /* + * Depending on the number of online CPUs in the original + * kernel, it is likely for CPU #0 to be offline in a kdump + * kernel. The associated IRQs in the affinity mappings + * provided by irq_create_affinity_masks() are thus not + * started by irq_startup(), as per-design for managed IRQs. + * This can be a problem with multi-queue block devices driven + * by blk-mq : such a non-started IRQ is very likely paired + * with the single queue enforced by blk-mq during kdump (see + * blk_mq_alloc_tag_set()). This causes the device to remain + * silent and likely hangs the guest at some point. + * + * We don't really care for fine-grained affinity when doing + * kdump actually : simply ignore the pre-computed affinity + * masks in this case and let the default mask with all CPUs + * be used when creating the IRQ mappings. + */ + if (is_kdump_kernel()) + virq = irq_create_mapping(NULL, hwirq); + else + virq = irq_create_mapping_affinity(NULL, hwirq, + entry->affinity);
if (!virq) { pr_debug("rtas_msi: Failed mapping hwirq %d\n", hwirq);
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Jakub Kicinski kuba@kernel.org
commit a4dcfbc4ee2218abd567d81d795082d8d4afcdf6 upstream.
netif_device_attach() will unpause the queues so we can't call it before __alx_open(). This went undetected until commit b0999223f224 ("alx: add ability to allocate and free alx_napi structures") but now if stack tries to xmit immediately on resume before __alx_open() we'll crash on the NAPI being null:
BUG: kernel NULL pointer dereference, address: 0000000000000198 CPU: 0 PID: 12 Comm: ksoftirqd/0 Tainted: G OE 5.10.0-3-amd64 #1 Debian 5.10.13-1 Hardware name: Gigabyte Technology Co., Ltd. To be filled by O.E.M./H77-D3H, BIOS F15 11/14/2013 RIP: 0010:alx_start_xmit+0x34/0x650 [alx] Code: 41 56 41 55 41 54 55 53 48 83 ec 20 0f b7 57 7c 8b 8e b0 0b 00 00 39 ca 72 06 89 d0 31 d2 f7 f1 89 d2 48 8b 84 df RSP: 0018:ffffb09240083d28 EFLAGS: 00010297 RAX: 0000000000000000 RBX: ffffa04d80ae7800 RCX: 0000000000000004 RDX: 0000000000000000 RSI: ffffa04d80afa000 RDI: ffffa04e92e92a00 RBP: 0000000000000042 R08: 0000000000000100 R09: ffffa04ea3146700 R10: 0000000000000014 R11: 0000000000000000 R12: ffffa04e92e92100 R13: 0000000000000001 R14: ffffa04e92e92a00 R15: ffffa04e92e92a00 FS: 0000000000000000(0000) GS:ffffa0508f600000(0000) knlGS:0000000000000000 i915 0000:00:02.0: vblank wait timed out on crtc 0 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000198 CR3: 000000004460a001 CR4: 00000000001706f0 Call Trace: dev_hard_start_xmit+0xc7/0x1e0 sch_direct_xmit+0x10f/0x310
Cc: stable@vger.kernel.org # 4.9+ Fixes: bc2bebe8de8e ("alx: remove WoL support") Reported-by: Zbynek Michl zbynek.michl@gmail.com Link: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=983595 Signed-off-by: Jakub Kicinski kuba@kernel.org Tested-by: Zbynek Michl zbynek.michl@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/atheros/alx/main.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
--- a/drivers/net/ethernet/atheros/alx/main.c +++ b/drivers/net/ethernet/atheros/alx/main.c @@ -1894,13 +1894,16 @@ static int alx_resume(struct device *dev
if (!netif_running(alx->dev)) return 0; - netif_device_attach(alx->dev);
rtnl_lock(); err = __alx_open(alx, true); rtnl_unlock(); + if (err) + return err; + + netif_device_attach(alx->dev);
- return err; + return 0; }
static SIMPLE_DEV_PM_OPS(alx_pm_ops, alx_suspend, alx_resume);
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Maciej W. Rozycki macro@orcam.me.uk
commit 6c810cf20feef0d4338e9b424ab7f2644a8b353e upstream.
The MIPS Poly1305 implementation is generic MIPS code written such as to support down to the original MIPS I and MIPS III ISA for the 32-bit and 64-bit variant respectively. Lift the current limitation then to enable code for MIPSr1 ISA or newer processors only and have it available for all MIPS processors.
Signed-off-by: Maciej W. Rozycki macro@orcam.me.uk Fixes: a11d055e7a64 ("crypto: mips/poly1305 - incorporate OpenSSL/CRYPTOGAMS optimized implementation") Cc: stable@vger.kernel.org # v5.5+ Acked-by: Jason A. Donenfeld Jason@zx2c4.com Signed-off-by: Thomas Bogendoerfer tsbogend@alpha.franken.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/mips/crypto/Makefile | 4 ++-- crypto/Kconfig | 2 +- drivers/net/Kconfig | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-)
--- a/arch/mips/crypto/Makefile +++ b/arch/mips/crypto/Makefile @@ -12,8 +12,8 @@ AFLAGS_chacha-core.o += -O2 # needed to obj-$(CONFIG_CRYPTO_POLY1305_MIPS) += poly1305-mips.o poly1305-mips-y := poly1305-core.o poly1305-glue.o
-perlasm-flavour-$(CONFIG_CPU_MIPS32) := o32 -perlasm-flavour-$(CONFIG_CPU_MIPS64) := 64 +perlasm-flavour-$(CONFIG_32BIT) := o32 +perlasm-flavour-$(CONFIG_64BIT) := 64
quiet_cmd_perlasm = PERLASM $@ cmd_perlasm = $(PERL) $(<) $(perlasm-flavour-y) $(@) --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -772,7 +772,7 @@ config CRYPTO_POLY1305_X86_64
config CRYPTO_POLY1305_MIPS tristate "Poly1305 authenticator algorithm (MIPS optimized)" - depends on CPU_MIPS32 || (CPU_MIPS64 && 64BIT) + depends on MIPS select CRYPTO_ARCH_HAVE_LIB_POLY1305
config CRYPTO_MD4 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -92,7 +92,7 @@ config WIREGUARD select CRYPTO_POLY1305_ARM if ARM select CRYPTO_CURVE25519_NEON if ARM && KERNEL_MODE_NEON select CRYPTO_CHACHA_MIPS if CPU_MIPS32_R2 - select CRYPTO_POLY1305_MIPS if CPU_MIPS32 || (CPU_MIPS64 && 64BIT) + select CRYPTO_POLY1305_MIPS if MIPS help WireGuard is a secure, fast, and easy to use replacement for IPSec that uses modern cryptography and clever networking tricks. It's
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Felix Fietkau nbd@nbd.name
commit 3b9ea7206d7e1fdd7419cbd10badd3b2c80d04b4 upstream.
When transmitting to a receiver in dynamic SMPS mode, all transmissions that use multiple spatial streams need to be sent using CTS-to-self or RTS/CTS to give the receiver's extra chains some time to wake up. This fixes the tx rate getting stuck at <= MCS7 for some clients, especially Intel ones, which make aggressive use of SMPS.
Cc: stable@vger.kernel.org Reported-by: Martin Kennedy hurricos@gmail.com Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20210214184911.96702-1-nbd@nbd.name Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/wireless/ath/ath9k/ath9k.h | 3 ++- drivers/net/wireless/ath/ath9k/xmit.c | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-)
--- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -177,7 +177,8 @@ struct ath_frame_info { s8 txq; u8 keyix; u8 rtscts_rate; - u8 retries : 7; + u8 retries : 6; + u8 dyn_smps : 1; u8 baw_tracked : 1; u8 tx_power; enum ath9k_key_type keytype:2; --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1271,6 +1271,11 @@ static void ath_buf_set_rate(struct ath_ is_40, is_sgi, is_sp); if (rix < 8 && (tx_info->flags & IEEE80211_TX_CTL_STBC)) info->rates[i].RateFlags |= ATH9K_RATESERIES_STBC; + if (rix >= 8 && fi->dyn_smps) { + info->rates[i].RateFlags |= + ATH9K_RATESERIES_RTS_CTS; + info->flags |= ATH9K_TXDESC_CTSENA; + }
info->txpower[i] = ath_get_rate_txpower(sc, bf, rix, is_40, false); @@ -2114,6 +2119,7 @@ static void setup_frame_info(struct ieee fi->keyix = an->ps_key; else fi->keyix = ATH9K_TXKEYIX_INVALID; + fi->dyn_smps = sta && sta->smps_mode == IEEE80211_SMPS_DYNAMIC; fi->keytype = keytype; fi->framelen = framelen; fi->tx_power = txpower;
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Daniel Borkmann daniel@iogearbox.net
commit 89e5c58fc1e2857ccdaae506fb8bc5fed57ee063 upstream.
We noticed a GRO issue for UDP-based encaps such as vxlan/geneve when the csum for the UDP header itself is 0. In that case, GRO aggregation does not take place on the phys dev, but instead is deferred to the vxlan/geneve driver (see trace below).
The reason is essentially that GRO aggregation bails out in udp_gro_receive() for such case when drivers marked the skb with CHECKSUM_UNNECESSARY (ice, i40e, others) where for non-zero csums 2abb7cdc0dc8 ("udp: Add support for doing checksum unnecessary conversion") promotes those skbs to CHECKSUM_COMPLETE and napi context has csum_valid set. This is however not the case for zero UDP csum (here: csum_cnt is still 0 and csum_valid continues to be false).
At the same time 57c67ff4bd92 ("udp: additional GRO support") added matches on !uh->check ^ !uh2->check as part to determine candidates for aggregation, so it certainly is expected to handle zero csums in udp_gro_receive(). The purpose of the check added via 662880f44203 ("net: Allow GRO to use and set levels of checksum unnecessary") seems to catch bad csum and stop aggregation right away.
One way to fix aggregation in the zero case is to only perform the !csum_valid check in udp_gro_receive() if uh->check is infact non-zero.
Before:
[...] swapper 0 [008] 731.946506: net:netif_receive_skb: dev=enp10s0f0 skbaddr=0xffff966497100400 len=1500 (1) swapper 0 [008] 731.946507: net:netif_receive_skb: dev=enp10s0f0 skbaddr=0xffff966497100200 len=1500 swapper 0 [008] 731.946507: net:netif_receive_skb: dev=enp10s0f0 skbaddr=0xffff966497101100 len=1500 swapper 0 [008] 731.946508: net:netif_receive_skb: dev=enp10s0f0 skbaddr=0xffff966497101700 len=1500 swapper 0 [008] 731.946508: net:netif_receive_skb: dev=enp10s0f0 skbaddr=0xffff966497101b00 len=1500 swapper 0 [008] 731.946508: net:netif_receive_skb: dev=enp10s0f0 skbaddr=0xffff966497100600 len=1500 swapper 0 [008] 731.946508: net:netif_receive_skb: dev=enp10s0f0 skbaddr=0xffff966497100f00 len=1500 swapper 0 [008] 731.946509: net:netif_receive_skb: dev=enp10s0f0 skbaddr=0xffff966497100a00 len=1500 swapper 0 [008] 731.946516: net:netif_receive_skb: dev=enp10s0f0 skbaddr=0xffff966497100500 len=1500 swapper 0 [008] 731.946516: net:netif_receive_skb: dev=enp10s0f0 skbaddr=0xffff966497100700 len=1500 swapper 0 [008] 731.946516: net:netif_receive_skb: dev=enp10s0f0 skbaddr=0xffff966497101d00 len=1500 (2) swapper 0 [008] 731.946517: net:netif_receive_skb: dev=enp10s0f0 skbaddr=0xffff966497101000 len=1500 swapper 0 [008] 731.946517: net:netif_receive_skb: dev=enp10s0f0 skbaddr=0xffff966497101c00 len=1500 swapper 0 [008] 731.946517: net:netif_receive_skb: dev=enp10s0f0 skbaddr=0xffff966497101400 len=1500 swapper 0 [008] 731.946518: net:netif_receive_skb: dev=enp10s0f0 skbaddr=0xffff966497100e00 len=1500 swapper 0 [008] 731.946518: net:netif_receive_skb: dev=enp10s0f0 skbaddr=0xffff966497101600 len=1500 swapper 0 [008] 731.946521: net:netif_receive_skb: dev=enp10s0f0 skbaddr=0xffff966497100800 len=774 swapper 0 [008] 731.946530: net:netif_receive_skb: dev=test_vxlan skbaddr=0xffff966497100400 len=14032 (1) swapper 0 [008] 731.946530: net:netif_receive_skb: dev=test_vxlan skbaddr=0xffff966497101d00 len=9112 (2) [...]
# netperf -H 10.55.10.4 -t TCP_STREAM -l 20 MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 10.55.10.4 () port 0 AF_INET : demo Recv Send Send Socket Socket Message Elapsed Size Size Size Time Throughput bytes bytes bytes secs. 10^6bits/sec
87380 16384 16384 20.01 13129.24
After:
[...] swapper 0 [026] 521.862641: net:netif_receive_skb: dev=enp10s0f0 skbaddr=0xffff93ab0d479000 len=11286 (1) swapper 0 [026] 521.862643: net:netif_receive_skb: dev=test_vxlan skbaddr=0xffff93ab0d479000 len=11236 (1) swapper 0 [026] 521.862650: net:netif_receive_skb: dev=enp10s0f0 skbaddr=0xffff93ab0d478500 len=2898 (2) swapper 0 [026] 521.862650: net:netif_receive_skb: dev=enp10s0f0 skbaddr=0xffff93ab0d479f00 len=8490 (3) swapper 0 [026] 521.862653: net:netif_receive_skb: dev=test_vxlan skbaddr=0xffff93ab0d478500 len=2848 (2) swapper 0 [026] 521.862653: net:netif_receive_skb: dev=test_vxlan skbaddr=0xffff93ab0d479f00 len=8440 (3) [...]
# netperf -H 10.55.10.4 -t TCP_STREAM -l 20 MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 10.55.10.4 () port 0 AF_INET : demo Recv Send Send Socket Socket Message Elapsed Size Size Size Time Throughput bytes bytes bytes secs. 10^6bits/sec
87380 16384 16384 20.01 24576.53
Fixes: 57c67ff4bd92 ("udp: additional GRO support") Fixes: 662880f44203 ("net: Allow GRO to use and set levels of checksum unnecessary") Signed-off-by: Daniel Borkmann daniel@iogearbox.net Cc: Eric Dumazet edumazet@google.com Cc: Jesse Brandeburg jesse.brandeburg@intel.com Cc: Tom Herbert tom@herbertland.com Acked-by: Willem de Bruijn willemb@google.com Acked-by: John Fastabend john.fastabend@gmail.com Link: https://lore.kernel.org/r/20210226212248.8300-1-daniel@iogearbox.net Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/ipv4/udp_offload.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/net/ipv4/udp_offload.c +++ b/net/ipv4/udp_offload.c @@ -522,7 +522,7 @@ struct sk_buff *udp_gro_receive(struct l }
if (!sk || NAPI_GRO_CB(skb)->encap_mark || - (skb->ip_summed != CHECKSUM_PARTIAL && + (uh->check && skb->ip_summed != CHECKSUM_PARTIAL && NAPI_GRO_CB(skb)->csum_cnt == 0 && !NAPI_GRO_CB(skb)->csum_valid) || !udp_sk(sk)->gro_receive)
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Balazs Nemeth bnemeth@redhat.com
commit 924a9bc362a5223cd448ca08c3dde21235adc310 upstream.
For gso packets, virtio_net_hdr_set_proto sets the protocol (if it isn't set) based on the type in the virtio net hdr, but the skb could contain anything since it could come from packet_snd through a raw socket. If there is a mismatch between what virtio_net_hdr_set_proto sets and the actual protocol, then the skb could be handled incorrectly later on.
An example where this poses an issue is with the subsequent call to skb_flow_dissect_flow_keys_basic which relies on skb->protocol being set correctly. A specially crafted packet could fool skb_flow_dissect_flow_keys_basic preventing EINVAL to be returned.
Avoid blindly trusting the information provided by the virtio net header by checking that the protocol in the packet actually matches the protocol set by virtio_net_hdr_set_proto. Note that since the protocol is only checked if skb->dev implements header_ops->parse_protocol, packets from devices without the implementation are not checked at this stage.
Fixes: 9274124f023b ("net: stricter validation of untrusted gso packets") Signed-off-by: Balazs Nemeth bnemeth@redhat.com Acked-by: Willem de Bruijn willemb@google.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- include/linux/virtio_net.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
--- a/include/linux/virtio_net.h +++ b/include/linux/virtio_net.h @@ -79,8 +79,13 @@ static inline int virtio_net_hdr_to_skb( if (gso_type && skb->network_header) { struct flow_keys_basic keys;
- if (!skb->protocol) + if (!skb->protocol) { + __be16 protocol = dev_parse_header_protocol(skb); + virtio_net_hdr_set_proto(skb, hdr); + if (protocol && protocol != skb->protocol) + return -EINVAL; + } retry: if (!skb_flow_dissect_flow_keys_basic(NULL, skb, &keys, NULL, 0, 0, 0,
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Balazs Nemeth bnemeth@redhat.com
commit d348ede32e99d3a04863e9f9b28d224456118c27 upstream.
A packet with skb_inner_network_header(skb) == skb_network_header(skb) and ETH_P_MPLS_UC will prevent mpls_gso_segment from pulling any headers from the packet. Subsequently, the call to skb_mac_gso_segment will again call mpls_gso_segment with the same packet leading to an infinite loop. In addition, ensure that the header length is a multiple of four, which should hold irrespective of the number of stacked labels.
Signed-off-by: Balazs Nemeth bnemeth@redhat.com Acked-by: Willem de Bruijn willemb@google.com Reviewed-by: David Ahern dsahern@kernel.org Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/mpls/mpls_gso.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/net/mpls/mpls_gso.c +++ b/net/mpls/mpls_gso.c @@ -14,6 +14,7 @@ #include <linux/netdev_features.h> #include <linux/netdevice.h> #include <linux/skbuff.h> +#include <net/mpls.h>
static struct sk_buff *mpls_gso_segment(struct sk_buff *skb, netdev_features_t features) @@ -27,6 +28,8 @@ static struct sk_buff *mpls_gso_segment(
skb_reset_network_header(skb); mpls_hlen = skb_inner_network_header(skb) - skb_network_header(skb); + if (unlikely(!mpls_hlen || mpls_hlen % MPLS_HLEN)) + goto out; if (unlikely(!pskb_may_pull(skb, mpls_hlen))) goto out;
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Matthias Schiffer mschiffer@universe-factory.net
commit 3e59e8856758eb5a2dfe1f831ef53b168fd58105 upstream.
Commit 5ee759cda51b ("l2tp: use standard API for warning log messages") changed a number of warnings about invalid packets in the receive path so that they are always shown, instead of only when a special L2TP debug flag is set. Even with rate limiting these warnings can easily cause significant log spam - potentially triggered by a malicious party sending invalid packets on purpose.
In addition these warnings were noticed by projects like Tunneldigger [1], which uses L2TP for its data path, but implements its own control protocol (which is sufficiently different from L2TP data packets that it would always be passed up to userspace even with future extensions of L2TP).
Some of the warnings were already redundant, as l2tp_stats has a counter for these packets. This commit adds one additional counter for invalid packets that are passed up to userspace. Packets with unknown session are not counted as invalid, as there is nothing wrong with the format of these packets.
With the additional counter, all of these messages are either redundant or benign, so we reduce them to pr_debug_ratelimited().
[1] https://github.com/wlanslovenija/tunneldigger/issues/160
Fixes: 5ee759cda51b ("l2tp: use standard API for warning log messages") Signed-off-by: Matthias Schiffer mschiffer@universe-factory.net Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- include/uapi/linux/l2tp.h | 1 + net/l2tp/l2tp_core.c | 41 ++++++++++++++++++++++------------------- net/l2tp/l2tp_core.h | 1 + net/l2tp/l2tp_netlink.c | 6 ++++++ 4 files changed, 30 insertions(+), 19 deletions(-)
--- a/include/uapi/linux/l2tp.h +++ b/include/uapi/linux/l2tp.h @@ -145,6 +145,7 @@ enum { L2TP_ATTR_RX_ERRORS, /* u64 */ L2TP_ATTR_STATS_PAD, L2TP_ATTR_RX_COOKIE_DISCARDS, /* u64 */ + L2TP_ATTR_RX_INVALID, /* u64 */ __L2TP_ATTR_STATS_MAX, };
--- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c @@ -649,9 +649,9 @@ void l2tp_recv_common(struct l2tp_sessio /* Parse and check optional cookie */ if (session->peer_cookie_len > 0) { if (memcmp(ptr, &session->peer_cookie[0], session->peer_cookie_len)) { - pr_warn_ratelimited("%s: cookie mismatch (%u/%u). Discarding.\n", - tunnel->name, tunnel->tunnel_id, - session->session_id); + pr_debug_ratelimited("%s: cookie mismatch (%u/%u). Discarding.\n", + tunnel->name, tunnel->tunnel_id, + session->session_id); atomic_long_inc(&session->stats.rx_cookie_discards); goto discard; } @@ -702,8 +702,8 @@ void l2tp_recv_common(struct l2tp_sessio * If user has configured mandatory sequence numbers, discard. */ if (session->recv_seq) { - pr_warn_ratelimited("%s: recv data has no seq numbers when required. Discarding.\n", - session->name); + pr_debug_ratelimited("%s: recv data has no seq numbers when required. Discarding.\n", + session->name); atomic_long_inc(&session->stats.rx_seq_discards); goto discard; } @@ -718,8 +718,8 @@ void l2tp_recv_common(struct l2tp_sessio session->send_seq = 0; l2tp_session_set_header_len(session, tunnel->version); } else if (session->send_seq) { - pr_warn_ratelimited("%s: recv data has no seq numbers when required. Discarding.\n", - session->name); + pr_debug_ratelimited("%s: recv data has no seq numbers when required. Discarding.\n", + session->name); atomic_long_inc(&session->stats.rx_seq_discards); goto discard; } @@ -809,9 +809,9 @@ static int l2tp_udp_recv_core(struct l2t
/* Short packet? */ if (!pskb_may_pull(skb, L2TP_HDR_SIZE_MAX)) { - pr_warn_ratelimited("%s: recv short packet (len=%d)\n", - tunnel->name, skb->len); - goto error; + pr_debug_ratelimited("%s: recv short packet (len=%d)\n", + tunnel->name, skb->len); + goto invalid; }
/* Point to L2TP header */ @@ -824,9 +824,9 @@ static int l2tp_udp_recv_core(struct l2t /* Check protocol version */ version = hdrflags & L2TP_HDR_VER_MASK; if (version != tunnel->version) { - pr_warn_ratelimited("%s: recv protocol version mismatch: got %d expected %d\n", - tunnel->name, version, tunnel->version); - goto error; + pr_debug_ratelimited("%s: recv protocol version mismatch: got %d expected %d\n", + tunnel->name, version, tunnel->version); + goto invalid; }
/* Get length of L2TP packet */ @@ -834,7 +834,7 @@ static int l2tp_udp_recv_core(struct l2t
/* If type is control packet, it is handled by userspace. */ if (hdrflags & L2TP_HDRFLAG_T) - goto error; + goto pass;
/* Skip flags */ ptr += 2; @@ -863,21 +863,24 @@ static int l2tp_udp_recv_core(struct l2t l2tp_session_dec_refcount(session);
/* Not found? Pass to userspace to deal with */ - pr_warn_ratelimited("%s: no session found (%u/%u). Passing up.\n", - tunnel->name, tunnel_id, session_id); - goto error; + pr_debug_ratelimited("%s: no session found (%u/%u). Passing up.\n", + tunnel->name, tunnel_id, session_id); + goto pass; }
if (tunnel->version == L2TP_HDR_VER_3 && l2tp_v3_ensure_opt_in_linear(session, skb, &ptr, &optr)) - goto error; + goto invalid;
l2tp_recv_common(session, skb, ptr, optr, hdrflags, length); l2tp_session_dec_refcount(session);
return 0;
-error: +invalid: + atomic_long_inc(&tunnel->stats.rx_invalid); + +pass: /* Put UDP header back */ __skb_push(skb, sizeof(struct udphdr));
--- a/net/l2tp/l2tp_core.h +++ b/net/l2tp/l2tp_core.h @@ -39,6 +39,7 @@ struct l2tp_stats { atomic_long_t rx_oos_packets; atomic_long_t rx_errors; atomic_long_t rx_cookie_discards; + atomic_long_t rx_invalid; };
struct l2tp_tunnel; --- a/net/l2tp/l2tp_netlink.c +++ b/net/l2tp/l2tp_netlink.c @@ -428,6 +428,9 @@ static int l2tp_nl_tunnel_send(struct sk L2TP_ATTR_STATS_PAD) || nla_put_u64_64bit(skb, L2TP_ATTR_RX_ERRORS, atomic_long_read(&tunnel->stats.rx_errors), + L2TP_ATTR_STATS_PAD) || + nla_put_u64_64bit(skb, L2TP_ATTR_RX_INVALID, + atomic_long_read(&tunnel->stats.rx_invalid), L2TP_ATTR_STATS_PAD)) goto nla_put_failure; nla_nest_end(skb, nest); @@ -771,6 +774,9 @@ static int l2tp_nl_session_send(struct s L2TP_ATTR_STATS_PAD) || nla_put_u64_64bit(skb, L2TP_ATTR_RX_ERRORS, atomic_long_read(&session->stats.rx_errors), + L2TP_ATTR_STATS_PAD) || + nla_put_u64_64bit(skb, L2TP_ATTR_RX_INVALID, + atomic_long_read(&session->stats.rx_invalid), L2TP_ATTR_STATS_PAD)) goto nla_put_failure; nla_nest_end(skb, nest);
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Oleksij Rempel o.rempel@pengutronix.de
commit e940e0895a82c6fbaa259f2615eb52b57ee91a7e upstream.
There are two ref count variables controlling the free()ing of a socket: - struct sock::sk_refcnt - which is changed by sock_hold()/sock_put() - struct sock::sk_wmem_alloc - which accounts the memory allocated by the skbs in the send path.
In case there are still TX skbs on the fly and the socket() is closed, the struct sock::sk_refcnt reaches 0. In the TX-path the CAN stack clones an "echo" skb, calls sock_hold() on the original socket and references it. This produces the following back trace:
| WARNING: CPU: 0 PID: 280 at lib/refcount.c:25 refcount_warn_saturate+0x114/0x134 | refcount_t: addition on 0; use-after-free. | Modules linked in: coda_vpu(E) v4l2_jpeg(E) videobuf2_vmalloc(E) imx_vdoa(E) | CPU: 0 PID: 280 Comm: test_can.sh Tainted: G E 5.11.0-04577-gf8ff6603c617 #203 | Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree) | Backtrace: | [<80bafea4>] (dump_backtrace) from [<80bb0280>] (show_stack+0x20/0x24) r7:00000000 r6:600f0113 r5:00000000 r4:81441220 | [<80bb0260>] (show_stack) from [<80bb593c>] (dump_stack+0xa0/0xc8) | [<80bb589c>] (dump_stack) from [<8012b268>] (__warn+0xd4/0x114) r9:00000019 r8:80f4a8c2 r7:83e4150c r6:00000000 r5:00000009 r4:80528f90 | [<8012b194>] (__warn) from [<80bb09c4>] (warn_slowpath_fmt+0x88/0xc8) r9:83f26400 r8:80f4a8d1 r7:00000009 r6:80528f90 r5:00000019 r4:80f4a8c2 | [<80bb0940>] (warn_slowpath_fmt) from [<80528f90>] (refcount_warn_saturate+0x114/0x134) r8:00000000 r7:00000000 r6:82b44000 r5:834e5600 r4:83f4d540 | [<80528e7c>] (refcount_warn_saturate) from [<8079a4c8>] (__refcount_add.constprop.0+0x4c/0x50) | [<8079a47c>] (__refcount_add.constprop.0) from [<8079a57c>] (can_put_echo_skb+0xb0/0x13c) | [<8079a4cc>] (can_put_echo_skb) from [<8079ba98>] (flexcan_start_xmit+0x1c4/0x230) r9:00000010 r8:83f48610 r7:0fdc0000 r6:0c080000 r5:82b44000 r4:834e5600 | [<8079b8d4>] (flexcan_start_xmit) from [<80969078>] (netdev_start_xmit+0x44/0x70) r9:814c0ba0 r8:80c8790c r7:00000000 r6:834e5600 r5:82b44000 r4:82ab1f00 | [<80969034>] (netdev_start_xmit) from [<809725a4>] (dev_hard_start_xmit+0x19c/0x318) r9:814c0ba0 r8:00000000 r7:82ab1f00 r6:82b44000 r5:00000000 r4:834e5600 | [<80972408>] (dev_hard_start_xmit) from [<809c6584>] (sch_direct_xmit+0xcc/0x264) r10:834e5600 r9:00000000 r8:00000000 r7:82b44000 r6:82ab1f00 r5:834e5600 r4:83f27400 | [<809c64b8>] (sch_direct_xmit) from [<809c6c0c>] (__qdisc_run+0x4f0/0x534)
To fix this problem, only set skb ownership to sockets which have still a ref count > 0.
Fixes: 0ae89beb283a ("can: add destructor for self generated skbs") Cc: Oliver Hartkopp socketcan@hartkopp.net Cc: Andre Naujoks nautsch2@gmail.com Link: https://lore.kernel.org/r/20210226092456.27126-1-o.rempel@pengutronix.de Suggested-by: Eric Dumazet edumazet@google.com Signed-off-by: Oleksij Rempel o.rempel@pengutronix.de Reviewed-by: Oliver Hartkopp socketcan@hartkopp.net Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- include/linux/can/skb.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
--- a/include/linux/can/skb.h +++ b/include/linux/can/skb.h @@ -49,8 +49,12 @@ static inline void can_skb_reserve(struc
static inline void can_skb_set_owner(struct sk_buff *skb, struct sock *sk) { - if (sk) { - sock_hold(sk); + /* If the socket has already been closed by user space, the + * refcount may already be 0 (and the socket will be freed + * after the last TX skb has been freed). So only increase + * socket refcount if the refcount is > 0. + */ + if (sk && refcount_inc_not_zero(&sk->sk_refcnt)) { skb->destructor = sock_efree; skb->sk = sk; }
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Joakim Zhang qiangqing.zhang@nxp.com
commit 449052cfebf624b670faa040245d3feed770d22f upstream.
Assert HALT bit to enter freeze mode, there is a premise that FRZ bit is asserted. This patch asserts FRZ bit in flexcan_chip_freeze, although the reset value is 1b'1. This is a prepare patch, later patch will invoke flexcan_chip_freeze() to enter freeze mode, which polling freeze mode acknowledge.
Fixes: b1aa1c7a2165b ("can: flexcan: fix transition from and to freeze mode in chip_{,un}freeze") Link: https://lore.kernel.org/r/20210218110037.16591-2-qiangqing.zhang@nxp.com Signed-off-by: Joakim Zhang qiangqing.zhang@nxp.com Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/can/flexcan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -662,7 +662,7 @@ static int flexcan_chip_freeze(struct fl u32 reg;
reg = priv->read(®s->mcr); - reg |= FLEXCAN_MCR_HALT; + reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT; priv->write(reg, ®s->mcr);
while (timeout-- && !(priv->read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK))
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Joakim Zhang qiangqing.zhang@nxp.com
commit ec15e27cc8904605846a354bb1f808ea1432f853 upstream.
RX FIFO enable failed could happen when do system reboot stress test:
[ 0.303958] flexcan 5a8d0000.can: 5a8d0000.can supply xceiver not found, using dummy regulator [ 0.304281] flexcan 5a8d0000.can (unnamed net_device) (uninitialized): Could not enable RX FIFO, unsupported core [ 0.314640] flexcan 5a8d0000.can: registering netdev failed [ 0.320728] flexcan 5a8e0000.can: 5a8e0000.can supply xceiver not found, using dummy regulator [ 0.320991] flexcan 5a8e0000.can (unnamed net_device) (uninitialized): Could not enable RX FIFO, unsupported core [ 0.331360] flexcan 5a8e0000.can: registering netdev failed [ 0.337444] flexcan 5a8f0000.can: 5a8f0000.can supply xceiver not found, using dummy regulator [ 0.337716] flexcan 5a8f0000.can (unnamed net_device) (uninitialized): Could not enable RX FIFO, unsupported core [ 0.348117] flexcan 5a8f0000.can: registering netdev failed
RX FIFO should be enabled after the FRZ/HALT are valid. But the current code enable RX FIFO and FRZ/HALT at the same time.
Fixes: e955cead03117 ("CAN: Add Flexcan CAN controller driver") Link: https://lore.kernel.org/r/20210218110037.16591-3-qiangqing.zhang@nxp.com Signed-off-by: Joakim Zhang qiangqing.zhang@nxp.com Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/can/flexcan.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
--- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -1800,10 +1800,14 @@ static int register_flexcandev(struct ne if (err) goto out_chip_disable;
- /* set freeze, halt and activate FIFO, restrict register access */ + /* set freeze, halt */ + err = flexcan_chip_freeze(priv); + if (err) + goto out_chip_disable; + + /* activate FIFO, restrict register access */ reg = priv->read(®s->mcr); - reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | - FLEXCAN_MCR_FEN | FLEXCAN_MCR_SUPV; + reg |= FLEXCAN_MCR_FEN | FLEXCAN_MCR_SUPV; priv->write(reg, ®s->mcr);
/* Currently we only support newer versions of this core
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Joakim Zhang qiangqing.zhang@nxp.com
commit c63820045e2000f05657467a08715c18c9f490d9 upstream.
Invoke flexcan_chip_freeze() to enter freeze mode, since need poll freeze mode acknowledge.
Fixes: e955cead03117 ("CAN: Add Flexcan CAN controller driver") Link: https://lore.kernel.org/r/20210218110037.16591-4-qiangqing.zhang@nxp.com Signed-off-by: Joakim Zhang qiangqing.zhang@nxp.com Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/can/flexcan.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
--- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -1375,10 +1375,13 @@ static int flexcan_chip_start(struct net
flexcan_set_bittiming(dev);
+ /* set freeze, halt */ + err = flexcan_chip_freeze(priv); + if (err) + goto out_chip_disable; + /* MCR * - * enable freeze - * halt now * only supervisor access * enable warning int * enable individual RX masking @@ -1387,9 +1390,8 @@ static int flexcan_chip_start(struct net */ reg_mcr = priv->read(®s->mcr); reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff); - reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | FLEXCAN_MCR_SUPV | - FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_IRMQ | FLEXCAN_MCR_IDAM_C | - FLEXCAN_MCR_MAXMB(priv->tx_mb_idx); + reg_mcr |= FLEXCAN_MCR_SUPV | FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_IRMQ | + FLEXCAN_MCR_IDAM_C | FLEXCAN_MCR_MAXMB(priv->tx_mb_idx);
/* MCR *
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Torin Cooper-Bennun torin@maxiluxsystems.com
commit 2712625200ed69c642b9abc3a403830c4643364c upstream.
This patch prevents a potentially destructive race condition. The device is fully operational on the bus after entering Normal Mode, so zeroing the MRAM after entering this mode may lead to loss of information, e.g. new received messages.
This patch fixes the problem by first initializing the MRAM, then bringing the device into Normale Mode.
Fixes: 5443c226ba91 ("can: tcan4x5x: Add tcan4x5x driver to the kernel") Link: https://lore.kernel.org/r/20210226163440.313628-1-torin@maxiluxsystems.com Suggested-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Torin Cooper-Bennun torin@maxiluxsystems.com Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/can/m_can/tcan4x5x.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
--- a/drivers/net/can/m_can/tcan4x5x.c +++ b/drivers/net/can/m_can/tcan4x5x.c @@ -328,14 +328,14 @@ static int tcan4x5x_init(struct m_can_cl if (ret) return ret;
+ /* Zero out the MCAN buffers */ + m_can_init_ram(cdev); + ret = regmap_update_bits(tcan4x5x->regmap, TCAN4X5X_CONFIG, TCAN4X5X_MODE_SEL_MASK, TCAN4X5X_MODE_NORMAL); if (ret) return ret;
- /* Zero out the MCAN buffers */ - m_can_init_ram(cdev); - return ret; }
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Arjun Roy arjunroy@google.com
commit 2107d45f17bedd7dbf4178462da0ac223835a2a7 upstream.
getsockopt(TCP_ZEROCOPY_RECEIVE) has a bug where we read a user-provided "len" field of type signed int, and then compare the value to the result of an "offsetofend" operation, which is unsigned.
Negative values provided by the user will be promoted to large positive numbers; thus checking that len < offsetofend() will return false when the intention was that it return true.
Note that while len is originally checked for negative values earlier on in do_tcp_getsockopt(), subsequent calls to get_user() re-read the value from userspace which may have changed in the meantime.
Therefore, re-add the check for negative values after the call to get_user in the handler code for TCP_ZEROCOPY_RECEIVE.
Fixes: c8856c051454 ("tcp-zerocopy: Return inq along with tcp receive zerocopy.") Reported-by: kernel test robot lkp@intel.com Reported-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Arjun Roy arjunroy@google.com Link: https://lore.kernel.org/r/20210225232628.4033281-1-arjunroy.kdev@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/ipv4/tcp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -3829,7 +3829,8 @@ static int do_tcp_getsockopt(struct sock
if (get_user(len, optlen)) return -EFAULT; - if (len < offsetofend(struct tcp_zerocopy_receive, length)) + if (len < 0 || + len < offsetofend(struct tcp_zerocopy_receive, length)) return -EINVAL; if (len > sizeof(zc)) { len = sizeof(zc);
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Eric Dumazet edumazet@google.com
commit 8811f4a9836e31c14ecdf79d9f3cb7c5d463265d upstream.
Qingyu Li reported a syzkaller bug where the repro changes RCV SEQ _after_ restoring data in the receive queue.
mprotect(0x4aa000, 12288, PROT_READ) = 0 mmap(0x1ffff000, 4096, PROT_NONE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x1ffff000 mmap(0x20000000, 16777216, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x20000000 mmap(0x21000000, 4096, PROT_NONE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x21000000 socket(AF_INET6, SOCK_STREAM, IPPROTO_IP) = 3 setsockopt(3, SOL_TCP, TCP_REPAIR, [1], 4) = 0 connect(3, {sa_family=AF_INET6, sin6_port=htons(0), sin6_flowinfo=htonl(0), inet_pton(AF_INET6, "::1", &sin6_addr), sin6_scope_id=0}, 28) = 0 setsockopt(3, SOL_TCP, TCP_REPAIR_QUEUE, [1], 4) = 0 sendmsg(3, {msg_name=NULL, msg_namelen=0, msg_iov=[{iov_base="0x0000000000000003\0\0", iov_len=20}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 20 setsockopt(3, SOL_TCP, TCP_REPAIR, [0], 4) = 0 setsockopt(3, SOL_TCP, TCP_QUEUE_SEQ, [128], 4) = 0 recvfrom(3, NULL, 20, 0, NULL, NULL) = -1 ECONNRESET (Connection reset by peer)
syslog shows: [ 111.205099] TCP recvmsg seq # bug 2: copied 80, seq 0, rcvnxt 80, fl 0 [ 111.207894] WARNING: CPU: 1 PID: 356 at net/ipv4/tcp.c:2343 tcp_recvmsg_locked+0x90e/0x29a0
This should not be allowed. TCP_QUEUE_SEQ should only be used when queues are empty.
This patch fixes this case, and the tx path as well.
Fixes: ee9952831cfd ("tcp: Initial repair mode") Signed-off-by: Eric Dumazet edumazet@google.com Cc: Pavel Emelyanov xemul@parallels.com Link: https://bugzilla.kernel.org/show_bug.cgi?id=212005 Reported-by: Qingyu Li ieatmuttonchuan@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/ipv4/tcp.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-)
--- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -3164,16 +3164,23 @@ static int do_tcp_setsockopt(struct sock break;
case TCP_QUEUE_SEQ: - if (sk->sk_state != TCP_CLOSE) + if (sk->sk_state != TCP_CLOSE) { err = -EPERM; - else if (tp->repair_queue == TCP_SEND_QUEUE) - WRITE_ONCE(tp->write_seq, val); - else if (tp->repair_queue == TCP_RECV_QUEUE) { - WRITE_ONCE(tp->rcv_nxt, val); - WRITE_ONCE(tp->copied_seq, val); - } - else + } else if (tp->repair_queue == TCP_SEND_QUEUE) { + if (!tcp_rtx_queue_empty(sk)) + err = -EPERM; + else + WRITE_ONCE(tp->write_seq, val); + } else if (tp->repair_queue == TCP_RECV_QUEUE) { + if (tp->rcv_nxt != tp->copied_seq) { + err = -EPERM; + } else { + WRITE_ONCE(tp->rcv_nxt, val); + WRITE_ONCE(tp->copied_seq, val); + } + } else { err = -EINVAL; + } break;
case TCP_REPAIR_OPTIONS:
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Florian Westphal fw@strlen.de
commit 03a3ca37e4c6478e3a84f04c8429dd5889e107fd upstream.
Under extremely rare conditions TCP early demux will retrieve the wrong socket.
1. local machine establishes a connection to a remote server, S, on port p.
This gives: laddr:lport -> S:p ... both in tcp and conntrack.
2. local machine establishes a connection to host H, on port p2. 2a. TCP stack choses same laddr:lport, so we have laddr:lport -> H:p2 from TCP point of view. 2b). There is a destination NAT rewrite in place, translating H:p2 to S:p. This results in following conntrack entries:
I) laddr:lport -> S:p (origin) S:p -> laddr:lport (reply) II) laddr:lport -> H:p2 (origin) S:p -> laddr:lport2 (reply)
NAT engine has rewritten laddr:lport to laddr:lport2 to map the reply packet to the correct origin.
When server sends SYN/ACK to laddr:lport2, the PREROUTING hook will undo-the SNAT transformation, rewriting IP header to S:p -> laddr:lport
This causes TCP early demux to associate the skb with the TCP socket of the first connection.
The INPUT hook will then reverse the DNAT transformation, rewriting the IP header to H:p2 -> laddr:lport.
Because packet ends up with the wrong socket, the new connection never completes: originator stays in SYN_SENT and conntrack entry remains in SYN_RECV until timeout, and responder retransmits SYN/ACK until it gives up.
To resolve this, orphan the skb after the input rewrite: Because the source IP address changed, the socket must be incorrect. We can't move the DNAT undo to prerouting due to backwards compatibility, doing so will make iptables/nftables rules to no longer match the way they did.
After orphan, the packet will be handed to the next protocol layer (tcp, udp, ...) and that will repeat the socket lookup just like as if early demux was disabled.
Fixes: 41063e9dd1195 ("ipv4: Early TCP socket demux.") Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1427 Signed-off-by: Florian Westphal fw@strlen.de Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/netfilter/nf_nat_proto.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-)
--- a/net/netfilter/nf_nat_proto.c +++ b/net/netfilter/nf_nat_proto.c @@ -646,8 +646,8 @@ nf_nat_ipv4_fn(void *priv, struct sk_buf }
static unsigned int -nf_nat_ipv4_in(void *priv, struct sk_buff *skb, - const struct nf_hook_state *state) +nf_nat_ipv4_pre_routing(void *priv, struct sk_buff *skb, + const struct nf_hook_state *state) { unsigned int ret; __be32 daddr = ip_hdr(skb)->daddr; @@ -660,6 +660,23 @@ nf_nat_ipv4_in(void *priv, struct sk_buf }
static unsigned int +nf_nat_ipv4_local_in(void *priv, struct sk_buff *skb, + const struct nf_hook_state *state) +{ + __be32 saddr = ip_hdr(skb)->saddr; + struct sock *sk = skb->sk; + unsigned int ret; + + ret = nf_nat_ipv4_fn(priv, skb, state); + + if (ret == NF_ACCEPT && sk && saddr != ip_hdr(skb)->saddr && + !inet_sk_transparent(sk)) + skb_orphan(skb); /* TCP edemux obtained wrong socket */ + + return ret; +} + +static unsigned int nf_nat_ipv4_out(void *priv, struct sk_buff *skb, const struct nf_hook_state *state) { @@ -736,7 +753,7 @@ nf_nat_ipv4_local_fn(void *priv, struct static const struct nf_hook_ops nf_nat_ipv4_ops[] = { /* Before packet filtering, change destination */ { - .hook = nf_nat_ipv4_in, + .hook = nf_nat_ipv4_pre_routing, .pf = NFPROTO_IPV4, .hooknum = NF_INET_PRE_ROUTING, .priority = NF_IP_PRI_NAT_DST, @@ -757,7 +774,7 @@ static const struct nf_hook_ops nf_nat_i }, /* After packet filtering, change source */ { - .hook = nf_nat_ipv4_fn, + .hook = nf_nat_ipv4_local_in, .pf = NFPROTO_IPV4, .hooknum = NF_INET_LOCAL_IN, .priority = NF_IP_PRI_NAT_SRC,
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Vasily Averin vvs@virtuozzo.com
commit 8e24edddad152b998b37a7f583175137ed2e04a5 upstream.
nested target/match_revfn() calls work with xt[NFPROTO_UNSPEC] lists without taking xt[NFPROTO_UNSPEC].mutex. This can race with module unload and cause host to crash:
general protection fault: 0000 [#1] Modules linked in: ... [last unloaded: xt_cluster] CPU: 0 PID: 542455 Comm: iptables RIP: 0010:[<ffffffff8ffbd518>] [<ffffffff8ffbd518>] strcmp+0x18/0x40 RDX: 0000000000000003 RSI: ffff9a5a5d9abe10 RDI: dead000000000111 R13: ffff9a5a5d9abe10 R14: ffff9a5a5d9abd8c R15: dead000000000100 (VvS: %R15 -- &xt_match, %RDI -- &xt_match.name, xt_cluster unregister match in xt[NFPROTO_UNSPEC].match list) Call Trace: [<ffffffff902ccf44>] match_revfn+0x54/0xc0 [<ffffffff902ccf9f>] match_revfn+0xaf/0xc0 [<ffffffff902cd01e>] xt_find_revision+0x6e/0xf0 [<ffffffffc05a5be0>] do_ipt_get_ctl+0x100/0x420 [ip_tables] [<ffffffff902cc6bf>] nf_getsockopt+0x4f/0x70 [<ffffffff902dd99e>] ip_getsockopt+0xde/0x100 [<ffffffff903039b5>] raw_getsockopt+0x25/0x50 [<ffffffff9026c5da>] sock_common_getsockopt+0x1a/0x20 [<ffffffff9026b89d>] SyS_getsockopt+0x7d/0xf0 [<ffffffff903cbf92>] system_call_fastpath+0x25/0x2a
Fixes: 656caff20e1 ("netfilter 04/09: x_tables: fix match/target revision lookup") Signed-off-by: Vasily Averin vvs@virtuozzo.com Reviewed-by: Florian Westphal fw@strlen.de Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/netfilter/x_tables.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
--- a/net/netfilter/x_tables.c +++ b/net/netfilter/x_tables.c @@ -330,6 +330,7 @@ static int match_revfn(u8 af, const char const struct xt_match *m; int have_rev = 0;
+ mutex_lock(&xt[af].mutex); list_for_each_entry(m, &xt[af].match, list) { if (strcmp(m->name, name) == 0) { if (m->revision > *bestp) @@ -338,6 +339,7 @@ static int match_revfn(u8 af, const char have_rev = 1; } } + mutex_unlock(&xt[af].mutex);
if (af != NFPROTO_UNSPEC && !have_rev) return match_revfn(NFPROTO_UNSPEC, name, revision, bestp); @@ -350,6 +352,7 @@ static int target_revfn(u8 af, const cha const struct xt_target *t; int have_rev = 0;
+ mutex_lock(&xt[af].mutex); list_for_each_entry(t, &xt[af].target, list) { if (strcmp(t->name, name) == 0) { if (t->revision > *bestp) @@ -358,6 +361,7 @@ static int target_revfn(u8 af, const cha have_rev = 1; } } + mutex_unlock(&xt[af].mutex);
if (af != NFPROTO_UNSPEC && !have_rev) return target_revfn(NFPROTO_UNSPEC, name, revision, bestp); @@ -371,12 +375,10 @@ int xt_find_revision(u8 af, const char * { int have_rev, best = -1;
- mutex_lock(&xt[af].mutex); if (target == 1) have_rev = target_revfn(af, name, revision, &best); else have_rev = match_revfn(af, name, revision, &best); - mutex_unlock(&xt[af].mutex);
/* Nothing at all? Return 0 to try loading module. */ if (best == -1) {
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Jason A. Donenfeld Jason@zx2c4.com
commit 4372339efc06bc2a796f4cc9d0a7a929dfda4967 upstream.
There were a few remaining tunnel drivers that didn't receive the prior conversion to icmp{,v6}_ndo_send. Knowing now that this could lead to memory corrution (see ee576c47db60 ("net: icmp: pass zeroed opts from icmp{,v6}_ndo_send before sending") for details), there's even more imperative to have these all converted. So this commit goes through the remaining cases that I could find and does a boring translation to the ndo variety.
The Fixes: line below is the merge that originally added icmp{,v6}_ ndo_send and converted the first batch of icmp{,v6}_send users. The rationale then for the change applies equally to this patch. It's just that these drivers were left out of the initial conversion because these network devices are hiding in net/ rather than in drivers/net/.
Cc: Florian Westphal fw@strlen.de Cc: Willem de Bruijn willemb@google.com Cc: David S. Miller davem@davemloft.net Cc: Hideaki YOSHIFUJI yoshfuji@linux-ipv6.org Cc: David Ahern dsahern@kernel.org Cc: Jakub Kicinski kuba@kernel.org Cc: Steffen Klassert steffen.klassert@secunet.com Fixes: 803381f9f117 ("Merge branch 'icmp-account-for-NAT-when-sending-icmps-from-ndo-layer'") Signed-off-by: Jason A. Donenfeld Jason@zx2c4.com Acked-by: Willem de Bruijn willemb@google.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/ipv4/ip_tunnel.c | 5 ++--- net/ipv4/ip_vti.c | 6 +++--- net/ipv6/ip6_gre.c | 16 ++++++++-------- net/ipv6/ip6_tunnel.c | 10 +++++----- net/ipv6/ip6_vti.c | 6 +++--- net/ipv6/sit.c | 2 +- 6 files changed, 22 insertions(+), 23 deletions(-)
--- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c @@ -502,8 +502,7 @@ static int tnl_update_pmtu(struct net_de if (!skb_is_gso(skb) && (inner_iph->frag_off & htons(IP_DF)) && mtu < pkt_size) { - memset(IPCB(skb), 0, sizeof(*IPCB(skb))); - icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu)); + icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu)); return -E2BIG; } } @@ -527,7 +526,7 @@ static int tnl_update_pmtu(struct net_de
if (!skb_is_gso(skb) && mtu >= IPV6_MIN_MTU && mtu < pkt_size) { - icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); + icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); return -E2BIG; } } --- a/net/ipv4/ip_vti.c +++ b/net/ipv4/ip_vti.c @@ -238,13 +238,13 @@ static netdev_tx_t vti_xmit(struct sk_bu if (skb->len > mtu) { skb_dst_update_pmtu_no_confirm(skb, mtu); if (skb->protocol == htons(ETH_P_IP)) { - icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, - htonl(mtu)); + icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, + htonl(mtu)); } else { if (mtu < IPV6_MIN_MTU) mtu = IPV6_MIN_MTU;
- icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); + icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); }
dst_release(dst); --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c @@ -678,8 +678,8 @@ static int prepare_ip6gre_xmit_ipv6(stru
tel = (struct ipv6_tlv_tnl_enc_lim *)&skb_network_header(skb)[offset]; if (tel->encap_limit == 0) { - icmpv6_send(skb, ICMPV6_PARAMPROB, - ICMPV6_HDR_FIELD, offset + 2); + icmpv6_ndo_send(skb, ICMPV6_PARAMPROB, + ICMPV6_HDR_FIELD, offset + 2); return -1; } *encap_limit = tel->encap_limit - 1; @@ -805,8 +805,8 @@ static inline int ip6gre_xmit_ipv4(struc if (err != 0) { /* XXX: send ICMP error even if DF is not set. */ if (err == -EMSGSIZE) - icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, - htonl(mtu)); + icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, + htonl(mtu)); return -1; }
@@ -837,7 +837,7 @@ static inline int ip6gre_xmit_ipv6(struc &mtu, skb->protocol); if (err != 0) { if (err == -EMSGSIZE) - icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); + icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); return -1; }
@@ -1063,10 +1063,10 @@ static netdev_tx_t ip6erspan_tunnel_xmit /* XXX: send ICMP error even if DF is not set. */ if (err == -EMSGSIZE) { if (skb->protocol == htons(ETH_P_IP)) - icmp_send(skb, ICMP_DEST_UNREACH, - ICMP_FRAG_NEEDED, htonl(mtu)); + icmp_ndo_send(skb, ICMP_DEST_UNREACH, + ICMP_FRAG_NEEDED, htonl(mtu)); else - icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); + icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); }
goto tx_err; --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -1363,8 +1363,8 @@ ipxip6_tnl_xmit(struct sk_buff *skb, str
tel = (void *)&skb_network_header(skb)[offset]; if (tel->encap_limit == 0) { - icmpv6_send(skb, ICMPV6_PARAMPROB, - ICMPV6_HDR_FIELD, offset + 2); + icmpv6_ndo_send(skb, ICMPV6_PARAMPROB, + ICMPV6_HDR_FIELD, offset + 2); return -1; } encap_limit = tel->encap_limit - 1; @@ -1416,11 +1416,11 @@ ipxip6_tnl_xmit(struct sk_buff *skb, str if (err == -EMSGSIZE) switch (protocol) { case IPPROTO_IPIP: - icmp_send(skb, ICMP_DEST_UNREACH, - ICMP_FRAG_NEEDED, htonl(mtu)); + icmp_ndo_send(skb, ICMP_DEST_UNREACH, + ICMP_FRAG_NEEDED, htonl(mtu)); break; case IPPROTO_IPV6: - icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); + icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); break; default: break; --- a/net/ipv6/ip6_vti.c +++ b/net/ipv6/ip6_vti.c @@ -520,10 +520,10 @@ vti6_xmit(struct sk_buff *skb, struct ne if (mtu < IPV6_MIN_MTU) mtu = IPV6_MIN_MTU;
- icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); + icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); } else { - icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, - htonl(mtu)); + icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, + htonl(mtu)); }
err = -EMSGSIZE; --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -987,7 +987,7 @@ static netdev_tx_t ipip6_tunnel_xmit(str skb_dst_update_pmtu_no_confirm(skb, mtu);
if (skb->len > mtu && !skb_is_gso(skb)) { - icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); + icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); ip_rt_put(rt); goto tx_error; }
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Guangbin Huang huangguangbin2@huawei.com
commit d9032dba5a2b2bbf0fdce67c8795300ec9923b43 upstream.
If phy uses generic driver and autoneg is on, enter command "ethtool -s eth0 speed 50" will not change phy speed actually, but command "ethtool eth0" shows speed is 50Mb/s because phydev->speed has been set to 50 and no update later.
And duplex setting has same problem too.
However, if autoneg is on, phy only changes speed and duplex according to phydev->advertising, but not phydev->speed and phydev->duplex. So in this case, phydev->speed and phydev->duplex don't need to be set in function phy_ethtool_ksettings_set() if autoneg is on.
Fixes: 51e2a3846eab ("PHY: Avoid unnecessary aneg restarts") Signed-off-by: Guangbin Huang huangguangbin2@huawei.com Signed-off-by: Huazhong Tan tanhuazhong@huawei.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/phy/phy.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
--- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -293,14 +293,16 @@ int phy_ethtool_ksettings_set(struct phy
phydev->autoneg = autoneg;
- phydev->speed = speed; + if (autoneg == AUTONEG_DISABLE) { + phydev->speed = speed; + phydev->duplex = duplex; + }
linkmode_copy(phydev->advertising, advertising);
linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->advertising, autoneg == AUTONEG_ENABLE);
- phydev->duplex = duplex; phydev->master_slave_set = cmd->base.master_slave_cfg; phydev->mdix_ctrl = cmd->base.eth_tp_mdix_ctrl;
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Ilya Leoshkevich iii@linux.ibm.com
commit 42a382a466a967dc053c73b969cd2ac2fec502cf upstream.
test_snprintf_btf fails on s390, because NULL points to a readable struct lowcore there. Fix by using the last page instead.
Error message example:
printing fffffffffffff000 should generate error, got (361)
Fixes: 076a95f5aff2 ("selftests/bpf: Add bpf_snprintf_btf helper tests") Signed-off-by: Ilya Leoshkevich iii@linux.ibm.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Acked-by: Heiko Carstens hca@linux.ibm.com Acked-by: Yonghong Song yhs@fb.com Link: https://lore.kernel.org/bpf/20210227051726.121256-1-iii@linux.ibm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- tools/testing/selftests/bpf/progs/netif_receive_skb.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
--- a/tools/testing/selftests/bpf/progs/netif_receive_skb.c +++ b/tools/testing/selftests/bpf/progs/netif_receive_skb.c @@ -16,6 +16,13 @@ bool skip = false; #define STRSIZE 2048 #define EXPECTED_STRSIZE 256
+#if defined(bpf_target_s390) +/* NULL points to a readable struct lowcore on s390, so take the last page */ +#define BADPTR ((void *)0xFFFFFFFFFFFFF000ULL) +#else +#define BADPTR 0 +#endif + #ifndef ARRAY_SIZE #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) #endif @@ -113,11 +120,11 @@ int BPF_PROG(trace_netif_receive_skb, st }
/* Check invalid ptr value */ - p.ptr = 0; + p.ptr = BADPTR; __ret = bpf_snprintf_btf(str, STRSIZE, &p, sizeof(p), 0); if (__ret >= 0) { - bpf_printk("printing NULL should generate error, got (%d)", - __ret); + bpf_printk("printing %llx should generate error, got (%d)", + (unsigned long long)BADPTR, __ret); ret = -ERANGE; }
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Hangbin Liu liuhangbin@gmail.com
commit 557c223b643a35effec9654958d8edc62fd2603a upstream.
In bpf geneve tunnel test we set geneve option on tx side. On rx side we only call bpf_skb_get_tunnel_opt(). Since commit 9c2e14b48119 ("ip_tunnels: Set tunnel option flag when tunnel metadata is present") geneve_rx() will not add TUNNEL_GENEVE_OPT flag if there is no geneve option, which cause bpf_skb_get_tunnel_opt() return ENOENT and _geneve_get_tunnel() in test_tunnel_kern.c drop the packet.
As it should be valid that bpf_skb_get_tunnel_opt() return error when there is not tunnel option, there is no need to drop the packet and break all geneve rx traffic. Just set opt_class to 0 in this test and keep returning TC_ACT_OK.
Fixes: 933a741e3b82 ("selftests/bpf: bpf tunnel test.") Signed-off-by: Hangbin Liu liuhangbin@gmail.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Acked-by: William Tu u9012063@gmail.com Link: https://lore.kernel.org/bpf/20210224081403.1425474-1-liuhangbin@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- tools/testing/selftests/bpf/progs/test_tunnel_kern.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
--- a/tools/testing/selftests/bpf/progs/test_tunnel_kern.c +++ b/tools/testing/selftests/bpf/progs/test_tunnel_kern.c @@ -446,10 +446,8 @@ int _geneve_get_tunnel(struct __sk_buff }
ret = bpf_skb_get_tunnel_opt(skb, &gopt, sizeof(gopt)); - if (ret < 0) { - ERROR(ret); - return TC_ACT_SHOT; - } + if (ret < 0) + gopt.opt_class = 0;
bpf_trace_printk(fmt, sizeof(fmt), key.tunnel_id, key.remote_ipv4, gopt.opt_class);
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Yauheni Kaliuta yauheni.kaliuta@redhat.com
commit 6185266c5a853bb0f2a459e3ff594546f277609b upstream.
The verifier test labelled "valid read map access into a read-only array 2" calls the bpf_csum_diff() helper and checks its return value. However, architecture implementations of csum_partial() (which is what the helper uses) differ in whether they fold the return value to 16 bit or not. For example, x86 version has ...
if (unlikely(odd)) { result = from32to16(result); result = ((result >> 8) & 0xff) | ((result & 0xff) << 8); }
... while generic lib/checksum.c does:
result = from32to16(result); if (odd) result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
This makes the helper return different values on different architectures, breaking the test on non-x86. To fix this, add an additional instruction to always mask the return value to 16 bits, and update the expected return value accordingly.
Fixes: fb2abb73e575 ("bpf, selftest: test {rd, wr}only flags and direct value access") Signed-off-by: Yauheni Kaliuta yauheni.kaliuta@redhat.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Link: https://lore.kernel.org/bpf/20210228103017.320240-1-yauheni.kaliuta@redhat.c... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- tools/testing/selftests/bpf/verifier/array_access.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/tools/testing/selftests/bpf/verifier/array_access.c +++ b/tools/testing/selftests/bpf/verifier/array_access.c @@ -250,12 +250,13 @@ BPF_MOV64_IMM(BPF_REG_5, 0), BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_csum_diff), + BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0xffff), BPF_EXIT_INSN(), }, .prog_type = BPF_PROG_TYPE_SCHED_CLS, .fixup_map_array_ro = { 3 }, .result = ACCEPT, - .retval = -29, + .retval = 65507, }, { "invalid write map access into a read-only array 1",
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Maciej Fijalkowski maciej.fijalkowski@intel.com
commit 6bc6699881012b5bd5d49fa861a69a37fc01b49c upstream.
We mmap the umem region, but we never munmap it. Add the missing call at the end of the cleanup.
Fixes: 3945b37a975d ("samples/bpf: use hugepages in xdpsock app") Signed-off-by: Maciej Fijalkowski maciej.fijalkowski@intel.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Acked-by: Björn Töpel bjorn.topel@intel.com Link: https://lore.kernel.org/bpf/20210303185636.18070-3-maciej.fijalkowski@intel.... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- samples/bpf/xdpsock_user.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/samples/bpf/xdpsock_user.c +++ b/samples/bpf/xdpsock_user.c @@ -1543,5 +1543,7 @@ int main(int argc, char **argv)
xdpsock_cleanup();
+ munmap(bufs, NUM_FRAMES * opt_xsk_frame_size); + return 0; }
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Maciej Fijalkowski maciej.fijalkowski@intel.com
commit 2b2aedabc44e9660f90ccf7ba1ca2706d75f411f upstream.
xsk_lookup_bpf_maps, based on prog_fd, looks whether current prog has a reference to XSKMAP. BPF prog can include insns that work on various BPF maps and this is covered by iterating through map_ids.
The bpf_map_info that is passed to bpf_obj_get_info_by_fd for filling needs to be cleared at each iteration, so that it doesn't contain any outdated fields and that is currently missing in the function of interest.
To fix that, zero-init map_info via memset before each bpf_obj_get_info_by_fd call.
Also, since the area of this code is touched, in general strcmp is considered harmful, so let's convert it to strncmp and provide the size of the array name for current map_info.
While at it, do s/continue/break/ once we have found the xsks_map to terminate the search.
Fixes: 5750902a6e9b ("libbpf: proper XSKMAP cleanup") Signed-off-by: Maciej Fijalkowski maciej.fijalkowski@intel.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Acked-by: Björn Töpel bjorn.topel@intel.com Link: https://lore.kernel.org/bpf/20210303185636.18070-4-maciej.fijalkowski@intel.... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- tools/lib/bpf/xsk.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
--- a/tools/lib/bpf/xsk.c +++ b/tools/lib/bpf/xsk.c @@ -535,15 +535,16 @@ static int xsk_lookup_bpf_maps(struct xs if (fd < 0) continue;
+ memset(&map_info, 0, map_len); err = bpf_obj_get_info_by_fd(fd, &map_info, &map_len); if (err) { close(fd); continue; }
- if (!strcmp(map_info.name, "xsks_map")) { + if (!strncmp(map_info.name, "xsks_map", sizeof(map_info.name))) { ctx->xsks_map_fd = fd; - continue; + break; }
close(fd);
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Michal Suchanek msuchanek@suse.de
commit 6881b07fdd24850def1f03761c66042b983ff86e upstream.
GCC 7.5 reports: ../drivers/net/ethernet/ibm/ibmvnic.c: In function 'ibmvnic_reset_init': ../drivers/net/ethernet/ibm/ibmvnic.c:5373:51: warning: 'old_num_tx_queues' may be used uninitialized in this function [-Wmaybe-uninitialized] ../drivers/net/ethernet/ibm/ibmvnic.c:5373:6: warning: 'old_num_rx_queues' may be used uninitialized in this function [-Wmaybe-uninitialized]
The variable is initialized only if(reset) and used only if(reset && something) so this is a false positive. However, there is no reason to not initialize the variables unconditionally avoiding the warning.
Fixes: 635e442f4a48 ("ibmvnic: merge ibmvnic_reset_init and ibmvnic_init") Signed-off-by: Michal Suchanek msuchanek@suse.de Reviewed-by: Sukadev Bhattiprolu sukadev@linux.ibm.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/ibm/ibmvnic.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
--- a/drivers/net/ethernet/ibm/ibmvnic.c +++ b/drivers/net/ethernet/ibm/ibmvnic.c @@ -5176,16 +5176,14 @@ static int ibmvnic_reset_init(struct ibm { struct device *dev = &adapter->vdev->dev; unsigned long timeout = msecs_to_jiffies(20000); - u64 old_num_rx_queues, old_num_tx_queues; + u64 old_num_rx_queues = adapter->req_rx_queues; + u64 old_num_tx_queues = adapter->req_tx_queues; int rc;
adapter->from_passive_init = false;
- if (reset) { - old_num_rx_queues = adapter->req_rx_queues; - old_num_tx_queues = adapter->req_tx_queues; + if (reset) reinit_completion(&adapter->init_done); - }
adapter->init_done_rc = 0; rc = ibmvnic_send_crq_init(adapter);
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Jiri Wiesner jwiesner@suse.com
commit 67eb211487f0c993d9f402d1c196ef159fd6a3b5 upstream.
The last change to ibmvnic_set_mac(), 8fc3672a8ad3, meant to prevent users from setting an invalid MAC address on an ibmvnic interface that has not been brought up yet. The change also prevented the requested MAC address from being stored by the adapter object for an ibmvnic interface when the state of the ibmvnic interface is VNIC_PROBED - that is after probing has finished but before the ibmvnic interface is brought up. The MAC address stored by the adapter object is used and sent to the hypervisor for checking when an ibmvnic interface is brought up.
The ibmvnic driver ignoring the requested MAC address when in VNIC_PROBED state caused LACP bonds (bonds in 802.3ad mode) with more than one slave to malfunction. The bonding code must be able to change the MAC address of its slaves before they are brought up during enslaving. The inability of kernels with 8fc3672a8ad3 to set the MAC addresses of bonding slaves is observable in the output of "ip address show". The MAC addresses of the slaves are the same as the MAC address of the bond on a working system whereas the slaves retain their original MAC addresses on a system with a malfunctioning LACP bond.
Fixes: 8fc3672a8ad3 ("ibmvnic: fix ibmvnic_set_mac") Signed-off-by: Jiri Wiesner jwiesner@suse.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/ibm/ibmvnic.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
--- a/drivers/net/ethernet/ibm/ibmvnic.c +++ b/drivers/net/ethernet/ibm/ibmvnic.c @@ -1832,10 +1832,9 @@ static int ibmvnic_set_mac(struct net_de if (!is_valid_ether_addr(addr->sa_data)) return -EADDRNOTAVAIL;
- if (adapter->state != VNIC_PROBED) { - ether_addr_copy(adapter->mac_addr, addr->sa_data); + ether_addr_copy(adapter->mac_addr, addr->sa_data); + if (adapter->state != VNIC_PROBED) rc = __ibmvnic_set_mac(netdev, addr->sa_data); - }
return rc; }
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Lorenzo Bianconi lorenzo@kernel.org
commit d0bd52c591a1070c54dc428e926660eb4f981099 upstream.
Commit b102f0c522cf6 ("mt76: fix array overflow on receiving too many fragments for a packet") fixes a possible OOB access but it introduces a memory leak since the pending frame is not released to page_frag_cache if the frag array of skb_shared_info is full. Commit 93a1d4791c10 ("mt76: dma: fix a possible memory leak in mt76_add_fragment()") fixes the issue but does not free the truncated skb that is forwarded to mac80211 layer. Fix the leftover issue discarding even truncated skbs.
Fixes: 93a1d4791c10 ("mt76: dma: fix a possible memory leak in mt76_add_fragment()") Signed-off-by: Lorenzo Bianconi lorenzo@kernel.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/a03166fcc8214644333c68674a781836e0f57576.161269721... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/wireless/mediatek/mt76/dma.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
--- a/drivers/net/wireless/mediatek/mt76/dma.c +++ b/drivers/net/wireless/mediatek/mt76/dma.c @@ -521,13 +521,13 @@ mt76_add_fragment(struct mt76_dev *dev, { struct sk_buff *skb = q->rx_head; struct skb_shared_info *shinfo = skb_shinfo(skb); + int nr_frags = shinfo->nr_frags;
- if (shinfo->nr_frags < ARRAY_SIZE(shinfo->frags)) { + if (nr_frags < ARRAY_SIZE(shinfo->frags)) { struct page *page = virt_to_head_page(data); int offset = data - page_address(page) + q->buf_offset;
- skb_add_rx_frag(skb, shinfo->nr_frags, page, offset, len, - q->buf_size); + skb_add_rx_frag(skb, nr_frags, page, offset, len, q->buf_size); } else { skb_free_frag(data); } @@ -536,7 +536,10 @@ mt76_add_fragment(struct mt76_dev *dev, return;
q->rx_head = NULL; - dev->drv->rx_skb(dev, q - dev->q_rx, skb); + if (nr_frags < ARRAY_SIZE(shinfo->frags)) + dev->drv->rx_skb(dev, q - dev->q_rx, skb); + else + dev_kfree_skb(skb); }
static int
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Christophe Leroy christophe.leroy@csgroup.eu
commit c119565a15a628efdfa51352f9f6c5186e506a1c upstream.
On book3s/32, page protection is defined by the PP bits in the PTE which provide the following protection depending on the access keys defined in the matching segment register: - PP 00 means RW with key 0 and N/A with key 1. - PP 01 means RW with key 0 and RO with key 1. - PP 10 means RW with both key 0 and key 1. - PP 11 means RO with both key 0 and key 1.
Since the implementation of kernel userspace access protection, PP bits have been set as follows: - PP00 for pages without _PAGE_USER - PP01 for pages with _PAGE_USER and _PAGE_RW - PP11 for pages with _PAGE_USER and without _PAGE_RW
For kernelspace segments, kernel accesses are performed with key 0 and user accesses are performed with key 1. As PP00 is used for non _PAGE_USER pages, user can't access kernel pages not flagged _PAGE_USER while kernel can.
For userspace segments, both kernel and user accesses are performed with key 0, therefore pages not flagged _PAGE_USER are still accessible to the user.
This shouldn't be an issue, because userspace is expected to be accessible to the user. But unlike most other architectures, powerpc implements PROT_NONE protection by removing _PAGE_USER flag instead of flagging the page as not valid. This means that pages in userspace that are not flagged _PAGE_USER shall remain inaccessible.
To get the expected behaviour, just mimic other architectures in the TLB miss handler by checking _PAGE_USER permission on userspace accesses as if it was the _PAGE_PRESENT bit.
Note that this problem only is only for 603 cores. The 604+ have an hash table, and hash_page() function already implement the verification of _PAGE_USER permission on userspace pages.
Fixes: f342adca3afc ("powerpc/32s: Prepare Kernel Userspace Access Protection") Cc: stable@vger.kernel.org # v5.2+ Reported-by: Christoph Plattner christoph.plattner@thalesgroup.com Signed-off-by: Christophe Leroy christophe.leroy@csgroup.eu Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/4a0c6e3bb8f0c162457bf54d9bc6fd8d7b55129f.161216090... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/powerpc/kernel/head_book3s_32.S | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
--- a/arch/powerpc/kernel/head_book3s_32.S +++ b/arch/powerpc/kernel/head_book3s_32.S @@ -461,10 +461,11 @@ InstructionTLBMiss: cmplw 0,r1,r3 #endif mfspr r2, SPRN_SPRG_PGDIR - li r1,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC + li r1,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC | _PAGE_USER #if defined(CONFIG_MODULES) || defined(CONFIG_DEBUG_PAGEALLOC) bgt- 112f lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */ + li r1,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */ #endif 112: rlwimi r2,r3,12,20,29 /* insert top 10 bits of address */ @@ -523,9 +524,10 @@ DataLoadTLBMiss: lis r1, TASK_SIZE@h /* check if kernel address */ cmplw 0,r1,r3 mfspr r2, SPRN_SPRG_PGDIR - li r1, _PAGE_PRESENT | _PAGE_ACCESSED + li r1, _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_USER bgt- 112f lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */ + li r1, _PAGE_PRESENT | _PAGE_ACCESSED addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */ 112: rlwimi r2,r3,12,20,29 /* insert top 10 bits of address */ lwz r2,0(r2) /* get pmd entry */ @@ -599,9 +601,10 @@ DataStoreTLBMiss: lis r1, TASK_SIZE@h /* check if kernel address */ cmplw 0,r1,r3 mfspr r2, SPRN_SPRG_PGDIR - li r1, _PAGE_RW | _PAGE_DIRTY | _PAGE_PRESENT | _PAGE_ACCESSED + li r1, _PAGE_RW | _PAGE_DIRTY | _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_USER bgt- 112f lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */ + li r1, _PAGE_RW | _PAGE_DIRTY | _PAGE_PRESENT | _PAGE_ACCESSED addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */ 112: rlwimi r2,r3,12,20,29 /* insert top 10 bits of address */ lwz r2,0(r2) /* get pmd entry */
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Christian Brauner christian.brauner@ubuntu.com
commit ee2e3f50629f17b0752b55b2566c15ce8dafb557 upstream.
Creating a series of detached mounts, attaching them to the filesystem, and unmounting them can be used to trigger an integer overflow in ns->mounts causing the kernel to block any new mounts in count_mounts() and returning ENOSPC because it falsely assumes that the maximum number of mounts in the mount namespace has been reached, i.e. it thinks it can't fit the new mounts into the mount namespace anymore.
Depending on the number of mounts in your system, this can be reproduced on any kernel that supportes open_tree() and move_mount() by compiling and running the following program:
/* SPDX-License-Identifier: LGPL-2.1+ */
#define _GNU_SOURCE #include <errno.h> #include <fcntl.h> #include <getopt.h> #include <limits.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/mount.h> #include <sys/stat.h> #include <sys/syscall.h> #include <sys/types.h> #include <unistd.h>
/* open_tree() */ #ifndef OPEN_TREE_CLONE #define OPEN_TREE_CLONE 1 #endif
#ifndef OPEN_TREE_CLOEXEC #define OPEN_TREE_CLOEXEC O_CLOEXEC #endif
#ifndef __NR_open_tree #if defined __alpha__ #define __NR_open_tree 538 #elif defined _MIPS_SIM #if _MIPS_SIM == _MIPS_SIM_ABI32 /* o32 */ #define __NR_open_tree 4428 #endif #if _MIPS_SIM == _MIPS_SIM_NABI32 /* n32 */ #define __NR_open_tree 6428 #endif #if _MIPS_SIM == _MIPS_SIM_ABI64 /* n64 */ #define __NR_open_tree 5428 #endif #elif defined __ia64__ #define __NR_open_tree (428 + 1024) #else #define __NR_open_tree 428 #endif #endif
/* move_mount() */ #ifndef MOVE_MOUNT_F_EMPTY_PATH #define MOVE_MOUNT_F_EMPTY_PATH 0x00000004 /* Empty from path permitted */ #endif
#ifndef __NR_move_mount #if defined __alpha__ #define __NR_move_mount 539 #elif defined _MIPS_SIM #if _MIPS_SIM == _MIPS_SIM_ABI32 /* o32 */ #define __NR_move_mount 4429 #endif #if _MIPS_SIM == _MIPS_SIM_NABI32 /* n32 */ #define __NR_move_mount 6429 #endif #if _MIPS_SIM == _MIPS_SIM_ABI64 /* n64 */ #define __NR_move_mount 5429 #endif #elif defined __ia64__ #define __NR_move_mount (428 + 1024) #else #define __NR_move_mount 429 #endif #endif
static inline int sys_open_tree(int dfd, const char *filename, unsigned int flags) { return syscall(__NR_open_tree, dfd, filename, flags); }
static inline int sys_move_mount(int from_dfd, const char *from_pathname, int to_dfd, const char *to_pathname, unsigned int flags) { return syscall(__NR_move_mount, from_dfd, from_pathname, to_dfd, to_pathname, flags); }
static bool is_shared_mountpoint(const char *path) { bool shared = false; FILE *f = NULL; char *line = NULL; int i; size_t len = 0;
f = fopen("/proc/self/mountinfo", "re"); if (!f) return 0;
while (getline(&line, &len, f) > 0) { char *slider1, *slider2;
for (slider1 = line, i = 0; slider1 && i < 4; i++) slider1 = strchr(slider1 + 1, ' ');
if (!slider1) continue;
slider2 = strchr(slider1 + 1, ' '); if (!slider2) continue;
*slider2 = '\0'; if (strcmp(slider1 + 1, path) == 0) { /* This is the path. Is it shared? */ slider1 = strchr(slider2 + 1, ' '); if (slider1 && strstr(slider1, "shared:")) { shared = true; break; } } } fclose(f); free(line);
return shared; }
static void usage(void) { const char *text = "mount-new [--recursive] <base-dir>\n"; fprintf(stderr, "%s", text); _exit(EXIT_SUCCESS); }
#define exit_usage(format, ...) \ ({ \ fprintf(stderr, format "\n", ##__VA_ARGS__); \ usage(); \ })
#define exit_log(format, ...) \ ({ \ fprintf(stderr, format "\n", ##__VA_ARGS__); \ exit(EXIT_FAILURE); \ })
static const struct option longopts[] = { {"help", no_argument, 0, 'a'}, { NULL, no_argument, 0, 0 }, };
int main(int argc, char *argv[]) { int exit_code = EXIT_SUCCESS, index = 0; int dfd, fd_tree, new_argc, ret; char *base_dir; char *const *new_argv; char target[PATH_MAX];
while ((ret = getopt_long_only(argc, argv, "", longopts, &index)) != -1) { switch (ret) { case 'a': /* fallthrough */ default: usage(); } }
new_argv = &argv[optind]; new_argc = argc - optind; if (new_argc < 1) exit_usage("Missing base directory\n"); base_dir = new_argv[0];
if (*base_dir != '/') exit_log("Please specify an absolute path");
/* Ensure that target is a shared mountpoint. */ if (!is_shared_mountpoint(base_dir)) exit_log("Please ensure that "%s" is a shared mountpoint", base_dir);
dfd = open(base_dir, O_RDONLY | O_DIRECTORY | O_CLOEXEC); if (dfd < 0) exit_log("%m - Failed to open base directory "%s"", base_dir);
ret = mkdirat(dfd, "detached-move-mount", 0755); if (ret < 0) exit_log("%m - Failed to create required temporary directories");
ret = snprintf(target, sizeof(target), "%s/detached-move-mount", base_dir); if (ret < 0 || (size_t)ret >= sizeof(target)) exit_log("%m - Failed to assemble target path");
/* * Having a mount table with 10000 mounts is already quite excessive * and shoult account even for weird test systems. */ for (size_t i = 0; i < 10000; i++) { fd_tree = sys_open_tree(dfd, "detached-move-mount", OPEN_TREE_CLONE | OPEN_TREE_CLOEXEC | AT_EMPTY_PATH); if (fd_tree < 0) { fprintf(stderr, "%m - Failed to open %d(detached-move-mount)", dfd); exit_code = EXIT_FAILURE; break; }
ret = sys_move_mount(fd_tree, "", dfd, "detached-move-mount", MOVE_MOUNT_F_EMPTY_PATH); if (ret < 0) { if (errno == ENOSPC) fprintf(stderr, "%m - Buggy mount counting"); else fprintf(stderr, "%m - Failed to attach mount to %d(detached-move-mount)", dfd); exit_code = EXIT_FAILURE; break; } close(fd_tree);
ret = umount2(target, MNT_DETACH); if (ret < 0) { fprintf(stderr, "%m - Failed to unmount %s", target); exit_code = EXIT_FAILURE; break; } }
(void)unlinkat(dfd, "detached-move-mount", AT_REMOVEDIR); close(dfd);
exit(exit_code); }
and wait for the kernel to refuse any new mounts by returning ENOSPC. How many iterations are needed depends on the number of mounts in your system. Assuming you have something like 50 mounts on a standard system it should be almost instantaneous.
The root cause of this is that detached mounts aren't handled correctly when source and target mount are identical and reside on a shared mount causing a broken mount tree where the detached source itself is propagated which propagation prevents for regular bind-mounts and new mounts. This ultimately leads to a miscalculation of the number of mounts in the mount namespace.
Detached mounts created via open_tree(fd, path, OPEN_TREE_CLONE) are essentially like an unattached new mount, or an unattached bind-mount. They can then later on be attached to the filesystem via move_mount() which calls into attach_recursive_mount(). Part of attaching it to the filesystem is making sure that mounts get correctly propagated in case the destination mountpoint is MS_SHARED, i.e. is a shared mountpoint. This is done by calling into propagate_mnt() which walks the list of peers calling propagate_one() on each mount in this list making sure it receives the propagation event. The propagate_one() functions thereby skips both new mounts and bind mounts to not propagate them "into themselves". Both are identified by checking whether the mount is already attached to any mount namespace in mnt->mnt_ns. The is what the IS_MNT_NEW() helper is responsible for.
However, detached mounts have an anonymous mount namespace attached to them stashed in mnt->mnt_ns which means that IS_MNT_NEW() doesn't realize they need to be skipped causing the mount to propagate "into itself" breaking the mount table and causing a disconnect between the number of mounts recorded as being beneath or reachable from the target mountpoint and the number of mounts actually recorded/counted in ns->mounts ultimately causing an overflow which in turn prevents any new mounts via the ENOSPC issue.
So teach propagation to handle detached mounts by making it aware of them. I've been tracking this issue down for the last couple of days and then verifying that the fix is correct by unmounting everything in my current mount table leaving only /proc and /sys mounted and running the reproducer above overnight verifying the number of mounts counted in ns->mounts. With this fix the counts are correct and the ENOSPC issue can't be reproduced.
This change will only have an effect on mounts created with the new mount API since detached mounts cannot be created with the old mount API so regressions are extremely unlikely.
Link: https://lore.kernel.org/r/20210306101010.243666-1-christian.brauner@ubuntu.c... Fixes: 2db154b3ea8e ("vfs: syscall: Add move_mount(2) to move mounts around") Cc: David Howells dhowells@redhat.com Cc: Al Viro viro@zeniv.linux.org.uk Cc: linux-fsdevel@vger.kernel.org Cc: stable@vger.kernel.org Reviewed-by: Christoph Hellwig hch@lst.de Signed-off-by: Christian Brauner christian.brauner@ubuntu.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/pnode.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/pnode.h +++ b/fs/pnode.h @@ -12,7 +12,7 @@
#define IS_MNT_SHARED(m) ((m)->mnt.mnt_flags & MNT_SHARED) #define IS_MNT_SLAVE(m) ((m)->mnt_master) -#define IS_MNT_NEW(m) (!(m)->mnt_ns) +#define IS_MNT_NEW(m) (!(m)->mnt_ns || is_anon_ns((m)->mnt_ns)) #define CLEAR_MNT_SHARED(m) ((m)->mnt.mnt_flags &= ~MNT_SHARED) #define IS_MNT_UNBINDABLE(m) ((m)->mnt.mnt_flags & MNT_UNBINDABLE) #define IS_MNT_MARKED(m) ((m)->mnt.mnt_flags & MNT_MARKED)
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Paulo Alcantara pc@cjr.nz
commit 14302ee3301b3a77b331cc14efb95bf7184c73cc upstream.
In cifs_statfs(), if server->ops->queryfs is not NULL, then we should use its return value rather than always returning 0. Instead, use rc variable as it is properly set to 0 in case there is no server->ops->queryfs.
Signed-off-by: Paulo Alcantara (SUSE) pc@cjr.nz Reviewed-by: Aurelien Aptel aaptel@suse.com Reviewed-by: Ronnie Sahlberg lsahlber@redhat.com CC: stable@vger.kernel.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/cifs/cifsfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -286,7 +286,7 @@ cifs_statfs(struct dentry *dentry, struc rc = server->ops->queryfs(xid, tcon, cifs_sb, buf);
free_xid(xid); - return 0; + return rc; }
static long cifs_fallocate(struct file *file, int mode, loff_t off, loff_t len)
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Linus Torvalds torvalds@linux-foundation.org
commit 9b1ea29bc0d7b94d420f96a0f4121403efc3dd85 upstream.
This reverts commit 8ff60eb052eeba95cfb3efe16b08c9199f8121cf.
The kernel test robot reports a huge performance regression due to the commit, and the reason seems fairly straightforward: when there is contention on the page list (which is what causes acquire_slab() to fail), we do _not_ want to just loop and try again, because that will transfer the contention to the 'n->list_lock' spinlock we hold, and just make things even worse.
This is admittedly likely a problem only on big machines - the kernel test robot report comes from a 96-thread dual socket Intel Xeon Gold 6252 setup, but the regression there really is quite noticeable:
-47.9% regression of stress-ng.rawpkt.ops_per_sec
and the commit that was marked as being fixed (7ced37197196: "slub: Acquire_slab() avoid loop") actually did the loop exit early very intentionally (the hint being that "avoid loop" part of that commit message), exactly to avoid this issue.
The correct thing to do may be to pick some kind of reasonable middle ground: instead of breaking out of the loop on the very first sign of contention, or trying over and over and over again, the right thing may be to re-try _once_, and then give up on the second failure (or pick your favorite value for "once"..).
Reported-by: kernel test robot oliver.sang@intel.com Link: https://lore.kernel.org/lkml/20210301080404.GF12822@xsang-OptiPlex-9020/ Cc: Jann Horn jannh@google.com Cc: David Rientjes rientjes@google.com Cc: Joonsoo Kim iamjoonsoo.kim@lge.com Acked-by: Christoph Lameter cl@linux.com Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- mm/slub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/mm/slub.c +++ b/mm/slub.c @@ -1971,7 +1971,7 @@ static void *get_partial_node(struct kme
t = acquire_slab(s, n, page, object == NULL, &objects); if (!t) - continue; /* cmpxchg raced */ + break;
available += objects; if (!object) {
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Jakub Kicinski kuba@kernel.org
commit dbbe7c962c3a8163bf724dbc3c9fdfc9b16d3117 upstream.
Leave it to Greg.
Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- Documentation/networking/netdev-FAQ.rst | 78 ++------------------------ Documentation/process/stable-kernel-rules.rst | 6 -- Documentation/process/submitting-patches.rst | 5 - 3 files changed, 7 insertions(+), 82 deletions(-)
--- a/Documentation/networking/netdev-FAQ.rst +++ b/Documentation/networking/netdev-FAQ.rst @@ -144,77 +144,13 @@ Please send incremental versions on top the patches the way they would look like if your latest patch series was to be merged.
-Q: How can I tell what patches are queued up for backporting to the various stable releases? --------------------------------------------------------------------------------------------- -A: Normally Greg Kroah-Hartman collects stable commits himself, but for -networking, Dave collects up patches he deems critical for the -networking subsystem, and then hands them off to Greg. - -There is a patchworks queue that you can see here: - - https://patchwork.kernel.org/bundle/netdev/stable/?state=* - -It contains the patches which Dave has selected, but not yet handed off -to Greg. If Greg already has the patch, then it will be here: - - https://git.kernel.org/pub/scm/linux/kernel/git/stable/stable-queue.git - -A quick way to find whether the patch is in this stable-queue is to -simply clone the repo, and then git grep the mainline commit ID, e.g. -:: - - stable-queue$ git grep -l 284041ef21fdf2e - releases/3.0.84/ipv6-fix-possible-crashes-in-ip6_cork_release.patch - releases/3.4.51/ipv6-fix-possible-crashes-in-ip6_cork_release.patch - releases/3.9.8/ipv6-fix-possible-crashes-in-ip6_cork_release.patch - stable/stable-queue$ - -Q: I see a network patch and I think it should be backported to stable. ------------------------------------------------------------------------ -Q: Should I request it via stable@vger.kernel.org like the references in -the kernel's Documentation/process/stable-kernel-rules.rst file say? -A: No, not for networking. Check the stable queues as per above first -to see if it is already queued. If not, then send a mail to netdev, -listing the upstream commit ID and why you think it should be a stable -candidate. - -Before you jump to go do the above, do note that the normal stable rules -in :ref:`Documentation/process/stable-kernel-rules.rst <stable_kernel_rules>` -still apply. So you need to explicitly indicate why it is a critical -fix and exactly what users are impacted. In addition, you need to -convince yourself that you *really* think it has been overlooked, -vs. having been considered and rejected. - -Generally speaking, the longer it has had a chance to "soak" in -mainline, the better the odds that it is an OK candidate for stable. So -scrambling to request a commit be added the day after it appears should -be avoided. - -Q: I have created a network patch and I think it should be backported to stable. --------------------------------------------------------------------------------- -Q: Should I add a Cc: stable@vger.kernel.org like the references in the -kernel's Documentation/ directory say? -A: No. See above answer. In short, if you think it really belongs in -stable, then ensure you write a decent commit log that describes who -gets impacted by the bug fix and how it manifests itself, and when the -bug was introduced. If you do that properly, then the commit will get -handled appropriately and most likely get put in the patchworks stable -queue if it really warrants it. - -If you think there is some valid information relating to it being in -stable that does *not* belong in the commit log, then use the three dash -marker line as described in -:ref:`Documentation/process/submitting-patches.rst <the_canonical_patch_format>` -to temporarily embed that information into the patch that you send. - -Q: Are all networking bug fixes backported to all stable releases? ------------------------------------------------------------------- -A: Due to capacity, Dave could only take care of the backports for the -last two stable releases. For earlier stable releases, each stable -branch maintainer is supposed to take care of them. If you find any -patch is missing from an earlier stable branch, please notify -stable@vger.kernel.org with either a commit ID or a formal patch -backported, and CC Dave and other relevant networking developers. +Q: Are there special rules regarding stable submissions on netdev? +--------------------------------------------------------------- +While it used to be the case that netdev submissions were not supposed +to carry explicit ``CC: stable@vger.kernel.org`` tags that is no longer +the case today. Please follow the standard stable rules in +:ref:`Documentation/process/stable-kernel-rules.rst <stable_kernel_rules>`, +and make sure you include appropriate Fixes tags!
Q: Is the comment style convention different for the networking content? ------------------------------------------------------------------------ --- a/Documentation/process/stable-kernel-rules.rst +++ b/Documentation/process/stable-kernel-rules.rst @@ -35,12 +35,6 @@ Rules on what kind of patches are accept Procedure for submitting patches to the -stable tree ----------------------------------------------------
- - If the patch covers files in net/ or drivers/net please follow netdev stable - submission guidelines as described in - :ref:`Documentation/networking/netdev-FAQ.rst <netdev-FAQ>` - after first checking the stable networking queue at - https://patchwork.kernel.org/bundle/netdev/stable/?state=* - to ensure the requested patch is not already queued up. - Security patches should not be handled (solely) by the -stable review process but should follow the procedures in :ref:`Documentation/admin-guide/security-bugs.rst <securitybugs>`. --- a/Documentation/process/submitting-patches.rst +++ b/Documentation/process/submitting-patches.rst @@ -250,11 +250,6 @@ should also read :ref:`Documentation/process/stable-kernel-rules.rst <stable_kernel_rules>` in addition to this file.
-Note, however, that some subsystem maintainers want to come to their own -conclusions on which patches should go to the stable trees. The networking -maintainer, in particular, would rather not see individual developers -adding lines like the above to their patches. - If changes affect userland-kernel interfaces, please send the MAN-PAGES maintainer (as listed in the MAINTAINERS file) a man-pages patch, or at least a notification of the change, so that some information makes its way
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: DENG Qingfang dqfext@gmail.com
commit 9eb8bc593a5eed167dac2029abef343854c5ba75 upstream.
Commit 86dd9868b878 has several issues, but was accepted too soon before anyone could take a look.
- Double free. dsa_slave_xmit() will free the skb if the xmit function returns NULL, but the skb is already freed by eth_skb_pad(). Use __skb_put_padto() to avoid that. - Unnecessary allocation. It has been done by DSA core since commit a3b0b6479700. - A u16 pointer points to skb data. It should be __be16 for network byte order. - Typo in comments. "numer" -> "number".
Fixes: 86dd9868b878 ("net: dsa: tag_rtl4_a: Support also egress tags") Signed-off-by: DENG Qingfang dqfext@gmail.com Reviewed-by: Florian Fainelli f.fainelli@gmail.com Reviewed-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/dsa/tag_rtl4_a.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-)
--- a/net/dsa/tag_rtl4_a.c +++ b/net/dsa/tag_rtl4_a.c @@ -35,14 +35,12 @@ static struct sk_buff *rtl4a_tag_xmit(st struct net_device *dev) { struct dsa_port *dp = dsa_slave_to_port(dev); + __be16 *p; u8 *tag; - u16 *p; u16 out;
/* Pad out to at least 60 bytes */ - if (unlikely(eth_skb_pad(skb))) - return NULL; - if (skb_cow_head(skb, RTL4_A_HDR_LEN) < 0) + if (unlikely(__skb_put_padto(skb, ETH_ZLEN, false))) return NULL;
netdev_dbg(dev, "add realtek tag to package to port %d\n", @@ -53,13 +51,13 @@ static struct sk_buff *rtl4a_tag_xmit(st tag = skb->data + 2 * ETH_ALEN;
/* Set Ethertype */ - p = (u16 *)tag; + p = (__be16 *)tag; *p = htons(RTL4_A_ETHERTYPE);
out = (RTL4_A_PROTOCOL_RTL8366RB << 12) | (2 << 8); - /* The lower bits is the port numer */ + /* The lower bits is the port number */ out |= (u8)dp->index; - p = (u16 *)(tag + 2); + p = (__be16 *)(tag + 2); *p = htons(out);
return skb;
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Sergey Shtylyov s.shtylyov@omprussia.ru
commit 8c91bc3d44dfef8284af384877fbe61117e8b7d1 upstream.
According to the SH7710, SH7712, SH7713 Group User's Manual: Hardware, Rev. 3.00, the TRSCER register actually has only bit 7 valid (and named differently), with all the other bits reserved. Apparently, this was not the case with some early revisions of the manual as we have the other bits declared (and set) in the original driver. Follow the suit and add the explicit sh_eth_cpu_data::trscer_err_mask initializer for SH771x...
Fixes: 86a74ff21a7a ("net: sh_eth: add support for Renesas SuperH Ethernet") Signed-off-by: Sergey Shtylyov s.shtylyov@omprussia.ru Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/renesas/sh_eth.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -1089,6 +1089,9 @@ static struct sh_eth_cpu_data sh771x_dat EESIPR_CEEFIP | EESIPR_CELFIP | EESIPR_RRFIP | EESIPR_RTLFIP | EESIPR_RTSFIP | EESIPR_PREIP | EESIPR_CERFIP, + + .trscer_err_mask = DESC_I_RINT8, + .tsu = 1, .dual_port = 1, };
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Vladimir Oltean vladimir.oltean@nxp.com
commit c646d10dda2dcde82c6ce5a474522621ab2b8b19 upstream.
After the blamed patch, all RX traffic gets hashed to CPU 0 because the hashing indirection table set up in:
enetc_pf_probe -> enetc_alloc_si_resources -> enetc_configure_si -> enetc_setup_default_rss_table
is overwritten later in:
enetc_pf_probe -> enetc_init_port_rss_memory
which zero-initializes the entire port RSS table in order to avoid ECC errors.
The trouble really is that enetc_init_port_rss_memory really neads enetc_alloc_si_resources to be called, because it depends upon enetc_alloc_cbdr and enetc_setup_cbdr. But that whole enetc_configure_si thing could have been better thought out, it has nothing to do in a function called "alloc_si_resources", especially since its counterpart, "free_si_resources", does nothing to unwind the configuration of the SI.
The point is, we need to pull out enetc_configure_si out of enetc_alloc_resources, and move it after enetc_init_port_rss_memory. This allows us to set up the default RSS indirection table after initializing the memory.
Fixes: 07bf34a50e32 ("net: enetc: initialize the RFS and RSS memories") Cc: Jesse Brandeburg jesse.brandeburg@intel.com Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/freescale/enetc/enetc.c | 11 +++-------- drivers/net/ethernet/freescale/enetc/enetc.h | 1 + drivers/net/ethernet/freescale/enetc/enetc_pf.c | 7 +++++++ drivers/net/ethernet/freescale/enetc/enetc_vf.c | 7 +++++++ 4 files changed, 18 insertions(+), 8 deletions(-)
--- a/drivers/net/ethernet/freescale/enetc/enetc.c +++ b/drivers/net/ethernet/freescale/enetc/enetc.c @@ -1098,13 +1098,12 @@ static int enetc_setup_default_rss_table return 0; }
-static int enetc_configure_si(struct enetc_ndev_priv *priv) +int enetc_configure_si(struct enetc_ndev_priv *priv) { struct enetc_si *si = priv->si; struct enetc_hw *hw = &si->hw; int err;
- enetc_setup_cbdr(hw, &si->cbd_ring); /* set SI cache attributes */ enetc_wr(hw, ENETC_SICAR0, ENETC_SICAR_RD_COHERENT | ENETC_SICAR_WR_COHERENT); @@ -1152,6 +1151,8 @@ int enetc_alloc_si_resources(struct enet if (err) return err;
+ enetc_setup_cbdr(&si->hw, &si->cbd_ring); + priv->cls_rules = kcalloc(si->num_fs_entries, sizeof(*priv->cls_rules), GFP_KERNEL); if (!priv->cls_rules) { @@ -1159,14 +1160,8 @@ int enetc_alloc_si_resources(struct enet goto err_alloc_cls; }
- err = enetc_configure_si(priv); - if (err) - goto err_config_si; - return 0;
-err_config_si: - kfree(priv->cls_rules); err_alloc_cls: enetc_clear_cbdr(&si->hw); enetc_free_cbdr(priv->dev, &si->cbd_ring); --- a/drivers/net/ethernet/freescale/enetc/enetc.h +++ b/drivers/net/ethernet/freescale/enetc/enetc.h @@ -293,6 +293,7 @@ void enetc_get_si_caps(struct enetc_si * void enetc_init_si_rings_params(struct enetc_ndev_priv *priv); int enetc_alloc_si_resources(struct enetc_ndev_priv *priv); void enetc_free_si_resources(struct enetc_ndev_priv *priv); +int enetc_configure_si(struct enetc_ndev_priv *priv);
int enetc_open(struct net_device *ndev); int enetc_close(struct net_device *ndev); --- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c +++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c @@ -1115,6 +1115,12 @@ static int enetc_pf_probe(struct pci_dev goto err_init_port_rss; }
+ err = enetc_configure_si(priv); + if (err) { + dev_err(&pdev->dev, "Failed to configure SI\n"); + goto err_config_si; + } + err = enetc_alloc_msix(priv); if (err) { dev_err(&pdev->dev, "MSIX alloc failed\n"); @@ -1143,6 +1149,7 @@ err_phylink_create: enetc_mdiobus_destroy(pf); err_mdiobus_create: enetc_free_msix(priv); +err_config_si: err_init_port_rss: err_init_port_rfs: err_alloc_msix: --- a/drivers/net/ethernet/freescale/enetc/enetc_vf.c +++ b/drivers/net/ethernet/freescale/enetc/enetc_vf.c @@ -177,6 +177,12 @@ static int enetc_vf_probe(struct pci_dev goto err_alloc_si_res; }
+ err = enetc_configure_si(priv); + if (err) { + dev_err(&pdev->dev, "Failed to configure SI\n"); + goto err_config_si; + } + err = enetc_alloc_msix(priv); if (err) { dev_err(&pdev->dev, "MSIX alloc failed\n"); @@ -193,6 +199,7 @@ static int enetc_vf_probe(struct pci_dev
err_reg_netdev: enetc_free_msix(priv); +err_config_si: err_alloc_msix: enetc_free_si_resources(priv); err_alloc_si_res:
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Vladimir Oltean vladimir.oltean@nxp.com
commit 6d36ecdbc4410e61a0e02adc5d3abeee22a8ffd3 upstream.
The workaround for the ENETC MDIO erratum caused a performance degradation of 82 Kpps (seen with IP forwarding of two 1Gbps streams of 64B packets). This is due to excessive locking and unlocking in the fast path, which can be avoided.
By taking the MDIO read-side lock only once per NAPI poll cycle, we are able to regain 54 Kpps (65%) of the performance hit. The rest of the performance degradation comes from the TX data path, but unfortunately it doesn't look like we can optimize that away easily, even with netdev_xmit_more(), there just isn't any skb batching done, to help with taking the MDIO lock less often than once per packet.
We need to change the register accessor type for enetc_get_tx_tstamp, because it now runs under the enetc_lock_mdio as per the new call path detailed below:
enetc_msix -> napi_schedule -> enetc_poll -> enetc_lock_mdio -> enetc_clean_tx_ring -> enetc_get_tx_tstamp -> enetc_clean_rx_ring -> enetc_unlock_mdio
Fixes: fd5736bf9f23 ("enetc: Workaround for MDIO register access issue") Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/freescale/enetc/enetc.c | 31 ++++++------------------ drivers/net/ethernet/freescale/enetc/enetc_hw.h | 2 + 2 files changed, 11 insertions(+), 22 deletions(-)
--- a/drivers/net/ethernet/freescale/enetc/enetc.c +++ b/drivers/net/ethernet/freescale/enetc/enetc.c @@ -321,6 +321,8 @@ static int enetc_poll(struct napi_struct int work_done; int i;
+ enetc_lock_mdio(); + for (i = 0; i < v->count_tx_rings; i++) if (!enetc_clean_tx_ring(&v->tx_ring[i], budget)) complete = false; @@ -331,8 +333,10 @@ static int enetc_poll(struct napi_struct if (work_done) v->rx_napi_work = true;
- if (!complete) + if (!complete) { + enetc_unlock_mdio(); return budget; + }
napi_complete_done(napi, work_done);
@@ -341,8 +345,6 @@ static int enetc_poll(struct napi_struct
v->rx_napi_work = false;
- enetc_lock_mdio(); - /* enable interrupts */ enetc_wr_reg_hot(v->rbier, ENETC_RBIER_RXTIE);
@@ -367,8 +369,8 @@ static void enetc_get_tx_tstamp(struct e { u32 lo, hi, tstamp_lo;
- lo = enetc_rd(hw, ENETC_SICTR0); - hi = enetc_rd(hw, ENETC_SICTR1); + lo = enetc_rd_hot(hw, ENETC_SICTR0); + hi = enetc_rd_hot(hw, ENETC_SICTR1); tstamp_lo = le32_to_cpu(txbd->wb.tstamp); if (lo <= tstamp_lo) hi -= 1; @@ -398,9 +400,7 @@ static bool enetc_clean_tx_ring(struct e i = tx_ring->next_to_clean; tx_swbd = &tx_ring->tx_swbd[i];
- enetc_lock_mdio(); bds_to_clean = enetc_bd_ready_count(tx_ring, i); - enetc_unlock_mdio();
do_tstamp = false;
@@ -443,8 +443,6 @@ static bool enetc_clean_tx_ring(struct e tx_swbd = tx_ring->tx_swbd; }
- enetc_lock_mdio(); - /* BD iteration loop end */ if (is_eof) { tx_frm_cnt++; @@ -455,8 +453,6 @@ static bool enetc_clean_tx_ring(struct e
if (unlikely(!bds_to_clean)) bds_to_clean = enetc_bd_ready_count(tx_ring, i); - - enetc_unlock_mdio(); }
tx_ring->next_to_clean = i; @@ -700,8 +696,6 @@ static int enetc_clean_rx_ring(struct en u32 bd_status; u16 size;
- enetc_lock_mdio(); - if (cleaned_cnt >= ENETC_RXBD_BUNDLE) { int count = enetc_refill_rx_ring(rx_ring, cleaned_cnt);
@@ -712,19 +706,15 @@ static int enetc_clean_rx_ring(struct en
rxbd = enetc_rxbd(rx_ring, i); bd_status = le32_to_cpu(rxbd->r.lstatus); - if (!bd_status) { - enetc_unlock_mdio(); + if (!bd_status) break; - }
enetc_wr_reg_hot(rx_ring->idr, BIT(rx_ring->index)); dma_rmb(); /* for reading other rxbd fields */ size = le16_to_cpu(rxbd->r.buf_len); skb = enetc_map_rx_buff_to_skb(rx_ring, i, size); - if (!skb) { - enetc_unlock_mdio(); + if (!skb) break; - }
enetc_get_offloads(rx_ring, rxbd, skb);
@@ -736,7 +726,6 @@ static int enetc_clean_rx_ring(struct en
if (unlikely(bd_status & ENETC_RXBD_LSTATUS(ENETC_RXBD_ERR_MASK))) { - enetc_unlock_mdio(); dev_kfree_skb(skb); while (!(bd_status & ENETC_RXBD_LSTATUS_F)) { dma_rmb(); @@ -776,8 +765,6 @@ static int enetc_clean_rx_ring(struct en
enetc_process_skb(rx_ring, skb);
- enetc_unlock_mdio(); - napi_gro_receive(napi, skb);
rx_frm_cnt++; --- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h +++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h @@ -453,6 +453,8 @@ static inline u64 _enetc_rd_reg64_wa(voi #define enetc_wr_reg(reg, val) _enetc_wr_reg_wa((reg), (val)) #define enetc_rd(hw, off) enetc_rd_reg((hw)->reg + (off)) #define enetc_wr(hw, off, val) enetc_wr_reg((hw)->reg + (off), val) +#define enetc_rd_hot(hw, off) enetc_rd_reg_hot((hw)->reg + (off)) +#define enetc_wr_hot(hw, off, val) enetc_wr_reg_hot((hw)->reg + (off), val) #define enetc_rd64(hw, off) _enetc_rd_reg64_wa((hw)->reg + (off)) /* port register accessors - PF only */ #define enetc_port_rd(hw, off) enetc_rd_reg((hw)->port + (off))
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Vladimir Oltean vladimir.oltean@nxp.com
commit 827b6fd046516af605e190c872949f22208b5d41 upstream.
When the enetc ports have rx-vlan-offload enabled, they report a TPID of ETH_P_8021Q regardless of what was actually in the packet. When rx-vlan-offload is disabled, packets have the proper TPID. Fix this inconsistency by finishing the TODO left in the code.
Fixes: d4fd0404c1c9 ("enetc: Introduce basic PF and VF ENETC ethernet drivers") Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/freescale/enetc/enetc.c | 34 ++++++++++++++++++------ drivers/net/ethernet/freescale/enetc/enetc_hw.h | 3 ++ 2 files changed, 29 insertions(+), 8 deletions(-)
--- a/drivers/net/ethernet/freescale/enetc/enetc.c +++ b/drivers/net/ethernet/freescale/enetc/enetc.c @@ -563,9 +563,8 @@ static void enetc_get_rx_tstamp(struct n static void enetc_get_offloads(struct enetc_bdr *rx_ring, union enetc_rx_bd *rxbd, struct sk_buff *skb) { -#ifdef CONFIG_FSL_ENETC_PTP_CLOCK struct enetc_ndev_priv *priv = netdev_priv(rx_ring->ndev); -#endif + /* TODO: hashing */ if (rx_ring->ndev->features & NETIF_F_RXCSUM) { u16 inet_csum = le16_to_cpu(rxbd->r.inet_csum); @@ -574,12 +573,31 @@ static void enetc_get_offloads(struct en skb->ip_summed = CHECKSUM_COMPLETE; }
- /* copy VLAN to skb, if one is extracted, for now we assume it's a - * standard TPID, but HW also supports custom values - */ - if (le16_to_cpu(rxbd->r.flags) & ENETC_RXBD_FLAG_VLAN) - __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), - le16_to_cpu(rxbd->r.vlan_opt)); + if (le16_to_cpu(rxbd->r.flags) & ENETC_RXBD_FLAG_VLAN) { + __be16 tpid = 0; + + switch (le16_to_cpu(rxbd->r.flags) & ENETC_RXBD_FLAG_TPID) { + case 0: + tpid = htons(ETH_P_8021Q); + break; + case 1: + tpid = htons(ETH_P_8021AD); + break; + case 2: + tpid = htons(enetc_port_rd(&priv->si->hw, + ENETC_PCVLANR1)); + break; + case 3: + tpid = htons(enetc_port_rd(&priv->si->hw, + ENETC_PCVLANR2)); + break; + default: + break; + } + + __vlan_hwaccel_put_tag(skb, tpid, le16_to_cpu(rxbd->r.vlan_opt)); + } + #ifdef CONFIG_FSL_ENETC_PTP_CLOCK if (priv->active_offloads & ENETC_F_RX_TSTAMP) enetc_get_rx_tstamp(rx_ring->ndev, rxbd, skb); --- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h +++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h @@ -172,6 +172,8 @@ enum enetc_bdr_type {TX, RX}; #define ENETC_PSIPMAR0(n) (0x0100 + (n) * 0x8) /* n = SI index */ #define ENETC_PSIPMAR1(n) (0x0104 + (n) * 0x8) #define ENETC_PVCLCTR 0x0208 +#define ENETC_PCVLANR1 0x0210 +#define ENETC_PCVLANR2 0x0214 #define ENETC_VLAN_TYPE_C BIT(0) #define ENETC_VLAN_TYPE_S BIT(1) #define ENETC_PVCLCTR_OVTPIDL(bmp) ((bmp) & 0xff) /* VLAN_TYPE */ @@ -575,6 +577,7 @@ union enetc_rx_bd { #define ENETC_RXBD_LSTATUS(flags) ((flags) << 16) #define ENETC_RXBD_FLAG_VLAN BIT(9) #define ENETC_RXBD_FLAG_TSTMP BIT(10) +#define ENETC_RXBD_FLAG_TPID GENMASK(1, 0)
#define ENETC_MAC_ADDR_FILT_CNT 8 /* # of supported entries per port */ #define EMETC_MAC_ADDR_FILT_RES 3 /* # of reserved entries at the beginning */
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Vladimir Oltean vladimir.oltean@nxp.com
commit a74dbce9d4541888fe0d39afe69a3a95004669b4 upstream.
Quoting from the blamed commit:
In promiscuous mode, it is more intuitive that all traffic is received, including VLAN tagged traffic. It appears that it is necessary to set the flag in PSIPVMR for that to be the case, so VLAN promiscuous mode is also temporarily enabled. On exit from promiscuous mode, the setting made by ethtool is restored.
Intuitive or not, there isn't any definition issued by a standards body which says that promiscuity has anything to do with VLAN filtering - it only has to do with accepting packets regardless of destination MAC address.
In fact people are already trying to use this misunderstanding/bug of the enetc driver as a justification to transform promiscuity into something it never was about: accepting every packet (maybe that would be the "rx-all" netdev feature?): https://lore.kernel.org/netdev/20201110153958.ci5ekor3o2ekg3ky@ipetronik.com...
This is relevant because there are use cases in the kernel (such as tc-flower rules with the protocol 802.1Q and a vlan_id key) which do not (yet) use the vlan_vid_add API to be compatible with VLAN-filtering NICs such as enetc, so for those, disabling rx-vlan-filter is currently the only right solution to make these setups work: https://lore.kernel.org/netdev/CA+h21hoxwRdhq4y+w8Kwgm74d4cA0xLeiHTrmT-VpSaM... The blamed patch has unintentionally introduced one more way for this to work, which is to enable IFF_PROMISC, however this is non-portable because port promiscuity is not meant to disable VLAN filtering. Therefore, it could invite people to write broken scripts for enetc, and then wonder why they are broken when migrating to other drivers that don't handle promiscuity in the same way.
Fixes: 7070eea5e95a ("enetc: permit configuration of rx-vlan-filter with ethtool") Cc: Markus Blöchl Markus.Bloechl@ipetronik.com Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/freescale/enetc/enetc_pf.c | 5 ----- 1 file changed, 5 deletions(-)
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c +++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c @@ -190,7 +190,6 @@ static void enetc_pf_set_rx_mode(struct { struct enetc_ndev_priv *priv = netdev_priv(ndev); struct enetc_pf *pf = enetc_si_priv(priv->si); - char vlan_promisc_simap = pf->vlan_promisc_simap; struct enetc_hw *hw = &priv->si->hw; bool uprom = false, mprom = false; struct enetc_mac_filter *filter; @@ -203,16 +202,12 @@ static void enetc_pf_set_rx_mode(struct psipmr = ENETC_PSIPMR_SET_UP(0) | ENETC_PSIPMR_SET_MP(0); uprom = true; mprom = true; - /* Enable VLAN promiscuous mode for SI0 (PF) */ - vlan_promisc_simap |= BIT(0); } else if (ndev->flags & IFF_ALLMULTI) { /* enable multi cast promisc mode for SI0 (PF) */ psipmr = ENETC_PSIPMR_SET_MP(0); mprom = true; }
- enetc_set_vlan_promisc(&pf->si->hw, vlan_promisc_simap); - /* first 2 filter entries belong to PF */ if (!uprom) { /* Update unicast filters */
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Vladimir Oltean vladimir.oltean@nxp.com
commit c76a97218dcbb2cb7cec1404ace43ef96c87d874 upstream.
The ENETC port 0 MAC supports in-band status signaling coming from a PHY when operating in RGMII mode, and this feature is enabled by default.
It has been reported that RGMII is broken in fixed-link, and that is not surprising considering the fact that no PHY is attached to the MAC in that case, but a switch.
This brings us to the topic of the patch: the enetc driver should have not enabled the optional in-band status signaling for RGMII unconditionally, but should have forced the speed and duplex to what was resolved by phylink.
Note that phylink does not accept the RGMII modes as valid for in-band signaling, and these operate a bit differently than 1000base-x and SGMII (notably there is no clause 37 state machine so no ACK required from the MAC, instead the PHY sends extra code words on RXD[3:0] whenever it is not transmitting something else, so it should be safe to leave a PHY with this option unconditionally enabled even if we ignore it). The spec talks about this here: https://e2e.ti.com/cfs-file/__key/communityserver-discussions-components-fil...
Fixes: 71b77a7a27a3 ("enetc: Migrate to PHYLINK and PCS_LYNX") Cc: Florian Fainelli f.fainelli@gmail.com Cc: Andrew Lunn andrew@lunn.ch Cc: Russell King rmk+kernel@armlinux.org.uk Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Acked-by: Russell King rmk+kernel@armlinux.org.uk Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/freescale/enetc/enetc_hw.h | 13 ++++- drivers/net/ethernet/freescale/enetc/enetc_pf.c | 53 ++++++++++++++++++++---- 2 files changed, 56 insertions(+), 10 deletions(-)
--- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h +++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h @@ -238,10 +238,17 @@ enum enetc_bdr_type {TX, RX}; #define ENETC_PM_IMDIO_BASE 0x8030
#define ENETC_PM0_IF_MODE 0x8300 -#define ENETC_PMO_IFM_RG BIT(2) +#define ENETC_PM0_IFM_RG BIT(2) #define ENETC_PM0_IFM_RLP (BIT(5) | BIT(11)) -#define ENETC_PM0_IFM_RGAUTO (BIT(15) | ENETC_PMO_IFM_RG | BIT(1)) -#define ENETC_PM0_IFM_XGMII BIT(12) +#define ENETC_PM0_IFM_EN_AUTO BIT(15) +#define ENETC_PM0_IFM_SSP_MASK GENMASK(14, 13) +#define ENETC_PM0_IFM_SSP_1000 (2 << 13) +#define ENETC_PM0_IFM_SSP_100 (0 << 13) +#define ENETC_PM0_IFM_SSP_10 (1 << 13) +#define ENETC_PM0_IFM_FULL_DPX BIT(12) +#define ENETC_PM0_IFM_IFMODE_MASK GENMASK(1, 0) +#define ENETC_PM0_IFM_IFMODE_XGMII 0 +#define ENETC_PM0_IFM_IFMODE_GMII 2 #define ENETC_PSIDCAPR 0x1b08 #define ENETC_PSIDCAPR_MSK GENMASK(15, 0) #define ENETC_PSFCAPR 0x1b18 --- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c +++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c @@ -315,7 +315,7 @@ static void enetc_set_loopback(struct ne u32 reg;
reg = enetc_port_rd(hw, ENETC_PM0_IF_MODE); - if (reg & ENETC_PMO_IFM_RG) { + if (reg & ENETC_PM0_IFM_RG) { /* RGMII mode */ reg = (reg & ~ENETC_PM0_IFM_RLP) | (en ? ENETC_PM0_IFM_RLP : 0); @@ -494,13 +494,20 @@ static void enetc_configure_port_mac(str
static void enetc_mac_config(struct enetc_hw *hw, phy_interface_t phy_mode) { - /* set auto-speed for RGMII */ - if (enetc_port_rd(hw, ENETC_PM0_IF_MODE) & ENETC_PMO_IFM_RG || - phy_interface_mode_is_rgmii(phy_mode)) - enetc_port_wr(hw, ENETC_PM0_IF_MODE, ENETC_PM0_IFM_RGAUTO); + u32 val; + + if (phy_interface_mode_is_rgmii(phy_mode)) { + val = enetc_port_rd(hw, ENETC_PM0_IF_MODE); + val &= ~ENETC_PM0_IFM_EN_AUTO; + val &= ENETC_PM0_IFM_IFMODE_MASK; + val |= ENETC_PM0_IFM_IFMODE_GMII | ENETC_PM0_IFM_RG; + enetc_port_wr(hw, ENETC_PM0_IF_MODE, val); + }
- if (phy_mode == PHY_INTERFACE_MODE_USXGMII) - enetc_port_wr(hw, ENETC_PM0_IF_MODE, ENETC_PM0_IFM_XGMII); + if (phy_mode == PHY_INTERFACE_MODE_USXGMII) { + val = ENETC_PM0_IFM_FULL_DPX | ENETC_PM0_IFM_IFMODE_XGMII; + enetc_port_wr(hw, ENETC_PM0_IF_MODE, val); + } }
static void enetc_mac_enable(struct enetc_hw *hw, bool en) @@ -939,6 +946,34 @@ static void enetc_pl_mac_config(struct p phylink_set_pcs(priv->phylink, &pf->pcs->pcs); }
+static void enetc_force_rgmii_mac(struct enetc_hw *hw, int speed, int duplex) +{ + u32 old_val, val; + + old_val = val = enetc_port_rd(hw, ENETC_PM0_IF_MODE); + + if (speed == SPEED_1000) { + val &= ~ENETC_PM0_IFM_SSP_MASK; + val |= ENETC_PM0_IFM_SSP_1000; + } else if (speed == SPEED_100) { + val &= ~ENETC_PM0_IFM_SSP_MASK; + val |= ENETC_PM0_IFM_SSP_100; + } else if (speed == SPEED_10) { + val &= ~ENETC_PM0_IFM_SSP_MASK; + val |= ENETC_PM0_IFM_SSP_10; + } + + if (duplex == DUPLEX_FULL) + val |= ENETC_PM0_IFM_FULL_DPX; + else + val &= ~ENETC_PM0_IFM_FULL_DPX; + + if (val == old_val) + return; + + enetc_port_wr(hw, ENETC_PM0_IF_MODE, val); +} + static void enetc_pl_mac_link_up(struct phylink_config *config, struct phy_device *phy, unsigned int mode, phy_interface_t interface, int speed, @@ -951,6 +986,10 @@ static void enetc_pl_mac_link_up(struct if (priv->active_offloads & ENETC_F_QBV) enetc_sched_speed_set(priv, speed);
+ if (!phylink_autoneg_inband(mode) && + phy_interface_mode_is_rgmii(interface)) + enetc_force_rgmii_mac(&pf->si->hw, speed, duplex); + enetc_mac_enable(&pf->si->hw, true); }
Hi!
It has been reported that RGMII is broken in fixed-link, and that is not surprising considering the fact that no PHY is attached to the MAC in that case, but a switch.
Okay, but there's something wrong in the code.
This brings us to the topic of the patch: the enetc driver should have not enabled the optional in-band status signaling for RGMII unconditionally, but should have forced the speed and duplex to what was resolved by phylink.
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c @@ -494,13 +494,20 @@ static void enetc_configure_port_mac(str static void enetc_mac_config(struct enetc_hw *hw, phy_interface_t phy_mode) {
...
- u32 val;
- if (phy_interface_mode_is_rgmii(phy_mode)) {
val = enetc_port_rd(hw, ENETC_PM0_IF_MODE);
val &= ~ENETC_PM0_IFM_EN_AUTO;
val &= ENETC_PM0_IFM_IFMODE_MASK;
val |= ENETC_PM0_IFM_IFMODE_GMII | ENETC_PM0_IFM_RG;
enetc_port_wr(hw, ENETC_PM0_IF_MODE, val);
- }
val clears ENETC_PM0_IFM_EN_AUTO bit, then the bit is cleared again, preserving just IFMODE bits, then ors the IFMODE bits with new values.
I believe this is needed:
Signed-off-by: Pavel Machek (CIP) pavel@denx.de Pavel
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c b/drivers/net/ethernet/freescale/enetc/enetc_pf.c index 83187cd59fdd..446ad4c43fab 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c +++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c @@ -499,7 +499,7 @@ static void enetc_mac_config(struct enetc_hw *hw, phy_interface_t phy_mode) if (phy_interface_mode_is_rgmii(phy_mode)) { val = enetc_port_rd(hw, ENETC_PM0_IF_MODE); val &= ~ENETC_PM0_IFM_EN_AUTO; - val &= ENETC_PM0_IFM_IFMODE_MASK; + val &= ~ENETC_PM0_IFM_IFMODE_MASK; val |= ENETC_PM0_IFM_IFMODE_GMII | ENETC_PM0_IFM_RG; enetc_port_wr(hw, ENETC_PM0_IF_MODE, val); }
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Vladimir Oltean vladimir.oltean@nxp.com
commit 96a5223b918c8b79270fc0fec235a7ebad459098 upstream.
The Station Interface Receive Interrupt Detect Register (SIRXIDR) contains a 16-bit wide mask of 'interrupt detected' events for each ring associated with a port. Bit i is write-1-to-clean for RX ring i.
I have no explanation whatsoever how this line of code came to be inserted in the blamed commit. I checked the downstream versions of that patch and none of them have it.
The somewhat comical aspect of it is that we're writing a binary number to the SIRXIDR register, which is derived from enetc_bd_unused(rx_ring). Since the RX rings have 512 buffer descriptors, we end up writing 511 to this register, which is 0x1ff, so we are effectively clearing the 'interrupt detected' event for rings 0-8.
This register is not what is used for interrupt handling though - it only provides a summary for the entire SI. The hardware provides one separate Interrupt Detect Register per RX ring, which auto-clears upon read. So there doesn't seem to be any adverse effect caused by this bogus write.
There is, however, one reason why this should be handled as a bugfix: next_to_clean _should_ be committed to hardware, just not to that register, and this was obscuring the fact that it wasn't. This is fixed in the next patch, and removing the bogus line now allows the fix patch to be backported beyond that point.
Fixes: fd5736bf9f23 ("enetc: Workaround for MDIO register access issue") Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/freescale/enetc/enetc.c | 1 - 1 file changed, 1 deletion(-)
--- a/drivers/net/ethernet/freescale/enetc/enetc.c +++ b/drivers/net/ethernet/freescale/enetc/enetc.c @@ -1252,7 +1252,6 @@ static void enetc_setup_rxbdr(struct ene rx_ring->idr = hw->reg + ENETC_SIRXIDR;
enetc_refill_rx_ring(rx_ring, enetc_bd_unused(rx_ring)); - enetc_wr(hw, ENETC_SIRXIDR, rx_ring->next_to_use);
/* enable ring */ enetc_rxbdr_wr(hw, idx, ENETC_RBMR, rbmr);
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Vladimir Oltean vladimir.oltean@nxp.com
commit 3a5d12c9be6f30080600c8bacaf310194e37d029 upstream.
The RX rings have a producer index owned by hardware, where newly received frame buffers are placed, and a consumer index owned by software, where newly allocated buffers are placed, in expectation of hardware being able to place frame data in them.
Hardware increments the producer index when a frame is received, however it is not allowed to increment the producer index to match the consumer index (RBCIR) since the ring can hold at most RBLENR[LENGTH]-1 received BDs. Whenever the producer index matches the value of the consumer index, the ring has no unprocessed received frames and all BDs in the ring have been initialized/prepared by software, i.e. hardware owns all BDs in the ring.
The code uses the next_to_clean variable to keep track of the producer index, and the next_to_use variable to keep track of the consumer index.
The RX rings are seeded from enetc_refill_rx_ring, which is called from two places:
1. initially the ring is seeded until full with enetc_bd_unused(rx_ring), i.e. with 511 buffers. This will make next_to_clean=0 and next_to_use=511:
.ndo_open -> enetc_open -> enetc_setup_bdrs -> enetc_setup_rxbdr -> enetc_refill_rx_ring
2. then during the data path processing, it is refilled with 16 buffers at a time:
enetc_msix -> napi_schedule -> enetc_poll -> enetc_clean_rx_ring -> enetc_refill_rx_ring
There is just one problem: the initial seeding done during .ndo_open updates just the producer index (ENETC_RBPIR) with 0, and the software next_to_clean and next_to_use variables. Notably, it will not update the consumer index to make the hardware aware of the newly added buffers.
Wait, what? So how does it work?
Well, the reset values of the producer index and of the consumer index of a ring are both zero. As per the description in the second paragraph, it means that the ring is full of buffers waiting for hardware to put frames in them, which by coincidence is almost true, because we have in fact seeded 511 buffers into the ring.
But will the hardware attempt to access the 512th entry of the ring, which has an invalid BD in it? Well, no, because in order to do that, it would have to first populate the first 511 entries, and the NAPI enetc_poll will kick in by then. Eventually, after 16 processed slots have become available in the RX ring, enetc_clean_rx_ring will call enetc_refill_rx_ring and then will [ finally ] update the consumer index with the new software next_to_use variable. From now on, the next_to_clean and next_to_use variables are in sync with the producer and consumer ring indices.
So the day is saved, right? Well, not quite. Freeing the memory allocated for the rings is done in:
enetc_close -> enetc_clear_bdrs -> enetc_clear_rxbdr -> this just disables the ring -> enetc_free_rxtx_rings -> enetc_free_rx_ring -> sets next_to_clean and next_to_use to 0
but again, nothing is committed to the hardware producer and consumer indices (yay!). The assumption is that the ring is disabled, so the indices don't matter anyway, and it's the responsibility of the "open" code path to set those up.
.. Except that the "open" code path does not set those up properly.
While initially, things almost work, during subsequent enetc_close -> enetc_open sequences, we have problems. To be precise, the enetc_open that is subsequent to enetc_close will again refill the ring with 511 entries, but it will leave the consumer index untouched. Untouched means, of course, equal to the value it had before disabling the ring and draining the old buffers in enetc_close.
But as mentioned, enetc_setup_rxbdr will at least update the producer index though, through this line of code:
enetc_rxbdr_wr(hw, idx, ENETC_RBPIR, 0);
so at this stage we'll have:
next_to_clean=0 (in hardware 0) next_to_use=511 (in hardware we'll have the refill index prior to enetc_close)
Again, the next_to_clean and producer index are in sync and set to correct values, so the driver manages to limp on. Eventually, 16 ring entries will be consumed by enetc_poll, and the savior enetc_clean_rx_ring will come and call enetc_refill_rx_ring, and then update the hardware consumer ring based upon the new next_to_use.
So.. it works? Well, by coincidence, it almost does, but there's a circumstance where enetc_clean_rx_ring won't be there to save us. If the previous value of the consumer index was 15, there's a problem, because the NAPI poll sequence will only issue a refill when 16 or more buffers have been consumed.
It's easiest to illustrate this with an example:
ip link set eno0 up ip addr add 192.168.100.1/24 dev eno0 ping 192.168.100.1 -c 20 # ping this port from another board ip link set eno0 down ip link set eno0 up ping 192.168.100.1 -c 20 # ping it again from the same other board
One by one:
1. ip link set eno0 up -> calls enetc_setup_rxbdr: -> calls enetc_refill_rx_ring(511 buffers) -> next_to_clean=0 (in hw 0) -> next_to_use=511 (in hw 0)
2. ping 192.168.100.1 -c 20 # ping this port from another board enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=1 next_to_clean 0 (in hw 1) next_to_use 511 (in hw 0) enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=2 next_to_clean 1 (in hw 2) next_to_use 511 (in hw 0) enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=3 next_to_clean 2 (in hw 3) next_to_use 511 (in hw 0) enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=4 next_to_clean 3 (in hw 4) next_to_use 511 (in hw 0) enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=5 next_to_clean 4 (in hw 5) next_to_use 511 (in hw 0) enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=6 next_to_clean 5 (in hw 6) next_to_use 511 (in hw 0) enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=7 next_to_clean 6 (in hw 7) next_to_use 511 (in hw 0) enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=8 next_to_clean 7 (in hw 8) next_to_use 511 (in hw 0) enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=9 next_to_clean 8 (in hw 9) next_to_use 511 (in hw 0) enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=10 next_to_clean 9 (in hw 10) next_to_use 511 (in hw 0) enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=11 next_to_clean 10 (in hw 11) next_to_use 511 (in hw 0) enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=12 next_to_clean 11 (in hw 12) next_to_use 511 (in hw 0) enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=13 next_to_clean 12 (in hw 13) next_to_use 511 (in hw 0) enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=14 next_to_clean 13 (in hw 14) next_to_use 511 (in hw 0) enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=15 next_to_clean 14 (in hw 15) next_to_use 511 (in hw 0) enetc_clean_rx_ring: enetc_refill_rx_ring(16) increments next_to_use by 16 (mod 512) and writes it to hw enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=0 next_to_clean 15 (in hw 16) next_to_use 15 (in hw 15) enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=1 next_to_clean 16 (in hw 17) next_to_use 15 (in hw 15) enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=2 next_to_clean 17 (in hw 18) next_to_use 15 (in hw 15) enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=3 next_to_clean 18 (in hw 19) next_to_use 15 (in hw 15) enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=4 next_to_clean 19 (in hw 20) next_to_use 15 (in hw 15) enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=5 next_to_clean 20 (in hw 21) next_to_use 15 (in hw 15) enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=6 next_to_clean 21 (in hw 22) next_to_use 15 (in hw 15)
20 packets transmitted, 20 packets received, 0% packet loss
3. ip link set eno0 down enetc_free_rx_ring: next_to_clean 0 (in hw 22), next_to_use 0 (in hw 15)
4. ip link set eno0 up -> calls enetc_setup_rxbdr: -> calls enetc_refill_rx_ring(511 buffers) -> next_to_clean=0 (in hw 0) -> next_to_use=511 (in hw 15)
5. ping 192.168.100.1 -c 20 # ping it again from the same other board enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=1 next_to_clean 0 (in hw 1) next_to_use 511 (in hw 15) enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=2 next_to_clean 1 (in hw 2) next_to_use 511 (in hw 15) enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=3 next_to_clean 2 (in hw 3) next_to_use 511 (in hw 15) enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=4 next_to_clean 3 (in hw 4) next_to_use 511 (in hw 15) enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=5 next_to_clean 4 (in hw 5) next_to_use 511 (in hw 15) enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=6 next_to_clean 5 (in hw 6) next_to_use 511 (in hw 15) enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=7 next_to_clean 6 (in hw 7) next_to_use 511 (in hw 15) enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=8 next_to_clean 7 (in hw 8) next_to_use 511 (in hw 15) enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=9 next_to_clean 8 (in hw 9) next_to_use 511 (in hw 15) enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=10 next_to_clean 9 (in hw 10) next_to_use 511 (in hw 15) enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=11 next_to_clean 10 (in hw 11) next_to_use 511 (in hw 15) enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=12 next_to_clean 11 (in hw 12) next_to_use 511 (in hw 15) enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=13 next_to_clean 12 (in hw 13) next_to_use 511 (in hw 15) enetc_clean_rx_ring: rx_frm_cnt=1 cleaned_cnt=14 next_to_clean 13 (in hw 14) next_to_use 511 (in hw 15)
20 packets transmitted, 12 packets received, 40% packet loss
And there it dies. No enetc_refill_rx_ring (because cleaned_cnt must be equal to 15 for that to happen), no nothing. The hardware enters the condition where the producer (14) + 1 is equal to the consumer (15) index, which makes it believe it has no more free buffers to put packets in, so it starts discarding them:
ip netns exec ns0 ethtool -S eno0 | grep -v ': 0' NIC statistics: Rx ring 0 discarded frames: 8
Summarized, if the interface receives between 16 and 32 (mod 512) frames and then there is a link flap, then the port will eventually die with no way to recover. If it receives less than 16 (mod 512) frames, then the initial NAPI poll [ before the link flap ] will not update the consumer index in hardware (it will remain zero) which will be ok when the buffers are later reinitialized. If more than 32 (mod 512) frames are received, the initial NAPI poll has the chance to refill the ring twice, updating the consumer index to at least 32. So after the link flap, the consumer index is still wrong, but the post-flap NAPI poll gets a chance to refill the ring once (because it passes through cleaned_cnt=15) and makes the consumer index be again back in sync with next_to_use.
The solution to this problem is actually simple, we just need to write next_to_use into the hardware consumer index at enetc_open time, which always brings it back in sync after an initial buffer seeding process.
The simpler thing would be to put the write to the consumer index into enetc_refill_rx_ring directly, but there are issues with the MDIO locking: in the NAPI poll code we have the enetc_lock_mdio() taken from top-level and we use the unlocked enetc_wr_reg_hot, whereas in enetc_open, the enetc_lock_mdio() is not taken at the top level, but instead by each individual enetc_wr_reg, so we are forced to put an additional enetc_wr_reg in enetc_setup_rxbdr. Better organization of the code is left as a refactoring exercise.
Fixes: d4fd0404c1c9 ("enetc: Introduce basic PF and VF ENETC ethernet drivers") Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/freescale/enetc/enetc.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/drivers/net/ethernet/freescale/enetc/enetc.c +++ b/drivers/net/ethernet/freescale/enetc/enetc.c @@ -1252,6 +1252,8 @@ static void enetc_setup_rxbdr(struct ene rx_ring->idr = hw->reg + ENETC_SIRXIDR;
enetc_refill_rx_ring(rx_ring, enetc_bd_unused(rx_ring)); + /* update ENETC's consumer index */ + enetc_rxbdr_wr(hw, idx, ENETC_RBCIR, rx_ring->next_to_use);
/* enable ring */ enetc_rxbdr_wr(hw, idx, ENETC_RBMR, rbmr);
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Biao Huang biao.huang@mediatek.com
commit 95b39f07a17faef3a9b225248ba449b976e529c8 upstream.
mtk_star_dma_unmap_rx() should unmap the dma_addr of old skb rather than that of new skb. Assign new_dma_addr to desc_data.dma_addr after all handling of old skb ends to avoid unexpected receive side error.
Fixes: f96e9641e92b ("net: ethernet: mtk-star-emac: fix error path in RX handling") Signed-off-by: Biao Huang biao.huang@mediatek.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/mediatek/mtk_star_emac.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
--- a/drivers/net/ethernet/mediatek/mtk_star_emac.c +++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c @@ -1225,8 +1225,6 @@ static int mtk_star_receive_packet(struc goto push_new_skb; }
- desc_data.dma_addr = new_dma_addr; - /* We can't fail anymore at this point: it's safe to unmap the skb. */ mtk_star_dma_unmap_rx(priv, &desc_data);
@@ -1236,6 +1234,9 @@ static int mtk_star_receive_packet(struc desc_data.skb->dev = ndev; netif_receive_skb(desc_data.skb);
+ /* update dma_addr for new skb */ + desc_data.dma_addr = new_dma_addr; + push_new_skb: desc_data.len = skb_tailroom(new_skb); desc_data.skb = new_skb;
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Kevin(Yudong) Yang yyd@google.com
commit 00ff801bb8ce6711e919af4530b6ffa14a22390a upstream.
This patch fixes a bug that the moderation config will not be applied when calling mlx4_en_reset_config. For example, when turning on rx timestamping, mlx4_en_reset_config() will be called, causing the NIC to forget previous moderation config.
This fix is in phase with a previous fix: commit 79c54b6bbf06 ("net/mlx4_en: Fix TX moderation info loss after set_ringparam is called")
Tested: Before this patch, on a host with NIC using mlx4, run netserver and stream TCP to the host at full utilization. $ sar -I SUM 1 INTR intr/s 14:03:56 sum 48758.00
After rx hwtstamp is enabled: $ sar -I SUM 1 14:10:38 sum 317771.00 We see the moderation is not working properly and issued 7x more interrupts.
After the patch, and turned on rx hwtstamp, the rate of interrupts is as expected: $ sar -I SUM 1 14:52:11 sum 49332.00
Fixes: 79c54b6bbf06 ("net/mlx4_en: Fix TX moderation info loss after set_ringparam is called") Signed-off-by: Kevin(Yudong) Yang yyd@google.com Reviewed-by: Eric Dumazet edumazet@google.com Reviewed-by: Neal Cardwell ncardwell@google.com CC: Tariq Toukan tariqt@nvidia.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 2 +- drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 2 ++ drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 1 + 3 files changed, 4 insertions(+), 1 deletion(-)
--- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c @@ -47,7 +47,7 @@ #define EN_ETHTOOL_SHORT_MASK cpu_to_be16(0xffff) #define EN_ETHTOOL_WORD_MASK cpu_to_be32(0xffffffff)
-static int mlx4_en_moderation_update(struct mlx4_en_priv *priv) +int mlx4_en_moderation_update(struct mlx4_en_priv *priv) { int i, t; int err = 0; --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -3559,6 +3559,8 @@ int mlx4_en_reset_config(struct net_devi en_err(priv, "Failed starting port\n"); }
+ if (!err) + err = mlx4_en_moderation_update(priv); out: mutex_unlock(&mdev->state_lock); kfree(tmp); --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h @@ -795,6 +795,7 @@ void mlx4_en_ptp_overflow_check(struct m #define DEV_FEATURE_CHANGED(dev, new_features, feature) \ ((dev->features & feature) ^ (new_features & feature))
+int mlx4_en_moderation_update(struct mlx4_en_priv *priv); int mlx4_en_reset_config(struct net_device *dev, struct hwtstamp_config ts_config, netdev_features_t new_features);
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Ong Boon Leong boon.leong.ong@intel.com
commit 879c348c35bb5fb758dd881d8a97409c1862dae8 upstream.
We introduce dwmac410_dma_init_channel() here for both EQoS v4.10 and above which use different DMA_CH(n)_Interrupt_Enable bit definitions for NIE and AIE.
Fixes: 48863ce5940f ("stmmac: add DMA support for GMAC 4.xx") Signed-off-by: Ong Boon Leong boon.leong.ong@intel.com Signed-off-by: Ramesh Babu B ramesh.babu.b@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/dwmac4_dma.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-)
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c @@ -124,6 +124,23 @@ static void dwmac4_dma_init_channel(void ioaddr + DMA_CHAN_INTR_ENA(chan)); }
+static void dwmac410_dma_init_channel(void __iomem *ioaddr, + struct stmmac_dma_cfg *dma_cfg, u32 chan) +{ + u32 value; + + /* common channel control register config */ + value = readl(ioaddr + DMA_CHAN_CONTROL(chan)); + if (dma_cfg->pblx8) + value = value | DMA_BUS_MODE_PBL; + + writel(value, ioaddr + DMA_CHAN_CONTROL(chan)); + + /* Mask interrupts by writing to CSR7 */ + writel(DMA_CHAN_INTR_DEFAULT_MASK_4_10, + ioaddr + DMA_CHAN_INTR_ENA(chan)); +} + static void dwmac4_dma_init(void __iomem *ioaddr, struct stmmac_dma_cfg *dma_cfg, int atds) { @@ -523,7 +540,7 @@ const struct stmmac_dma_ops dwmac4_dma_o const struct stmmac_dma_ops dwmac410_dma_ops = { .reset = dwmac4_dma_reset, .init = dwmac4_dma_init, - .init_chan = dwmac4_dma_init_channel, + .init_chan = dwmac410_dma_init_channel, .init_rx_chan = dwmac4_dma_init_rx_chan, .init_tx_chan = dwmac4_dma_init_tx_chan, .axi = dwmac4_dma_axi,
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Ido Schimmel idosch@nvidia.com
commit 76c03bf8e2624076b88d93542d78e22d5345c88e upstream.
As far as user space is concerned, blackhole nexthops do not have a nexthop device and therefore should not be affected by the administrative or carrier state of any netdev.
However, when the loopback netdev goes down all the blackhole nexthops are flushed. This happens because internally the kernel associates blackhole nexthops with the loopback netdev.
This behavior is both confusing to those not familiar with kernel internals and also diverges from the legacy API where blackhole IPv4 routes are not flushed when the loopback netdev goes down:
# ip route add blackhole 198.51.100.0/24 # ip link set dev lo down # ip route show 198.51.100.0/24 blackhole 198.51.100.0/24
Blackhole IPv6 routes are flushed, but at least user space knows that they are associated with the loopback netdev:
# ip -6 route show 2001:db8:1::/64 blackhole 2001:db8:1::/64 dev lo metric 1024 pref medium
Fix this by only flushing blackhole nexthops when the loopback netdev is unregistered.
Fixes: ab84be7e54fc ("net: Initial nexthop code") Signed-off-by: Ido Schimmel idosch@nvidia.com Reported-by: Donald Sharp sharpd@nvidia.com Reviewed-by: David Ahern dsahern@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/ipv4/nexthop.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
--- a/net/ipv4/nexthop.c +++ b/net/ipv4/nexthop.c @@ -1182,7 +1182,7 @@ out:
/* rtnl */ /* remove all nexthops tied to a device being deleted */ -static void nexthop_flush_dev(struct net_device *dev) +static void nexthop_flush_dev(struct net_device *dev, unsigned long event) { unsigned int hash = nh_dev_hashfn(dev->ifindex); struct net *net = dev_net(dev); @@ -1194,6 +1194,10 @@ static void nexthop_flush_dev(struct net if (nhi->fib_nhc.nhc_dev != dev) continue;
+ if (nhi->reject_nh && + (event == NETDEV_DOWN || event == NETDEV_CHANGE)) + continue; + remove_nexthop(net, nhi->nh_parent, NULL); } } @@ -1940,11 +1944,11 @@ static int nh_netdev_event(struct notifi switch (event) { case NETDEV_DOWN: case NETDEV_UNREGISTER: - nexthop_flush_dev(dev); + nexthop_flush_dev(dev, event); break; case NETDEV_CHANGE: if (!(dev_get_flags(dev) & (IFF_RUNNING | IFF_LOWER_UP))) - nexthop_flush_dev(dev); + nexthop_flush_dev(dev, event); break; case NETDEV_CHANGEMTU: info_ext = ptr;
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Maximilian Heyne mheyne@amazon.de
commit bfc2560563586372212b0a8aeca7428975fa91fe upstream.
This is a follow up of commit ea3274695353 ("net: sched: avoid duplicates in qdisc dump") which has fixed the issue only for the qdisc dump.
The duplicate printing also occurs when dumping the classes via tc class show dev eth0
Fixes: 59cc1f61f09c ("net: sched: convert qdisc linked list to hashtable") Signed-off-by: Maximilian Heyne mheyne@amazon.de Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/sched/sch_api.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
--- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -2167,7 +2167,7 @@ static int tc_dump_tclass_qdisc(struct Q
static int tc_dump_tclass_root(struct Qdisc *root, struct sk_buff *skb, struct tcmsg *tcm, struct netlink_callback *cb, - int *t_p, int s_t) + int *t_p, int s_t, bool recur) { struct Qdisc *q; int b; @@ -2178,7 +2178,7 @@ static int tc_dump_tclass_root(struct Qd if (tc_dump_tclass_qdisc(root, skb, tcm, cb, t_p, s_t) < 0) return -1;
- if (!qdisc_dev(root)) + if (!qdisc_dev(root) || !recur) return 0;
if (tcm->tcm_parent) { @@ -2213,13 +2213,13 @@ static int tc_dump_tclass(struct sk_buff s_t = cb->args[0]; t = 0;
- if (tc_dump_tclass_root(dev->qdisc, skb, tcm, cb, &t, s_t) < 0) + if (tc_dump_tclass_root(dev->qdisc, skb, tcm, cb, &t, s_t, true) < 0) goto done;
dev_queue = dev_ingress_queue(dev); if (dev_queue && tc_dump_tclass_root(dev_queue->qdisc_sleeping, skb, tcm, cb, - &t, s_t) < 0) + &t, s_t, false) < 0) goto done;
done:
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Vladimir Oltean vladimir.oltean@nxp.com
commit f1becbed411c6fa29d7ce3def3a1dcd4f63f2d74 upstream.
An attempt is made to warn the user about the fact that VCAP IS1 cannot offload keys matching on destination IP (at least given the current half key format), but sadly that warning fails miserably in practice, due to the fact that it operates on an uninitialized "match" variable. We must first decode the keys from the flow rule.
Fixes: 75944fda1dfe ("net: mscc: ocelot: offload ingress skbedit and vlan actions to VCAP IS1") Reported-by: Colin Ian King colin.king@canonical.com Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Reviewed-by: Colin Ian King colin.king@canonical.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/mscc/ocelot_flower.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/net/ethernet/mscc/ocelot_flower.c +++ b/drivers/net/ethernet/mscc/ocelot_flower.c @@ -540,13 +540,14 @@ ocelot_flower_parse_key(struct ocelot *o return -EOPNOTSUPP; }
+ flow_rule_match_ipv4_addrs(rule, &match); + if (filter->block_id == VCAP_IS1 && *(u32 *)&match.mask->dst) { NL_SET_ERR_MSG_MOD(extack, "Key type S1_NORMAL cannot match on destination IP"); return -EOPNOTSUPP; }
- flow_rule_match_ipv4_addrs(rule, &match); tmp = &filter->key.ipv4.sip.value.addr[0]; memcpy(tmp, &match.key->src, 4);
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Vladimir Oltean vladimir.oltean@nxp.com
commit 053d8ad10d585adf9891fcd049637536e2fe9ea7 upstream.
When using MLO_AN_PHY or MLO_AN_FIXED, the MII_BMCR of the SGMII PCS is read before resetting the switch so it can be reprogrammed afterwards. This works for the speeds of 1Gbps and 100Mbps, but not for 10Mbps, because SPEED_10 is actually 0, so AND-ing anything with 0 is false, therefore that last branch is dead code.
Do what others do (genphy_read_status_fixed, phy_mii_ioctl) and just remove the check for SPEED_10, let it fall into the default case.
Fixes: ffe10e679cec ("net: dsa: sja1105: Add support for the SGMII port") Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Reviewed-by: Andrew Lunn andrew@lunn.ch Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/dsa/sja1105/sja1105_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/dsa/sja1105/sja1105_main.c +++ b/drivers/net/dsa/sja1105/sja1105_main.c @@ -1834,7 +1834,7 @@ out_unlock_ptp: speed = SPEED_1000; else if (bmcr & BMCR_SPEED100) speed = SPEED_100; - else if (bmcr & BMCR_SPEED10) + else speed = SPEED_10;
sja1105_sgmii_pcs_force_speed(priv, speed);
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Daniele Palmas dnlplm@gmail.com
commit 6c59cff38e66584ae3ac6c2f0cbd8d039c710ba7 upstream.
There's no reason for preventing the creation and removal of qmimux network interfaces when the underlying interface is up.
This makes qmi_wwan mux implementation more similar to the rmnet one, simplifying userspace management of the same logical interfaces.
Fixes: c6adf77953bc ("net: usb: qmi_wwan: add qmap mux protocol support") Reported-by: Aleksander Morgado aleksander@aleksander.es Signed-off-by: Daniele Palmas dnlplm@gmail.com Acked-by: Bjørn Mork bjorn@mork.no Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/usb/qmi_wwan.c | 14 -------------- 1 file changed, 14 deletions(-)
--- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -419,13 +419,6 @@ static ssize_t add_mux_store(struct devi goto err; }
- /* we don't want to modify a running netdev */ - if (netif_running(dev->net)) { - netdev_err(dev->net, "Cannot change a running device\n"); - ret = -EBUSY; - goto err; - } - ret = qmimux_register_device(dev->net, mux_id); if (!ret) { info->flags |= QMI_WWAN_FLAG_MUX; @@ -455,13 +448,6 @@ static ssize_t del_mux_store(struct devi if (!rtnl_trylock()) return restart_syscall();
- /* we don't want to modify a running netdev */ - if (netif_running(dev->net)) { - netdev_err(dev->net, "Cannot change a running device\n"); - ret = -EBUSY; - goto err; - } - del_dev = qmimux_find_dev(dev, mux_id); if (!del_dev) { netdev_err(dev->net, "mux_id not present\n");
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Hillf Danton hdanton@sina.com
commit 863a42b289c22df63db62b10fc2c2ffc237e2125 upstream.
Init the u64 stats in order to avoid the lockdep prints on the 32bit hardware like
INFO: trying to register non-static key. the code is fine but needs lockdep annotation. turning off the locking correctness validator. CPU: 0 PID: 4695 Comm: syz-executor.0 Not tainted 5.11.0-rc5-syzkaller #0 Hardware name: ARM-Versatile Express Backtrace: [<826fc5b8>] (dump_backtrace) from [<826fc82c>] (show_stack+0x18/0x1c arch/arm/kernel/traps.c:252) [<826fc814>] (show_stack) from [<8270d1f8>] (__dump_stack lib/dump_stack.c:79 [inline]) [<826fc814>] (show_stack) from [<8270d1f8>] (dump_stack+0xa8/0xc8 lib/dump_stack.c:120) [<8270d150>] (dump_stack) from [<802bf9c0>] (assign_lock_key kernel/locking/lockdep.c:935 [inline]) [<8270d150>] (dump_stack) from [<802bf9c0>] (register_lock_class+0xabc/0xb68 kernel/locking/lockdep.c:1247) [<802bef04>] (register_lock_class) from [<802baa2c>] (__lock_acquire+0x84/0x32d4 kernel/locking/lockdep.c:4711) [<802ba9a8>] (__lock_acquire) from [<802be840>] (lock_acquire.part.0+0xf0/0x554 kernel/locking/lockdep.c:5442) [<802be750>] (lock_acquire.part.0) from [<802bed10>] (lock_acquire+0x6c/0x74 kernel/locking/lockdep.c:5415) [<802beca4>] (lock_acquire) from [<81560548>] (seqcount_lockdep_reader_access include/linux/seqlock.h:103 [inline]) [<802beca4>] (lock_acquire) from [<81560548>] (__u64_stats_fetch_begin include/linux/u64_stats_sync.h:164 [inline]) [<802beca4>] (lock_acquire) from [<81560548>] (u64_stats_fetch_begin include/linux/u64_stats_sync.h:175 [inline]) [<802beca4>] (lock_acquire) from [<81560548>] (nsim_get_stats64+0xdc/0xf0 drivers/net/netdevsim/netdev.c:70) [<8156046c>] (nsim_get_stats64) from [<81e2efa0>] (dev_get_stats+0x44/0xd0 net/core/dev.c:10405) [<81e2ef5c>] (dev_get_stats) from [<81e53204>] (rtnl_fill_stats+0x38/0x120 net/core/rtnetlink.c:1211) [<81e531cc>] (rtnl_fill_stats) from [<81e59d58>] (rtnl_fill_ifinfo+0x6d4/0x148c net/core/rtnetlink.c:1783) [<81e59684>] (rtnl_fill_ifinfo) from [<81e5ceb4>] (rtmsg_ifinfo_build_skb+0x9c/0x108 net/core/rtnetlink.c:3798) [<81e5ce18>] (rtmsg_ifinfo_build_skb) from [<81e5d0ac>] (rtmsg_ifinfo_event net/core/rtnetlink.c:3830 [inline]) [<81e5ce18>] (rtmsg_ifinfo_build_skb) from [<81e5d0ac>] (rtmsg_ifinfo_event net/core/rtnetlink.c:3821 [inline]) [<81e5ce18>] (rtmsg_ifinfo_build_skb) from [<81e5d0ac>] (rtmsg_ifinfo+0x44/0x70 net/core/rtnetlink.c:3839) [<81e5d068>] (rtmsg_ifinfo) from [<81e45c2c>] (register_netdevice+0x664/0x68c net/core/dev.c:10103) [<81e455c8>] (register_netdevice) from [<815608bc>] (nsim_create+0xf8/0x124 drivers/net/netdevsim/netdev.c:317) [<815607c4>] (nsim_create) from [<81561184>] (__nsim_dev_port_add+0x108/0x188 drivers/net/netdevsim/dev.c:941) [<8156107c>] (__nsim_dev_port_add) from [<815620d8>] (nsim_dev_port_add_all drivers/net/netdevsim/dev.c:990 [inline]) [<8156107c>] (__nsim_dev_port_add) from [<815620d8>] (nsim_dev_probe+0x5cc/0x750 drivers/net/netdevsim/dev.c:1119) [<81561b0c>] (nsim_dev_probe) from [<815661dc>] (nsim_bus_probe+0x10/0x14 drivers/net/netdevsim/bus.c:287) [<815661cc>] (nsim_bus_probe) from [<811724c0>] (really_probe+0x100/0x50c drivers/base/dd.c:554) [<811723c0>] (really_probe) from [<811729c4>] (driver_probe_device+0xf8/0x1c8 drivers/base/dd.c:740) [<811728cc>] (driver_probe_device) from [<81172fe4>] (__device_attach_driver+0x8c/0xf0 drivers/base/dd.c:846) [<81172f58>] (__device_attach_driver) from [<8116fee0>] (bus_for_each_drv+0x88/0xd8 drivers/base/bus.c:431) [<8116fe58>] (bus_for_each_drv) from [<81172c6c>] (__device_attach+0xdc/0x1d0 drivers/base/dd.c:914) [<81172b90>] (__device_attach) from [<8117305c>] (device_initial_probe+0x14/0x18 drivers/base/dd.c:961) [<81173048>] (device_initial_probe) from [<81171358>] (bus_probe_device+0x90/0x98 drivers/base/bus.c:491) [<811712c8>] (bus_probe_device) from [<8116e77c>] (device_add+0x320/0x824 drivers/base/core.c:3109) [<8116e45c>] (device_add) from [<8116ec9c>] (device_register+0x1c/0x20 drivers/base/core.c:3182) [<8116ec80>] (device_register) from [<81566710>] (nsim_bus_dev_new drivers/net/netdevsim/bus.c:336 [inline]) [<8116ec80>] (device_register) from [<81566710>] (new_device_store+0x178/0x208 drivers/net/netdevsim/bus.c:215) [<81566598>] (new_device_store) from [<8116fcb4>] (bus_attr_store+0x2c/0x38 drivers/base/bus.c:122) [<8116fc88>] (bus_attr_store) from [<805b4b8c>] (sysfs_kf_write+0x48/0x54 fs/sysfs/file.c:139) [<805b4b44>] (sysfs_kf_write) from [<805b3c90>] (kernfs_fop_write_iter+0x128/0x1ec fs/kernfs/file.c:296) [<805b3b68>] (kernfs_fop_write_iter) from [<804d22fc>] (call_write_iter include/linux/fs.h:1901 [inline]) [<805b3b68>] (kernfs_fop_write_iter) from [<804d22fc>] (new_sync_write fs/read_write.c:518 [inline]) [<805b3b68>] (kernfs_fop_write_iter) from [<804d22fc>] (vfs_write+0x3dc/0x57c fs/read_write.c:605) [<804d1f20>] (vfs_write) from [<804d2604>] (ksys_write+0x68/0xec fs/read_write.c:658) [<804d259c>] (ksys_write) from [<804d2698>] (__do_sys_write fs/read_write.c:670 [inline]) [<804d259c>] (ksys_write) from [<804d2698>] (sys_write+0x10/0x14 fs/read_write.c:667) [<804d2688>] (sys_write) from [<80200060>] (ret_fast_syscall+0x0/0x2c arch/arm/mm/proc-v7.S:64)
Fixes: 83c9e13aa39a ("netdevsim: add software driver for testing offloads") Reported-by: syzbot+e74a6857f2d0efe3ad81@syzkaller.appspotmail.com Tested-by: Dmitry Vyukov dvyukov@google.com Signed-off-by: Hillf Danton hdanton@sina.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/netdevsim/netdev.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/net/netdevsim/netdev.c +++ b/drivers/net/netdevsim/netdev.c @@ -296,6 +296,7 @@ nsim_create(struct nsim_dev *nsim_dev, s dev_net_set(dev, nsim_dev_net(nsim_dev)); ns = netdev_priv(dev); ns->netdev = dev; + u64_stats_init(&ns->syncp); ns->nsim_dev = nsim_dev; ns->nsim_dev_port = nsim_dev_port; ns->nsim_bus_dev = nsim_dev->nsim_bus_dev;
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Paul Moore paul@paul-moore.com
commit ad5d07f4a9cd671233ae20983848874731102c08 upstream.
The current CIPSO and CALIPSO refcounting scheme for the DOI definitions is a bit flawed in that we:
1. Don't correctly match gets/puts in netlbl_cipsov4_list(). 2. Decrement the refcount on each attempt to remove the DOI from the DOI list, only removing it from the list once the refcount drops to zero.
This patch fixes these problems by adding the missing "puts" to netlbl_cipsov4_list() and introduces a more conventional, i.e. not-buggy, refcounting mechanism to the DOI definitions. Upon the addition of a DOI to the DOI list, it is initialized with a refcount of one, removing a DOI from the list removes it from the list and drops the refcount by one; "gets" and "puts" behave as expected with respect to refcounts, increasing and decreasing the DOI's refcount by one.
Fixes: b1edeb102397 ("netlabel: Replace protocol/NetLabel linking with refrerence counts") Fixes: d7cce01504a0 ("netlabel: Add support for removing a CALIPSO DOI.") Reported-by: syzbot+9ec037722d2603a9f52e@syzkaller.appspotmail.com Signed-off-by: Paul Moore paul@paul-moore.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/ipv4/cipso_ipv4.c | 11 +---------- net/ipv6/calipso.c | 14 +++++--------- net/netlabel/netlabel_cipso_v4.c | 3 +++ 3 files changed, 9 insertions(+), 19 deletions(-)
--- a/net/ipv4/cipso_ipv4.c +++ b/net/ipv4/cipso_ipv4.c @@ -519,16 +519,10 @@ int cipso_v4_doi_remove(u32 doi, struct ret_val = -ENOENT; goto doi_remove_return; } - if (!refcount_dec_and_test(&doi_def->refcount)) { - spin_unlock(&cipso_v4_doi_list_lock); - ret_val = -EBUSY; - goto doi_remove_return; - } list_del_rcu(&doi_def->list); spin_unlock(&cipso_v4_doi_list_lock);
- cipso_v4_cache_invalidate(); - call_rcu(&doi_def->rcu, cipso_v4_doi_free_rcu); + cipso_v4_doi_putdef(doi_def); ret_val = 0;
doi_remove_return: @@ -585,9 +579,6 @@ void cipso_v4_doi_putdef(struct cipso_v4
if (!refcount_dec_and_test(&doi_def->refcount)) return; - spin_lock(&cipso_v4_doi_list_lock); - list_del_rcu(&doi_def->list); - spin_unlock(&cipso_v4_doi_list_lock);
cipso_v4_cache_invalidate(); call_rcu(&doi_def->rcu, cipso_v4_doi_free_rcu); --- a/net/ipv6/calipso.c +++ b/net/ipv6/calipso.c @@ -83,6 +83,9 @@ struct calipso_map_cache_entry {
static struct calipso_map_cache_bkt *calipso_cache;
+static void calipso_cache_invalidate(void); +static void calipso_doi_putdef(struct calipso_doi *doi_def); + /* Label Mapping Cache Functions */
@@ -444,15 +447,10 @@ static int calipso_doi_remove(u32 doi, s ret_val = -ENOENT; goto doi_remove_return; } - if (!refcount_dec_and_test(&doi_def->refcount)) { - spin_unlock(&calipso_doi_list_lock); - ret_val = -EBUSY; - goto doi_remove_return; - } list_del_rcu(&doi_def->list); spin_unlock(&calipso_doi_list_lock);
- call_rcu(&doi_def->rcu, calipso_doi_free_rcu); + calipso_doi_putdef(doi_def); ret_val = 0;
doi_remove_return: @@ -508,10 +506,8 @@ static void calipso_doi_putdef(struct ca
if (!refcount_dec_and_test(&doi_def->refcount)) return; - spin_lock(&calipso_doi_list_lock); - list_del_rcu(&doi_def->list); - spin_unlock(&calipso_doi_list_lock);
+ calipso_cache_invalidate(); call_rcu(&doi_def->rcu, calipso_doi_free_rcu); }
--- a/net/netlabel/netlabel_cipso_v4.c +++ b/net/netlabel/netlabel_cipso_v4.c @@ -575,6 +575,7 @@ list_start:
break; } + cipso_v4_doi_putdef(doi_def); rcu_read_unlock();
genlmsg_end(ans_skb, data); @@ -583,12 +584,14 @@ list_start: list_retry: /* XXX - this limit is a guesstimate */ if (nlsze_mult < 4) { + cipso_v4_doi_putdef(doi_def); rcu_read_unlock(); kfree_skb(ans_skb); nlsze_mult *= 2; goto list_start; } list_failure_lock: + cipso_v4_doi_putdef(doi_def); rcu_read_unlock(); list_failure: kfree_skb(ans_skb);
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Ong Boon Leong boon.leong.ong@intel.com
commit 9a7b3950c7e15968e23d83be215e95ccc7c92a53 upstream.
For Intel mGbE controller, MAC VLAN filter delete operation will time-out if serdes power-down sequence happened first during driver remove() with below message.
[82294.764958] intel-eth-pci 0000:00:1e.4 eth2: stmmac_dvr_remove: removing driver [82294.778677] intel-eth-pci 0000:00:1e.4 eth2: Timeout accessing MAC_VLAN_Tag_Filter [82294.779997] intel-eth-pci 0000:00:1e.4 eth2: failed to kill vid 0081/0 [82294.947053] intel-eth-pci 0000:00:1d.2 eth1: stmmac_dvr_remove: removing driver [82295.002091] intel-eth-pci 0000:00:1d.1 eth0: stmmac_dvr_remove: removing driver
Therefore, we delay the serdes power-down to be after unregister_netdev() which triggers the VLAN filter delete.
Fixes: b9663b7ca6ff ("net: stmmac: Enable SERDES power up/down sequence") Signed-off-by: Ong Boon Leong boon.leong.ong@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 | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -5114,13 +5114,16 @@ int stmmac_dvr_remove(struct device *dev netdev_info(priv->dev, "%s: removing driver", __func__);
stmmac_stop_all_dma(priv); + stmmac_mac_set(priv, priv->ioaddr, false); + netif_carrier_off(ndev); + unregister_netdev(ndev);
+ /* Serdes power down needs to happen after VLAN filter + * is deleted that is triggered by unregister_netdev(). + */ if (priv->plat->serdes_powerdown) priv->plat->serdes_powerdown(ndev, priv->plat->bsp_priv);
- stmmac_mac_set(priv, priv->ioaddr, false); - netif_carrier_off(ndev); - unregister_netdev(ndev); #ifdef CONFIG_DEBUG_FS stmmac_exit_fs(ndev); #endif
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Wong Vee Khee vee.khee.wong@intel.com
commit 8eb37ab7cc045ec6305a6a1a9c32374695a1a977 upstream.
Issue seen when enumerating multiple Intel mGbE interfaces in EHL.
[ 6.898141] intel-eth-pci 0000:00:1d.2: enabling device (0000 -> 0002) [ 6.900971] intel-eth-pci 0000:00:1d.2: Fail to register stmmac-clk [ 6.906434] intel-eth-pci 0000:00:1d.2: User ID: 0x51, Synopsys ID: 0x52
We fix it by making the clock name to be unique following the format of stmmac-pci_name(pci_dev) so that we can differentiate the clock for these Intel mGbE interfaces in EHL platform as follow:
/sys/kernel/debug/clk/stmmac-0000:00:1d.1 /sys/kernel/debug/clk/stmmac-0000:00:1d.2 /sys/kernel/debug/clk/stmmac-0000:00:1e.4
Fixes: 58da0cfa6cf1 ("net: stmmac: create dwmac-intel.c to contain all Intel platform") Signed-off-by: Wong Vee Khee vee.khee.wong@intel.com Signed-off-by: Voon Weifeng weifeng.voon@intel.com 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: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c @@ -233,6 +233,7 @@ static void common_default_data(struct p static int intel_mgbe_common_data(struct pci_dev *pdev, struct plat_stmmacenet_data *plat) { + char clk_name[20]; int ret; int i;
@@ -300,8 +301,10 @@ static int intel_mgbe_common_data(struct plat->eee_usecs_rate = plat->clk_ptp_rate;
/* Set system clock */ + sprintf(clk_name, "%s-%s", "stmmac", pci_name(pdev)); + plat->stmmac_clk = clk_register_fixed_rate(&pdev->dev, - "stmmac-clk", NULL, 0, + clk_name, NULL, 0, plat->clk_ptp_rate);
if (IS_ERR(plat->stmmac_clk)) {
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Xie He xie.he.0141@gmail.com
commit f7d9d4854519fdf4d45c70a4d953438cd88e7e58 upstream.
For the devices in this driver, the default qdisc is "noqueue", because their "tx_queue_len" is 0.
In function "__dev_queue_xmit" in "net/core/dev.c", devices with the "noqueue" qdisc are specially handled. Packets are transmitted without being queued after a "dev->flags & IFF_UP" check. However, it's possible that even if this check succeeds, "ops->ndo_stop" may still have already been called. This is because in "__dev_close_many", "ops->ndo_stop" is called before clearing the "IFF_UP" flag.
If we call "netif_stop_queue" in "ops->ndo_stop", then it's possible in "__dev_queue_xmit", it sees the "IFF_UP" flag is present, and then it checks "netif_xmit_stopped" and finds that the queue is already stopped. In this case, it will complain that: "Virtual device ... asks to queue packet!"
To prevent "__dev_queue_xmit" from generating this complaint, we should not call "netif_stop_queue" in "ops->ndo_stop".
We also don't need to call "netif_start_queue" in "ops->ndo_open", because after a netdev is allocated and registered, the "__QUEUE_STATE_DRV_XOFF" flag is initially not set, so there is no need to call "netif_start_queue" to clear it.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Xie He xie.he.0141@gmail.com Acked-by: Martin Schiller ms@dev.tdt.de Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/wan/lapbether.c | 3 --- 1 file changed, 3 deletions(-)
--- a/drivers/net/wan/lapbether.c +++ b/drivers/net/wan/lapbether.c @@ -283,7 +283,6 @@ static int lapbeth_open(struct net_devic return -ENODEV; }
- netif_start_queue(dev); return 0; }
@@ -291,8 +290,6 @@ static int lapbeth_close(struct net_devi { int err;
- netif_stop_queue(dev); - if ((err = lapb_unregister(dev)) != LAPB_OK) pr_err("lapb_unregister error: %d\n", err);
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Paul Cercueil paul@crapouillou.net
commit ac88c531a5b38877eba2365a3f28f0c8b513dc33 upstream.
When the probe fails or requests to be defered, we must disable the regulator that was previously enabled.
Fixes: 7994fe55a4a2 ("dm9000: Add regulator and reset support to dm9000") Signed-off-by: Paul Cercueil paul@crapouillou.net Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/davicom/dm9000.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
--- a/drivers/net/ethernet/davicom/dm9000.c +++ b/drivers/net/ethernet/davicom/dm9000.c @@ -1452,7 +1452,7 @@ dm9000_probe(struct platform_device *pde if (ret) { dev_err(dev, "failed to request reset gpio %d: %d\n", reset_gpios, ret); - return -ENODEV; + goto out_regulator_disable; }
/* According to manual PWRST# Low Period Min 1ms */ @@ -1464,8 +1464,10 @@ dm9000_probe(struct platform_device *pde
if (!pdata) { pdata = dm9000_parse_dt(&pdev->dev); - if (IS_ERR(pdata)) - return PTR_ERR(pdata); + if (IS_ERR(pdata)) { + ret = PTR_ERR(pdata); + goto out_regulator_disable; + } }
/* Init network device */ @@ -1706,6 +1708,10 @@ out: dm9000_release_board(pdev, db); free_netdev(ndev);
+out_regulator_disable: + if (!IS_ERR(power)) + regulator_disable(power); + return ret; }
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Paul Cercueil paul@crapouillou.net
commit cf9e60aa69ae6c40d3e3e4c94dd6c8de31674e9b upstream.
We must disable the regulator that was enabled in the probe function.
Fixes: 7994fe55a4a2 ("dm9000: Add regulator and reset support to dm9000") Signed-off-by: Paul Cercueil paul@crapouillou.net Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/davicom/dm9000.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
--- a/drivers/net/ethernet/davicom/dm9000.c +++ b/drivers/net/ethernet/davicom/dm9000.c @@ -133,6 +133,8 @@ struct board_info { u32 wake_state;
int ip_summed; + + struct regulator *power_supply; };
/* debug code */ @@ -1484,6 +1486,8 @@ dm9000_probe(struct platform_device *pde
db->dev = &pdev->dev; db->ndev = ndev; + if (!IS_ERR(power)) + db->power_supply = power;
spin_lock_init(&db->lock); mutex_init(&db->addr_lock); @@ -1769,10 +1773,13 @@ static int dm9000_drv_remove(struct platform_device *pdev) { struct net_device *ndev = platform_get_drvdata(pdev); + struct board_info *dm = to_dm9000_board(ndev);
unregister_netdev(ndev); - dm9000_release_board(pdev, netdev_priv(ndev)); + dm9000_release_board(pdev, dm); free_netdev(ndev); /* free device structure */ + if (dm->power_supply) + regulator_disable(dm->power_supply);
dev_dbg(&pdev->dev, "released and freed device\n"); return 0;
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Vladimir Oltean vladimir.oltean@nxp.com
commit 29d98f54a4fe1b6a9089bec8715a1b89ff9ad59c upstream.
The txtime is passed to the driver in skb->skb_mstamp_ns, which is actually in a union with skb->tstamp (the place where software timestamps are kept).
Since commit b50a5c70ffa4 ("net: allow simultaneous SW and HW transmit timestamping"), __sock_recv_timestamp has some logic for making sure that the two calls to skb_tstamp_tx:
skb_tx_timestamp(skb) # Software timestamp in the driver -> skb_tstamp_tx(skb, NULL)
and
skb_tstamp_tx(skb, &shhwtstamps) # Hardware timestamp in the driver
will both do the right thing and in a race-free manner, meaning that skb_tx_timestamp will deliver a cmsg with the software timestamp only, and skb_tstamp_tx with a non-NULL hwtstamps argument will deliver a cmsg with the hardware timestamp only.
Why are races even possible? Well, because although the software timestamp skb->tstamp is private per skb, the hardware timestamp skb_hwtstamps(skb) lives in skb_shinfo(skb), an area which is shared between skbs and their clones. And skb_tstamp_tx works by cloning the packets when timestamping them, therefore attempting to perform hardware timestamping on an skb's clone will also change the hardware timestamp of the original skb. And the original skb might have been yet again cloned for software timestamping, at an earlier stage.
So the logic in __sock_recv_timestamp can't be as simple as saying "does this skb have a hardware timestamp? if yes I'll send the hardware timestamp to the socket, otherwise I'll send the software timestamp", precisely because the hardware timestamp is shared. Instead, it's quite the other way around: __sock_recv_timestamp says "does this skb have a software timestamp? if yes, I'll send the software timestamp, otherwise the hardware one". This works because the software timestamp is not shared with clones.
But that means we have a problem when we attempt hardware timestamping with skbs that don't have the skb->tstamp == 0. __sock_recv_timestamp will say "oh, yeah, this must be some sort of odd clone" and will not deliver the hardware timestamp to the socket. And this is exactly what is happening when we have txtime enabled on the socket: as mentioned, that is put in a union with skb->tstamp, so it is quite easy to mistake it.
Do what other drivers do (intel igb/igc) and write zero to skb->tstamp before taking the hardware timestamp. It's of no use to us now (we're already on the TX confirmation path).
Fixes: 0d08c9ec7d6e ("enetc: add support time specific departure base on the qos etf") Cc: Vinicius Costa Gomes vinicius.gomes@intel.com Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Acked-by: Vinicius Costa Gomes vinicius.gomes@intel.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/freescale/enetc/enetc.c | 6 ++++++ 1 file changed, 6 insertions(+)
--- a/drivers/net/ethernet/freescale/enetc/enetc.c +++ b/drivers/net/ethernet/freescale/enetc/enetc.c @@ -384,6 +384,12 @@ static void enetc_tstamp_tx(struct sk_bu if (skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS) { memset(&shhwtstamps, 0, sizeof(shhwtstamps)); shhwtstamps.hwtstamp = ns_to_ktime(tstamp); + /* Ensure skb_mstamp_ns, which might have been populated with + * the txtime, is not mistaken for a software timestamp, + * because this will prevent the dispatch of our hardware + * timestamp to the socket. + */ + skb->tstamp = ktime_set(0, 0); skb_tstamp_tx(skb, &shhwtstamps); } }
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Jia-Ju Bai baijiaju1990@gmail.com
commit 179d0ba0c454057a65929c46af0d6ad986754781 upstream.
When sock_alloc_send_skb() returns NULL to skb, no error return code of qrtr_sendmsg() is assigned. To fix this bug, rc is assigned with -ENOMEM in this case.
Fixes: 194ccc88297a ("net: qrtr: Support decoding incoming v2 packets") Reported-by: TOTE Robot oslab@tsinghua.edu.cn Signed-off-by: Jia-Ju Bai baijiaju1990@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/qrtr/qrtr.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
--- a/net/qrtr/qrtr.c +++ b/net/qrtr/qrtr.c @@ -935,8 +935,10 @@ static int qrtr_sendmsg(struct socket *s plen = (len + 3) & ~3; skb = sock_alloc_send_skb(sk, plen + QRTR_HDR_MAX_SIZE, msg->msg_flags & MSG_DONTWAIT, &rc); - if (!skb) + if (!skb) { + rc = -ENOMEM; goto out_node; + }
skb_reserve(skb, QRTR_HDR_MAX_SIZE);
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Julian Wiedmann jwi@linux.ibm.com
commit e7a36d27f6b9f389e41d8189a8a08919c6835732 upstream.
When qeth_alloc_qdio_queues() fails to allocate one of the buffers that back an Output Queue, the 'out_freeoutqbufs' path will free all previously allocated buffers for this queue. But it misses to free the half-finished queue struct itself.
Move the buffer allocation into qeth_alloc_output_queue(), and deal with such errors internally.
Fixes: 0da9581ddb0f ("qeth: exploit asynchronous delivery of storage blocks") Signed-off-by: Julian Wiedmann jwi@linux.ibm.com Reviewed-by: Alexandra Winter wintera@linux.ibm.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/s390/net/qeth_core_main.c | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-)
--- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -2632,15 +2632,28 @@ static void qeth_free_output_queue(struc static struct qeth_qdio_out_q *qeth_alloc_output_queue(void) { struct qeth_qdio_out_q *q = kzalloc(sizeof(*q), GFP_KERNEL); + unsigned int i;
if (!q) return NULL;
- if (qdio_alloc_buffers(q->qdio_bufs, QDIO_MAX_BUFFERS_PER_Q)) { - kfree(q); - return NULL; + if (qdio_alloc_buffers(q->qdio_bufs, QDIO_MAX_BUFFERS_PER_Q)) + goto err_qdio_bufs; + + for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; i++) { + if (qeth_init_qdio_out_buf(q, i)) + goto err_out_bufs; } + return q; + +err_out_bufs: + while (i > 0) + kmem_cache_free(qeth_qdio_outbuf_cache, q->bufs[--i]); + qdio_free_buffers(q->qdio_bufs, QDIO_MAX_BUFFERS_PER_Q); +err_qdio_bufs: + kfree(q); + return NULL; }
static void qeth_tx_completion_timer(struct timer_list *timer) @@ -2653,7 +2666,7 @@ static void qeth_tx_completion_timer(str
static int qeth_alloc_qdio_queues(struct qeth_card *card) { - int i, j; + unsigned int i;
QETH_CARD_TEXT(card, 2, "allcqdbf");
@@ -2687,13 +2700,6 @@ static int qeth_alloc_qdio_queues(struct queue->coalesce_usecs = QETH_TX_COALESCE_USECS; queue->max_coalesced_frames = QETH_TX_MAX_COALESCED_FRAMES; queue->priority = QETH_QIB_PQUE_PRIO_DEFAULT; - - /* give outbound qeth_qdio_buffers their qdio_buffers */ - for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j) { - WARN_ON(queue->bufs[j]); - if (qeth_init_qdio_out_buf(queue, j)) - goto out_freeoutqbufs; - } }
/* completion */ @@ -2702,13 +2708,6 @@ static int qeth_alloc_qdio_queues(struct
return 0;
-out_freeoutqbufs: - while (j > 0) { - --j; - kmem_cache_free(qeth_qdio_outbuf_cache, - card->qdio.out_qs[i]->bufs[j]); - card->qdio.out_qs[i]->bufs[j] = NULL; - } out_freeoutq: while (i > 0) { qeth_free_output_queue(card->qdio.out_qs[--i]);
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Hayes Wang hayeswang@realtek.com
commit abbf9a0ef8848dca58c5b97750c1c59bbee45637 upstream.
The (0xBAF70000 & 0x00FFF000) << 6 should be (0xf70 << 18).
Fixes: 561535b0f239 ("r8169: fix OCP access on RTL8117") Signed-off-by: Hayes Wang hayeswang@realtek.com Acked-by: Heiner Kallweit hkallweit1@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/realtek/r8169_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/ethernet/realtek/r8169_main.c +++ b/drivers/net/ethernet/realtek/r8169_main.c @@ -1042,7 +1042,7 @@ static void r8168fp_adjust_ocp_cmd(struc { /* based on RTL8168FP_OOBMAC_BASE in vendor driver */ if (tp->mac_version == RTL_GIGA_MAC_VER_52 && type == ERIAR_OOB) - *cmd |= 0x7f0 << 18; + *cmd |= 0xf70 << 18; }
DECLARE_RTL_COND(rtl_eriar_cond)
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Antony Antony antony@phenome.org
commit d785e1fec60179f534fbe8d006c890e5ad186e51 upstream.
Based on talks and indirect references ixgbe IPsec offlod do not support IPsec tunnel mode offload. It can only support IPsec transport mode offload. Now explicitly fail when creating non transport mode SA with offload to avoid false performance expectations.
Fixes: 63a67fe229ea ("ixgbe: add ipsec offload add and remove SA") Signed-off-by: Antony Antony antony@phenome.org Acked-by: Shannon Nelson snelson@pensando.io Tested-by: Tony Brelinski tonyx.brelinski@intel.com Signed-off-by: Tony Nguyen anthony.l.nguyen@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c | 5 +++++ drivers/net/ethernet/intel/ixgbevf/ipsec.c | 5 +++++ 2 files changed, 10 insertions(+)
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c @@ -575,6 +575,11 @@ static int ixgbe_ipsec_add_sa(struct xfr return -EINVAL; }
+ if (xs->props.mode != XFRM_MODE_TRANSPORT) { + netdev_err(dev, "Unsupported mode for ipsec offload\n"); + return -EINVAL; + } + if (ixgbe_ipsec_check_mgmt_ip(xs)) { netdev_err(dev, "IPsec IP addr clash with mgmt filters\n"); return -EINVAL; --- a/drivers/net/ethernet/intel/ixgbevf/ipsec.c +++ b/drivers/net/ethernet/intel/ixgbevf/ipsec.c @@ -272,6 +272,11 @@ static int ixgbevf_ipsec_add_sa(struct x return -EINVAL; }
+ if (xs->props.mode != XFRM_MODE_TRANSPORT) { + netdev_err(dev, "Unsupported mode for ipsec offload\n"); + return -EINVAL; + } + if (xs->xso.flags & XFRM_OFFLOAD_INBOUND) { struct rx_sa rsa;
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Kun-Chuan Hsieh jetswayss@gmail.com
commit 41462c6e730ca0e63f5fed5a517052385d980c54 upstream.
Older libelf.h and glibc elf.h might not yet define the ELF compression types.
Checking and defining SHF_COMPRESSED fix the build error when compiling with older toolchains. Also, the tool resolve_btfids is compiled with host toolchain. The host toolchain is more likely to be older than the cross compile toolchain.
Fixes: 51f6463aacfb ("tools/resolve_btfids: Fix sections with wrong alignment") Signed-off-by: Kun-Chuan Hsieh jetswayss@gmail.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Acked-by: Jiri Olsa jolsa@redhat.com Link: https://lore.kernel.org/bpf/20210224052752.5284-1-jetswayss@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- tools/bpf/resolve_btfids/main.c | 5 +++++ 1 file changed, 5 insertions(+)
--- a/tools/bpf/resolve_btfids/main.c +++ b/tools/bpf/resolve_btfids/main.c @@ -258,6 +258,11 @@ static struct btf_id *add_symbol(struct return btf_id__add(root, id, false); }
+/* Older libelf.h and glibc elf.h might not yet define the ELF compression types. */ +#ifndef SHF_COMPRESSED +#define SHF_COMPRESSED (1 << 11) /* Section with compressed data. */ +#endif + /* * The data of compressed section should be aligned to 4 * (for 32bit) or 8 (for 64 bit) bytes. The binutils ld
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Antonio Terceiro antonio.terceiro@linaro.org
commit dacfc08dcafa7d443ab339592999e37bbb8a3ef0 upstream.
This was introduced by commit e4ffd066ff440a57 ("perf: Normalize gcc parameter when generating arch errno table").
Assuming the first word of $(CC) is the actual compiler breaks usage like CC="ccache gcc": the script ends up calling ccache directly with gcc arguments, what fails. Instead of getting the first word, just remove from $(CC) any word that starts with a "-". This maintains the spirit of the original patch, while not breaking ccache users.
Fixes: e4ffd066ff440a57 ("perf: Normalize gcc parameter when generating arch errno table") Signed-off-by: Antonio Terceiro antonio.terceiro@linaro.org Tested-by: Arnaldo Carvalho de Melo acme@redhat.com Cc: Alexander Shishkin alexander.shishkin@linux.intel.com Cc: He Zhe zhe.he@windriver.com Cc: Jiri Olsa jolsa@redhat.com Cc: Mark Rutland mark.rutland@arm.com Cc: Namhyung Kim namhyung@kernel.org Cc: Peter Zijlstra peterz@infradead.org Cc: stable@vger.kernel.org Link: http://lore.kernel.org/lkml/20210224130046.346977-1-antonio.terceiro@linaro.... Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- tools/perf/Makefile.perf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -600,7 +600,7 @@ arch_errno_hdr_dir := $(srctree)/tools arch_errno_tbl := $(srctree)/tools/perf/trace/beauty/arch_errno_names.sh
$(arch_errno_name_array): $(arch_errno_tbl) - $(Q)$(SHELL) '$(arch_errno_tbl)' $(firstword $(CC)) $(arch_errno_hdr_dir) > $@ + $(Q)$(SHELL) '$(arch_errno_tbl)' '$(patsubst -%,,$(CC))' $(arch_errno_hdr_dir) > $@
sync_file_range_arrays := $(beauty_outdir)/sync_file_range_arrays.c sync_file_range_tbls := $(srctree)/tools/perf/trace/beauty/sync_file_range.sh
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Joakim Zhang qiangqing.zhang@nxp.com
commit a3e860a83397bf761ec1128a3f0ba186445992c6 upstream.
If clear GMAC_CONFIG_TE bit, it would stop all tx channels, but users may only want to stop specific tx channel.
Fixes: 48863ce5940f ("stmmac: add DMA support for GMAC 4.xx") Signed-off-by: Joakim Zhang qiangqing.zhang@nxp.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c | 4 ---- 1 file changed, 4 deletions(-)
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c @@ -53,10 +53,6 @@ void dwmac4_dma_stop_tx(void __iomem *io
value &= ~DMA_CONTROL_ST; writel(value, ioaddr + DMA_CHAN_TX_CONTROL(chan)); - - value = readl(ioaddr + GMAC_CONFIG); - value &= ~GMAC_CONFIG_TE; - writel(value, ioaddr + GMAC_CONFIG); }
void dwmac4_dma_start_rx(void __iomem *ioaddr, u32 chan)
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Joakim Zhang qiangqing.zhang@nxp.com
commit c511819d138de38e1637eedb645c207e09680d0f upstream.
stmmac_xmit() call stmmac_tx_timer_arm() at the end to modify tx timer to do the transmission cleanup work. Imagine such a situation, stmmac enters suspend immediately after tx timer modified, it's expire callback stmmac_tx_clean() would not be invoked. This could affect BQL, since netdev_tx_sent_queue() has been called, but netdev_tx_completed_queue() have not been involved, as a result, dql_avail(&dev_queue->dql) finally always return a negative value.
__dev_queue_xmit->__dev_xmit_skb->qdisc_run->__qdisc_run->qdisc_restart->dequeue_skb: if ((q->flags & TCQ_F_ONETXQUEUE) && netif_xmit_frozen_or_stopped(txq)) // __QUEUE_STATE_STACK_XOFF is set
Net core will stop transmitting any more. Finillay, net watchdong would timeout. To fix this issue, we should call netdev_tx_reset_queue() in stmmac_resume().
Fixes: 54139cf3bb33 ("net: stmmac: adding multiple buffers for rx") Signed-off-by: Joakim Zhang qiangqing.zhang@nxp.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -5230,6 +5230,8 @@ static void stmmac_reset_queues_param(st tx_q->cur_tx = 0; tx_q->dirty_tx = 0; tx_q->mss = 0; + + netdev_tx_reset_queue(netdev_get_tx_queue(priv->dev, queue)); } }
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Joakim Zhang qiangqing.zhang@nxp.com
commit 396e13e11577b614db77db0bbb6fca935b94eb1b upstream.
In current driver, buffer2 available only when hardware supports split header. Wrongly set buffer2 valid in stmmac_rx_refill when refill buffer address. You can see that desc3 is 0x81000000 after initialization, but turn out to be 0x83000000 after refill.
Fixes: 67afd6d1cfdf ("net: stmmac: Add Split Header support and enable it in XGMAC cores") Signed-off-by: Joakim Zhang qiangqing.zhang@nxp.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c | 9 +++++++-- drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c | 2 +- drivers/net/ethernet/stmicro/stmmac/hwif.h | 2 +- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 8 ++++++-- 4 files changed, 15 insertions(+), 6 deletions(-)
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c @@ -499,10 +499,15 @@ static void dwmac4_get_rx_header_len(str *len = le32_to_cpu(p->des2) & RDES2_HL; }
-static void dwmac4_set_sec_addr(struct dma_desc *p, dma_addr_t addr) +static void dwmac4_set_sec_addr(struct dma_desc *p, dma_addr_t addr, bool buf2_valid) { p->des2 = cpu_to_le32(lower_32_bits(addr)); - p->des3 = cpu_to_le32(upper_32_bits(addr) | RDES3_BUFFER2_VALID_ADDR); + p->des3 = cpu_to_le32(upper_32_bits(addr)); + + if (buf2_valid) + p->des3 |= cpu_to_le32(RDES3_BUFFER2_VALID_ADDR); + else + p->des3 &= cpu_to_le32(~RDES3_BUFFER2_VALID_ADDR); }
static void dwmac4_set_tbs(struct dma_edesc *p, u32 sec, u32 nsec) --- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c @@ -292,7 +292,7 @@ static void dwxgmac2_get_rx_header_len(s *len = le32_to_cpu(p->des2) & XGMAC_RDES2_HL; }
-static void dwxgmac2_set_sec_addr(struct dma_desc *p, dma_addr_t addr) +static void dwxgmac2_set_sec_addr(struct dma_desc *p, dma_addr_t addr, bool is_valid) { p->des2 = cpu_to_le32(lower_32_bits(addr)); p->des3 = cpu_to_le32(upper_32_bits(addr)); --- a/drivers/net/ethernet/stmicro/stmmac/hwif.h +++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h @@ -91,7 +91,7 @@ struct stmmac_desc_ops { int (*get_rx_hash)(struct dma_desc *p, u32 *hash, enum pkt_hash_types *type); void (*get_rx_header_len)(struct dma_desc *p, unsigned int *len); - void (*set_sec_addr)(struct dma_desc *p, dma_addr_t addr); + void (*set_sec_addr)(struct dma_desc *p, dma_addr_t addr, bool buf2_valid); void (*set_sarc)(struct dma_desc *p, u32 sarc_type); void (*set_vlan_tag)(struct dma_desc *p, u16 tag, u16 inner_tag, u32 inner_type); --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -1279,9 +1279,10 @@ static int stmmac_init_rx_buffers(struct return -ENOMEM;
buf->sec_addr = page_pool_get_dma_addr(buf->sec_page); - stmmac_set_desc_sec_addr(priv, p, buf->sec_addr); + stmmac_set_desc_sec_addr(priv, p, buf->sec_addr, true); } else { buf->sec_page = NULL; + stmmac_set_desc_sec_addr(priv, p, buf->sec_addr, false); }
buf->addr = page_pool_get_dma_addr(buf->page); @@ -3618,7 +3619,10 @@ static inline void stmmac_rx_refill(stru DMA_FROM_DEVICE);
stmmac_set_desc_addr(priv, p, buf->addr); - stmmac_set_desc_sec_addr(priv, p, buf->sec_addr); + if (priv->sph) + stmmac_set_desc_sec_addr(priv, p, buf->sec_addr, true); + else + stmmac_set_desc_sec_addr(priv, p, buf->sec_addr, false); stmmac_refill_desc3(priv, rx_q, p);
rx_q->rx_count_frames++;
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Yinjun Zhang yinjun.zhang@corigine.com
commit a4fc088ad4ff4a99d01978aa41065132b574b4b2 upstream.
The command "ethtool -L <intf> combined 0" may clean the RX/TX channel count and skip the error path, since the attrs tb[ETHTOOL_A_CHANNELS_RX_COUNT] and tb[ETHTOOL_A_CHANNELS_TX_COUNT] are NULL in this case when recent ethtool is used.
Tested using ethtool v5.10.
Fixes: 7be92514b99c ("ethtool: check if there is at least one channel for TX/RX in the core") Signed-off-by: Yinjun Zhang yinjun.zhang@corigine.com Signed-off-by: Simon Horman simon.horman@netronome.com Signed-off-by: Louis Peens louis.peens@netronome.com Link: https://lore.kernel.org/r/20210225125102.23989-1-simon.horman@netronome.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/ethtool/channels.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-)
--- a/net/ethtool/channels.c +++ b/net/ethtool/channels.c @@ -116,10 +116,9 @@ int ethnl_set_channels(struct sk_buff *s struct ethtool_channels channels = {}; struct ethnl_req_info req_info = {}; struct nlattr **tb = info->attrs; - const struct nlattr *err_attr; + u32 err_attr, max_rx_in_use = 0; const struct ethtool_ops *ops; struct net_device *dev; - u32 max_rx_in_use = 0; int ret;
ret = ethnl_parse_header_dev_get(&req_info, @@ -157,34 +156,35 @@ int ethnl_set_channels(struct sk_buff *s
/* ensure new channel counts are within limits */ if (channels.rx_count > channels.max_rx) - err_attr = tb[ETHTOOL_A_CHANNELS_RX_COUNT]; + err_attr = ETHTOOL_A_CHANNELS_RX_COUNT; else if (channels.tx_count > channels.max_tx) - err_attr = tb[ETHTOOL_A_CHANNELS_TX_COUNT]; + err_attr = ETHTOOL_A_CHANNELS_TX_COUNT; else if (channels.other_count > channels.max_other) - err_attr = tb[ETHTOOL_A_CHANNELS_OTHER_COUNT]; + err_attr = ETHTOOL_A_CHANNELS_OTHER_COUNT; else if (channels.combined_count > channels.max_combined) - err_attr = tb[ETHTOOL_A_CHANNELS_COMBINED_COUNT]; + err_attr = ETHTOOL_A_CHANNELS_COMBINED_COUNT; else - err_attr = NULL; + err_attr = 0; if (err_attr) { ret = -EINVAL; - NL_SET_ERR_MSG_ATTR(info->extack, err_attr, + NL_SET_ERR_MSG_ATTR(info->extack, tb[err_attr], "requested channel count exceeds maximum"); goto out_ops; }
/* ensure there is at least one RX and one TX channel */ if (!channels.combined_count && !channels.rx_count) - err_attr = tb[ETHTOOL_A_CHANNELS_RX_COUNT]; + err_attr = ETHTOOL_A_CHANNELS_RX_COUNT; else if (!channels.combined_count && !channels.tx_count) - err_attr = tb[ETHTOOL_A_CHANNELS_TX_COUNT]; + err_attr = ETHTOOL_A_CHANNELS_TX_COUNT; else - err_attr = NULL; + err_attr = 0; if (err_attr) { if (mod_combined) - err_attr = tb[ETHTOOL_A_CHANNELS_COMBINED_COUNT]; + err_attr = ETHTOOL_A_CHANNELS_COMBINED_COUNT; ret = -EINVAL; - NL_SET_ERR_MSG_ATTR(info->extack, err_attr, "requested channel counts would result in no RX or TX channel being configured"); + NL_SET_ERR_MSG_ATTR(info->extack, tb[err_attr], + "requested channel counts would result in no RX or TX channel being configured"); goto out_ops; }
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Arnd Bergmann arnd@arndb.de
commit 7f654157f0aefba04cd7f6297351c87b76b47b89 upstream.
When CONFIG_PM_SLEEP is disabled, the compiler warns about unused functions:
drivers/net/phy/phy_device.c:273:12: error: unused function 'mdio_bus_phy_suspend' [-Werror,-Wunused-function] static int mdio_bus_phy_suspend(struct device *dev) drivers/net/phy/phy_device.c:293:12: error: unused function 'mdio_bus_phy_resume' [-Werror,-Wunused-function] static int mdio_bus_phy_resume(struct device *dev)
The logic is intentional, so just mark these two as __maybe_unused and remove the incorrect #ifdef.
Fixes: 4c0d2e96ba05 ("net: phy: consider that suspend2ram may cut off PHY power") Signed-off-by: Arnd Bergmann arnd@arndb.de Reviewed-by: Andrew Lunn andrew@lunn.ch Link: https://lore.kernel.org/r/20210225145748.404410-1-arnd@kernel.org Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/phy/phy_device.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
--- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -230,7 +230,6 @@ static struct phy_driver genphy_driver; static LIST_HEAD(phy_fixup_list); static DEFINE_MUTEX(phy_fixup_lock);
-#ifdef CONFIG_PM static bool mdio_bus_phy_may_suspend(struct phy_device *phydev) { struct device_driver *drv = phydev->mdio.dev.driver; @@ -270,7 +269,7 @@ out: return !phydev->suspended; }
-static int mdio_bus_phy_suspend(struct device *dev) +static __maybe_unused int mdio_bus_phy_suspend(struct device *dev) { struct phy_device *phydev = to_phy_device(dev);
@@ -290,7 +289,7 @@ static int mdio_bus_phy_suspend(struct d return phy_suspend(phydev); }
-static int mdio_bus_phy_resume(struct device *dev) +static __maybe_unused int mdio_bus_phy_resume(struct device *dev) { struct phy_device *phydev = to_phy_device(dev); int ret; @@ -316,7 +315,6 @@ no_resume:
static SIMPLE_DEV_PM_OPS(mdio_bus_phy_pm_ops, mdio_bus_phy_suspend, mdio_bus_phy_resume); -#endif /* CONFIG_PM */
/** * phy_register_fixup - creates a new phy_fixup and adds it to the list
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Danielle Ratson danieller@nvidia.com
commit edcbf5137f093b5502f5f6b97cce3cbadbde27aa upstream.
When mirroring to a gretap in hardware the device expects to be programmed with the egress port and all the encapsulating headers. This requires the driver to resolve the path the packet will take in the software data path and program the device accordingly.
If the path cannot be resolved (in this case because of an unresolved neighbor), then mirror installation fails until the path is resolved. This results in a race that causes the test to sometimes fail.
Fix this by setting the neighbor's state to permanent, so that it is always valid.
Fixes: b5b029399fa6d ("selftests: forwarding: mirror_gre_bridge_1d_vlan: Add STP test") Signed-off-by: Danielle Ratson danieller@nvidia.com Reviewed-by: Petr Machata petrm@nvidia.com Signed-off-by: Ido Schimmel idosch@nvidia.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- tools/testing/selftests/net/forwarding/mirror_gre_bridge_1d_vlan.sh | 9 +++++++++ 1 file changed, 9 insertions(+)
--- a/tools/testing/selftests/net/forwarding/mirror_gre_bridge_1d_vlan.sh +++ b/tools/testing/selftests/net/forwarding/mirror_gre_bridge_1d_vlan.sh @@ -86,11 +86,20 @@ test_ip6gretap()
test_gretap_stp() { + # Sometimes after mirror installation, the neighbor's state is not valid. + # The reason is that there is no SW datapath activity related to the + # neighbor for the remote GRE address. Therefore whether the corresponding + # neighbor will be valid is a matter of luck, and the test is thus racy. + # Set the neighbor's state to permanent, so it would be always valid. + ip neigh replace 192.0.2.130 lladdr $(mac_get $h3) \ + nud permanent dev br2 full_test_span_gre_stp gt4 $swp3.555 "mirror to gretap" }
test_ip6gretap_stp() { + ip neigh replace 2001:db8:2::2 lladdr $(mac_get $h3) \ + nud permanent dev br2 full_test_span_gre_stp gt6 $swp3.555 "mirror to ip6gretap" }
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Danielle Ratson danieller@nvidia.com
commit ae9b24ddb69b4e31cda1b5e267a5a08a1db11717 upstream.
Currently, only external bits are added to the PTYS register, whereas there is one external bit that is wrongly marked as internal, and so was recently removed from the register.
Add that bit to the PTYS register again, as this bit is no longer internal.
Its removal resulted in '100000baseLR4_ER4/Full' link mode no longer being supported, causing a regression on some setups.
Fixes: 5bf01b571cf4 ("mlxsw: spectrum_ethtool: Remove internal speeds from PTYS register") Signed-off-by: Danielle Ratson danieller@nvidia.com Reported-by: Eddie Shklaer eddies@nvidia.com Tested-by: Eddie Shklaer eddies@nvidia.com Reviewed-by: Jiri Pirko jiri@nvidia.com Signed-off-by: Ido Schimmel idosch@nvidia.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/mellanox/mlxsw/reg.h | 1 + drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c | 5 +++++ drivers/net/ethernet/mellanox/mlxsw/switchx2.c | 3 ++- 3 files changed, 8 insertions(+), 1 deletion(-)
--- a/drivers/net/ethernet/mellanox/mlxsw/reg.h +++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h @@ -4208,6 +4208,7 @@ MLXSW_ITEM32(reg, ptys, ext_eth_proto_ca #define MLXSW_REG_PTYS_ETH_SPEED_100GBASE_CR4 BIT(20) #define MLXSW_REG_PTYS_ETH_SPEED_100GBASE_SR4 BIT(21) #define MLXSW_REG_PTYS_ETH_SPEED_100GBASE_KR4 BIT(22) +#define MLXSW_REG_PTYS_ETH_SPEED_100GBASE_LR4_ER4 BIT(23) #define MLXSW_REG_PTYS_ETH_SPEED_25GBASE_CR BIT(27) #define MLXSW_REG_PTYS_ETH_SPEED_25GBASE_KR BIT(28) #define MLXSW_REG_PTYS_ETH_SPEED_25GBASE_SR BIT(29) --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c @@ -1171,6 +1171,11 @@ static const struct mlxsw_sp1_port_link_ .mask_ethtool = ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT, .speed = SPEED_100000, }, + { + .mask = MLXSW_REG_PTYS_ETH_SPEED_100GBASE_LR4_ER4, + .mask_ethtool = ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT, + .speed = SPEED_100000, + }, };
#define MLXSW_SP1_PORT_LINK_MODE_LEN ARRAY_SIZE(mlxsw_sp1_port_link_mode) --- a/drivers/net/ethernet/mellanox/mlxsw/switchx2.c +++ b/drivers/net/ethernet/mellanox/mlxsw/switchx2.c @@ -612,7 +612,8 @@ static const struct mlxsw_sx_port_link_m { .mask = MLXSW_REG_PTYS_ETH_SPEED_100GBASE_CR4 | MLXSW_REG_PTYS_ETH_SPEED_100GBASE_SR4 | - MLXSW_REG_PTYS_ETH_SPEED_100GBASE_KR4, + MLXSW_REG_PTYS_ETH_SPEED_100GBASE_KR4 | + MLXSW_REG_PTYS_ETH_SPEED_100GBASE_LR4_ER4, .speed = 100000, }, };
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Ian Rogers irogers@google.com
commit 137a5258939aca56558f3a23eb229b9c4b293917 upstream.
Issue detected by address sanitizer.
Fixes: cd4ceb63438e9e28 ("perf util: Save pid-cmdline mapping into tracing header") Signed-off-by: Ian Rogers irogers@google.com Acked-by: Namhyung Kim namhyung@kernel.org Cc: Alexander Shishkin alexander.shishkin@linux.intel.com Cc: Jiri Olsa jolsa@redhat.com Cc: Mark Rutland mark.rutland@arm.com Cc: Peter Zijlstra peterz@infradead.org Cc: Stephane Eranian eranian@google.com Link: http://lore.kernel.org/lkml/20210226221431.1985458-1-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- tools/perf/util/trace-event-read.c | 1 + 1 file changed, 1 insertion(+)
--- a/tools/perf/util/trace-event-read.c +++ b/tools/perf/util/trace-event-read.c @@ -361,6 +361,7 @@ static int read_saved_cmdline(struct tep pr_debug("error reading saved cmdlines\n"); goto out; } + buf[ret] = '\0';
parse_saved_cmdline(pevent, buf, size); ret = 0;
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Ravi Bangoria ravi.bangoria@linux.ibm.com
commit 6740a4e70e5d1b9d8e7fe41fd46dd5656d65dadf upstream.
perf report fails to add valid additional fields with -F when used with branch or mem modes. Fix it.
Before patch:
$ perf record -b $ perf report -b -F +srcline_from --stdio Error: Invalid --fields key: `srcline_from'
After patch:
$ perf report -b -F +srcline_from --stdio # Samples: 8K of event 'cycles' # Event count (approx.): 8784 ...
Committer notes:
There was an inversion: when looking at branch stack dimensions (keys) it was checking if the sort mode was 'mem', not 'branch'.
Fixes: aa6b3c99236b ("perf report: Make -F more strict like -s") Reported-by: Athira Jajeev atrajeev@linux.vnet.ibm.com Signed-off-by: Ravi Bangoria ravi.bangoria@linux.ibm.com Reviewed-by: Athira Jajeev atrajeev@linux.vnet.ibm.com Tested-by: Arnaldo Carvalho de Melo acme@redhat.com Tested-by: Athira Jajeev atrajeev@linux.vnet.ibm.com Cc: Jiri Olsa jolsa@redhat.com Cc: Kan Liang kan.liang@linux.intel.com Cc: Namhyung Kim namhyung@kernel.org Link: http://lore.kernel.org/lkml/20210304062958.85465-1-ravi.bangoria@linux.ibm.c... Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- tools/perf/util/sort.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -3003,7 +3003,7 @@ int output_field_add(struct perf_hpp_lis if (strncasecmp(tok, sd->name, strlen(tok))) continue;
- if (sort__mode != SORT_MODE__MEMORY) + if (sort__mode != SORT_MODE__BRANCH) return -EINVAL;
return __sort_dimension__add_output(list, sd); @@ -3015,7 +3015,7 @@ int output_field_add(struct perf_hpp_lis if (strncasecmp(tok, sd->name, strlen(tok))) continue;
- if (sort__mode != SORT_MODE__BRANCH) + if (sort__mode != SORT_MODE__MEMORY) return -EINVAL;
return __sort_dimension__add_output(list, sd);
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Jian Shen shenjian15@huawei.com
commit c75ec148a316e8cf52274d16b9b422703b96f5ce upstream.
Currently, the driver returns VLAN_VID_MASK for vlan mask field, when get flow director rule information for rule doesn't use vlan. It may cause the vlan mask value display as 0xf000 in this case, like below:
estuary:/$ ethtool -u eth1 50 RX rings available Total 1 rules
Filter: 2 Rule Type: TCP over IPv4 Src IP addr: 0.0.0.0 mask: 255.255.255.255 Dest IP addr: 0.0.0.0 mask: 255.255.255.255 TOS: 0x0 mask: 0xff Src port: 0 mask: 0xffff Dest port: 0 mask: 0xffff VLAN EtherType: 0x0 mask: 0xffff VLAN: 0x0 mask: 0xf000 User-defined: 0x1234 mask: 0x0 Action: Direct to queue 3
Fix it by return 0.
Fixes: 05c2314fe6a8 ("net: hns3: Add support for rule query of flow director") Signed-off-by: Jian Shen shenjian15@huawei.com Signed-off-by: Huazhong Tan tanhuazhong@huawei.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -6183,8 +6183,7 @@ static void hclge_fd_get_ext_info(struct fs->h_ext.vlan_tci = cpu_to_be16(rule->tuples.vlan_tag1); fs->m_ext.vlan_tci = rule->unused_tuple & BIT(INNER_VLAN_TAG_FST) ? - cpu_to_be16(VLAN_VID_MASK) : - cpu_to_be16(rule->tuples_mask.vlan_tag1); + 0 : cpu_to_be16(rule->tuples_mask.vlan_tag1); }
if (fs->flow_type & FLOW_MAC_EXT) {
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Jian Shen shenjian15@huawei.com
commit b36fc875bcdee56865c444a2cdae17d354a6d5f5 upstream.
The function hclge_fd_convert_tuple() is used to convert tuples and tuples mask to TCAM x and y. But it misuses the source mac as source mac mask when convert INNER_SRC_MAC, which may cause the flow director rule works unexpectedly. So fix it.
Fixes: 117328680288 ("net: hns3: Add input key and action config support for flow director") Signed-off-by: Jian Shen shenjian15@huawei.com Signed-off-by: Huazhong Tan tanhuazhong@huawei.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -5115,9 +5115,9 @@ static bool hclge_fd_convert_tuple(u32 t case BIT(INNER_SRC_MAC): for (i = 0; i < ETH_ALEN; i++) { calc_x(key_x[ETH_ALEN - 1 - i], rule->tuples.src_mac[i], - rule->tuples.src_mac[i]); + rule->tuples_mask.src_mac[i]); calc_y(key_y[ETH_ALEN - 1 - i], rule->tuples.src_mac[i], - rule->tuples.src_mac[i]); + rule->tuples_mask.src_mac[i]); }
return true;
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Wang Qing wangqing@vivo.com
commit 51c44babdc19aaf882e1213325a0ba291573308f upstream.
The copy_to_user() function returns the number of bytes remaining to be copied, but we want to return -EFAULT if the copy doesn't complete.
Fixes: e01bcdd61320 ("vfio: ccw: realize VFIO_DEVICE_GET_REGION_INFO ioctl") Signed-off-by: Wang Qing wangqing@vivo.com Signed-off-by: Heiko Carstens hca@linux.ibm.com Link: https://lore.kernel.org/r/1614600093-13992-1-git-send-email-wangqing@vivo.co... Signed-off-by: Heiko Carstens hca@linux.ibm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/s390/cio/vfio_ccw_ops.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/s390/cio/vfio_ccw_ops.c +++ b/drivers/s390/cio/vfio_ccw_ops.c @@ -539,7 +539,7 @@ static ssize_t vfio_ccw_mdev_ioctl(struc if (ret) return ret;
- return copy_to_user((void __user *)arg, &info, minsz); + return copy_to_user((void __user *)arg, &info, minsz) ? -EFAULT : 0; } case VFIO_DEVICE_GET_REGION_INFO: { @@ -557,7 +557,7 @@ static ssize_t vfio_ccw_mdev_ioctl(struc if (ret) return ret;
- return copy_to_user((void __user *)arg, &info, minsz); + return copy_to_user((void __user *)arg, &info, minsz) ? -EFAULT : 0; } case VFIO_DEVICE_GET_IRQ_INFO: {
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Edwin Peer edwin.peer@broadcom.com
commit 20d7d1c5c9b11e9f538ed4a2289be106de970d3e upstream.
The following trace excerpt corresponds with a NULL pointer dereference of 'bp->irq_tbl' in bnxt_setup_inta() on an Aarch64 system after many device resets:
Unable to handle kernel NULL pointer dereference at ... 000000d ... pc : string+0x3c/0x80 lr : vsnprintf+0x294/0x7e0 sp : ffff00000f61ba70 pstate : 20000145 x29: ffff00000f61ba70 x28: 000000000000000d x27: ffff0000009c8b5a x26: ffff00000f61bb80 x25: ffff0000009c8b5a x24: 0000000000000012 x23: 00000000ffffffe0 x22: ffff000008990428 x21: ffff00000f61bb80 x20: 000000000000000d x19: 000000000000001f x18: 0000000000000000 x17: 0000000000000000 x16: ffff800b6d0fb400 x15: 0000000000000000 x14: ffff800b7fe31ae8 x13: 00001ed16472c920 x12: ffff000008c6b1c9 x11: ffff000008cf0580 x10: ffff00000f61bb80 x9 : 00000000ffffffd8 x8 : 000000000000000c x7 : ffff800b684b8000 x6 : 0000000000000000 x5 : 0000000000000065 x4 : 0000000000000001 x3 : ffff0a00ffffff04 x2 : 000000000000001f x1 : 0000000000000000 x0 : 000000000000000d Call trace: string+0x3c/0x80 vsnprintf+0x294/0x7e0 snprintf+0x44/0x50 __bnxt_open_nic+0x34c/0x928 [bnxt_en] bnxt_open+0xe8/0x238 [bnxt_en] __dev_open+0xbc/0x130 __dev_change_flags+0x12c/0x168 dev_change_flags+0x20/0x60 ...
Ordinarily, a call to bnxt_setup_inta() (not in trace due to inlining) would not be expected on a system supporting MSIX at all. However, if bnxt_init_int_mode() does not end up being called after the call to bnxt_clear_int_mode() in bnxt_fw_reset_close(), then the driver will think that only INTA is supported and bp->irq_tbl will be NULL, causing the above crash.
In the error recovery scenario, we call bnxt_clear_int_mode() in bnxt_fw_reset_close() early in the sequence. Ordinarily, we will call bnxt_init_int_mode() in bnxt_hwrm_if_change() after we reestablish communication with the firmware after reset. However, if the sequence has to abort before we call bnxt_init_int_mode() and if the user later attempts to re-open the device, then it will cause the crash above.
We fix it in 2 ways:
1. Check for bp->irq_tbl in bnxt_setup_int_mode(). If it is NULL, call bnxt_init_init_mode().
2. If we need to abort in bnxt_hwrm_if_change() and cannot complete the error recovery sequence, set the BNXT_STATE_ABORT_ERR flag. This will cause more drastic recovery at the next attempt to re-open the device, including a call to bnxt_init_int_mode().
Fixes: 3bc7d4a352ef ("bnxt_en: Add BNXT_STATE_IN_FW_RESET state.") Reviewed-by: Scott Branden scott.branden@broadcom.com Signed-off-by: Edwin Peer edwin.peer@broadcom.com Signed-off-by: Michael Chan michael.chan@broadcom.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -8430,10 +8430,18 @@ static void bnxt_setup_inta(struct bnxt bp->irq_tbl[0].handler = bnxt_inta; }
+static int bnxt_init_int_mode(struct bnxt *bp); + static int bnxt_setup_int_mode(struct bnxt *bp) { int rc;
+ if (!bp->irq_tbl) { + rc = bnxt_init_int_mode(bp); + if (rc || !bp->irq_tbl) + return rc ?: -ENODEV; + } + if (bp->flags & BNXT_FLAG_USING_MSIX) bnxt_setup_msix(bp); else @@ -8618,7 +8626,7 @@ static int bnxt_init_inta(struct bnxt *b
static int bnxt_init_int_mode(struct bnxt *bp) { - int rc = 0; + int rc = -ENODEV;
if (bp->flags & BNXT_FLAG_MSIX_CAP) rc = bnxt_init_msix(bp); @@ -9339,7 +9347,8 @@ static int bnxt_hwrm_if_change(struct bn { struct hwrm_func_drv_if_change_output *resp = bp->hwrm_cmd_resp_addr; struct hwrm_func_drv_if_change_input req = {0}; - bool resc_reinit = false, fw_reset = false; + bool fw_reset = !bp->irq_tbl; + bool resc_reinit = false; u32 flags = 0; int rc;
@@ -9367,6 +9376,7 @@ static int bnxt_hwrm_if_change(struct bn
if (test_bit(BNXT_STATE_IN_FW_RESET, &bp->state) && !fw_reset) { netdev_err(bp->dev, "RESET_DONE not set during FW reset.\n"); + set_bit(BNXT_STATE_ABORT_ERR, &bp->state); return -ENODEV; } if (resc_reinit || fw_reset) {
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Andy Shevchenko andriy.shevchenko@linux.intel.com
commit 62d5247d239d4b48762192a251c647d7c997616a upstream.
On some systems the ACPI tables has wrong pin number and instead of having a relative one it provides an absolute one in the global GPIO number space.
Add ACPI_GPIO_QUIRK_ABSOLUTE_NUMBER quirk to cope with such cases.
Fixes: ba8c90c61847 ("gpio: pca953x: Override IRQ for one of the expanders on Galileo Gen 2") Depends-on: 0ea683931adb ("gpio: dwapb: Convert driver to using the GPIO-lib-based IRQ-chip") Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Acked-by: Mika Westerberg mika.westerberg@linux.intel.com Acked-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpio/gpiolib-acpi.c | 7 ++++++- include/linux/gpio/consumer.h | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-)
--- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -649,6 +649,7 @@ static int acpi_populate_gpio_lookup(str if (!lookup->desc) { const struct acpi_resource_gpio *agpio = &ares->data.gpio; bool gpioint = agpio->connection_type == ACPI_RESOURCE_GPIO_TYPE_INT; + struct gpio_desc *desc; int pin_index;
if (lookup->info.quirks & ACPI_GPIO_QUIRK_ONLY_GPIOIO && gpioint) @@ -661,8 +662,12 @@ static int acpi_populate_gpio_lookup(str if (pin_index >= agpio->pin_table_length) return 1;
- lookup->desc = acpi_get_gpiod(agpio->resource_source.string_ptr, + if (lookup->info.quirks & ACPI_GPIO_QUIRK_ABSOLUTE_NUMBER) + desc = gpio_to_desc(agpio->pin_table[pin_index]); + else + desc = acpi_get_gpiod(agpio->resource_source.string_ptr, agpio->pin_table[pin_index]); + lookup->desc = desc; lookup->info.pin_config = agpio->pin_config; lookup->info.gpioint = gpioint;
--- a/include/linux/gpio/consumer.h +++ b/include/linux/gpio/consumer.h @@ -674,6 +674,8 @@ struct acpi_gpio_mapping { * get GpioIo type explicitly, this quirk may be used. */ #define ACPI_GPIO_QUIRK_ONLY_GPIOIO BIT(1) +/* Use given pin as an absolute GPIO number in the system */ +#define ACPI_GPIO_QUIRK_ABSOLUTE_NUMBER BIT(2)
unsigned int quirks; };
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Andy Shevchenko andriy.shevchenko@linux.intel.com
commit 809390219fb9c2421239afe5c9eb862d73978ba0 upstream.
Currently only search by index is supported. However, in some cases we might need to pass the quirks to the acpi_dev_gpio_irq_get().
For this, split out acpi_dev_gpio_irq_get_by() and replace acpi_dev_gpio_irq_get() by calling above with NULL for name parameter.
Fixes: ba8c90c61847 ("gpio: pca953x: Override IRQ for one of the expanders on Galileo Gen 2") Depends-on: 0ea683931adb ("gpio: dwapb: Convert driver to using the GPIO-lib-based IRQ-chip") Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Acked-by: Mika Westerberg mika.westerberg@linux.intel.com Acked-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpio/gpiolib-acpi.c | 12 ++++++++---- include/linux/acpi.h | 10 ++++++++-- 2 files changed, 16 insertions(+), 6 deletions(-)
--- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -916,8 +916,9 @@ struct gpio_desc *acpi_node_get_gpiod(st }
/** - * acpi_dev_gpio_irq_get() - Find GpioInt and translate it to Linux IRQ number + * acpi_dev_gpio_irq_get_by() - Find GpioInt and translate it to Linux IRQ number * @adev: pointer to a ACPI device to get IRQ from + * @name: optional name of GpioInt resource * @index: index of GpioInt resource (starting from %0) * * If the device has one or more GpioInt resources, this function can be @@ -927,9 +928,12 @@ struct gpio_desc *acpi_node_get_gpiod(st * The function is idempotent, though each time it runs it will configure GPIO * pin direction according to the flags in GpioInt resource. * + * The function takes optional @name parameter. If the resource has a property + * name, then only those will be taken into account. + * * Return: Linux IRQ number (> %0) on success, negative errno on failure. */ -int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index) +int acpi_dev_gpio_irq_get_by(struct acpi_device *adev, const char *name, int index) { int idx, i; unsigned int irq_flags; @@ -939,7 +943,7 @@ int acpi_dev_gpio_irq_get(struct acpi_de struct acpi_gpio_info info; struct gpio_desc *desc;
- desc = acpi_get_gpiod_by_index(adev, NULL, i, &info); + desc = acpi_get_gpiod_by_index(adev, name, i, &info);
/* Ignore -EPROBE_DEFER, it only matters if idx matches */ if (IS_ERR(desc) && PTR_ERR(desc) != -EPROBE_DEFER) @@ -976,7 +980,7 @@ int acpi_dev_gpio_irq_get(struct acpi_de } return -ENOENT; } -EXPORT_SYMBOL_GPL(acpi_dev_gpio_irq_get); +EXPORT_SYMBOL_GPL(acpi_dev_gpio_irq_get_by);
static acpi_status acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address, --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -1072,19 +1072,25 @@ void __acpi_handle_debug(struct _ddebug #if defined(CONFIG_ACPI) && defined(CONFIG_GPIOLIB) bool acpi_gpio_get_irq_resource(struct acpi_resource *ares, struct acpi_resource_gpio **agpio); -int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index); +int acpi_dev_gpio_irq_get_by(struct acpi_device *adev, const char *name, int index); #else static inline bool acpi_gpio_get_irq_resource(struct acpi_resource *ares, struct acpi_resource_gpio **agpio) { return false; } -static inline int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index) +static inline int acpi_dev_gpio_irq_get_by(struct acpi_device *adev, + const char *name, int index) { return -ENXIO; } #endif
+static inline int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index) +{ + return acpi_dev_gpio_irq_get_by(adev, NULL, index); +} + /* Device properties */
#ifdef CONFIG_ACPI
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Andy Shevchenko andriy.shevchenko@linux.intel.com
commit b41ba2ec54a70908067034f139aa23d0dd2985ce upstream.
On STM32MP1, the GPIO banks are subnodes of pin-controller@50002000, see arch/arm/boot/dts/stm32mp151.dtsi. The driver for pin-controller@50002000 is in drivers/pinctrl/stm32/pinctrl-stm32.c and iterates over all of its DT subnodes when registering each GPIO bank gpiochip. Each gpiochip has:
- gpio_chip.parent = dev, where dev is the device node of the pin controller - gpio_chip.of_node = np, which is the OF node of the GPIO bank
Therefore, dev_fwnode(chip->parent) != of_fwnode_handle(chip.of_node), i.e. pin-controller@50002000 != pin-controller@50002000/gpio@5000*000.
The original code behaved correctly, as it extracted the "gpio-line-names" from of_fwnode_handle(chip.of_node) = pin-controller@50002000/gpio@5000*000.
To achieve the same behaviour, read property from the firmware node.
Fixes: 7cba1a4d5e162 ("gpiolib: generalize devprop_gpiochip_set_names() for device properties") Reported-by: Marek Vasut marex@denx.de Reported-by: Roman Guskov rguskov@dh-electronics.com Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Tested-by: Marek Vasut marex@denx.de Reviewed-by: Marek Vasut marex@denx.de Signed-off-by: Bartosz Golaszewski bgolaszewski@baylibre.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpio/gpiolib.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-)
--- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -364,22 +364,18 @@ static int gpiochip_set_desc_names(struc * * Looks for device property "gpio-line-names" and if it exists assigns * GPIO line names for the chip. The memory allocated for the assigned - * names belong to the underlying software node and should not be released + * names belong to the underlying firmware node and should not be released * by the caller. */ static int devprop_gpiochip_set_names(struct gpio_chip *chip) { struct gpio_device *gdev = chip->gpiodev; - struct device *dev = chip->parent; + struct fwnode_handle *fwnode = dev_fwnode(&gdev->dev); const char **names; int ret, i; int count;
- /* GPIO chip may not have a parent device whose properties we inspect. */ - if (!dev) - return 0; - - count = device_property_string_array_count(dev, "gpio-line-names"); + count = fwnode_property_string_array_count(fwnode, "gpio-line-names"); if (count < 0) return 0;
@@ -393,7 +389,7 @@ static int devprop_gpiochip_set_names(st if (!names) return -ENOMEM;
- ret = device_property_read_string_array(dev, "gpio-line-names", + ret = fwnode_property_read_string_array(fwnode, "gpio-line-names", names, count); if (ret < 0) { dev_warn(&gdev->dev, "failed to read GPIO line names\n");
On 3/15/21 2:52 PM, gregkh@linuxfoundation.org wrote:
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Andy Shevchenko andriy.shevchenko@linux.intel.com
commit b41ba2ec54a70908067034f139aa23d0dd2985ce upstream.
On STM32MP1, the GPIO banks are subnodes of pin-controller@50002000, see arch/arm/boot/dts/stm32mp151.dtsi. The driver for pin-controller@50002000 is in drivers/pinctrl/stm32/pinctrl-stm32.c and iterates over all of its DT subnodes when registering each GPIO bank gpiochip. Each gpiochip has:
- gpio_chip.parent = dev, where dev is the device node of the pin controller
- gpio_chip.of_node = np, which is the OF node of the GPIO bank
Therefore, dev_fwnode(chip->parent) != of_fwnode_handle(chip.of_node), i.e. pin-controller@50002000 != pin-controller@50002000/gpio@5000*000.
The original code behaved correctly, as it extracted the "gpio-line-names" from of_fwnode_handle(chip.of_node) = pin-controller@50002000/gpio@5000*000.
To achieve the same behaviour, read property from the firmware node.
There seem to be some discussion going on around this patch, so please postpone backporting until that is settled. Same for v5.11 backport. I hope Andy/Bartosz agrees ?
On Mon, Mar 15, 2021 at 4:01 PM Marek Vasut marex@denx.de wrote:
On 3/15/21 2:52 PM, gregkh@linuxfoundation.org wrote:
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Andy Shevchenko andriy.shevchenko@linux.intel.com
commit b41ba2ec54a70908067034f139aa23d0dd2985ce upstream.
On STM32MP1, the GPIO banks are subnodes of pin-controller@50002000, see arch/arm/boot/dts/stm32mp151.dtsi. The driver for pin-controller@50002000 is in drivers/pinctrl/stm32/pinctrl-stm32.c and iterates over all of its DT subnodes when registering each GPIO bank gpiochip. Each gpiochip has:
- gpio_chip.parent = dev, where dev is the device node of the pin controller
- gpio_chip.of_node = np, which is the OF node of the GPIO bank
Therefore, dev_fwnode(chip->parent) != of_fwnode_handle(chip.of_node), i.e. pin-controller@50002000 != pin-controller@50002000/gpio@5000*000.
The original code behaved correctly, as it extracted the "gpio-line-names" from of_fwnode_handle(chip.of_node) = pin-controller@50002000/gpio@5000*000.
To achieve the same behaviour, read property from the firmware node.
There seem to be some discussion going on around this patch, so please postpone backporting until that is settled. Same for v5.11 backport. I hope Andy/Bartosz agrees ?
Yes, this patch broke at least the testing module and we're working to determine if it breaks DT drivers too.
Bart
On Mon, Mar 15, 2021 at 05:32:09PM +0100, Bartosz Golaszewski wrote:
On Mon, Mar 15, 2021 at 4:01 PM Marek Vasut marex@denx.de wrote:
On 3/15/21 2:52 PM, gregkh@linuxfoundation.org wrote:
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Andy Shevchenko andriy.shevchenko@linux.intel.com
commit b41ba2ec54a70908067034f139aa23d0dd2985ce upstream.
On STM32MP1, the GPIO banks are subnodes of pin-controller@50002000, see arch/arm/boot/dts/stm32mp151.dtsi. The driver for pin-controller@50002000 is in drivers/pinctrl/stm32/pinctrl-stm32.c and iterates over all of its DT subnodes when registering each GPIO bank gpiochip. Each gpiochip has:
- gpio_chip.parent = dev, where dev is the device node of the pin controller
- gpio_chip.of_node = np, which is the OF node of the GPIO bank
Therefore, dev_fwnode(chip->parent) != of_fwnode_handle(chip.of_node), i.e. pin-controller@50002000 != pin-controller@50002000/gpio@5000*000.
The original code behaved correctly, as it extracted the "gpio-line-names" from of_fwnode_handle(chip.of_node) = pin-controller@50002000/gpio@5000*000.
To achieve the same behaviour, read property from the firmware node.
There seem to be some discussion going on around this patch, so please postpone backporting until that is settled. Same for v5.11 backport. I hope Andy/Bartosz agrees ?
Yes, this patch broke at least the testing module and we're working to determine if it breaks DT drivers too.
Now dropped, thanks.
greg k-h
On Mon, Mar 15, 2021 at 5:05 PM Marek Vasut marex@denx.de wrote:
On 3/15/21 2:52 PM, gregkh@linuxfoundation.org wrote:
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Andy Shevchenko andriy.shevchenko@linux.intel.com
commit b41ba2ec54a70908067034f139aa23d0dd2985ce upstream.
On STM32MP1, the GPIO banks are subnodes of pin-controller@50002000, see arch/arm/boot/dts/stm32mp151.dtsi. The driver for pin-controller@50002000 is in drivers/pinctrl/stm32/pinctrl-stm32.c and iterates over all of its DT subnodes when registering each GPIO bank gpiochip. Each gpiochip has:
- gpio_chip.parent = dev, where dev is the device node of the pin controller
- gpio_chip.of_node = np, which is the OF node of the GPIO bank
Therefore, dev_fwnode(chip->parent) != of_fwnode_handle(chip.of_node), i.e. pin-controller@50002000 != pin-controller@50002000/gpio@5000*000.
The original code behaved correctly, as it extracted the "gpio-line-names" from of_fwnode_handle(chip.of_node) = pin-controller@50002000/gpio@5000*000.
To achieve the same behaviour, read property from the firmware node.
There seem to be some discussion going on around this patch, so please postpone backporting until that is settled. Same for v5.11 backport. I hope Andy/Bartosz agrees ?
No need to postpone. The fix will be somewhere else, though inside gpiolib.c.
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Andy Shevchenko andriy.shevchenko@linux.intel.com
commit eb441337c7147514ab45036cadf09c3a71e4ce31 upstream.
The commit 0ea683931adb ("gpio: dwapb: Convert driver to using the GPIO-lib-based IRQ-chip") indeliberately made a regression on how IRQ line from GPIO I²C expander is handled. I.e. it reveals that the quirk for Intel Galileo Gen 2 misses the part of setting IRQ type which previously was predefined by gpio-dwapb driver. Now, we have to reorganize the approach to call necessary parts, which can be done via ACPI_GPIO_QUIRK_ABSOLUTE_NUMBER quirk.
Without this fix and with above mentioned change the kernel hangs on the first IRQ event with:
gpio gpiochip3: Persistence not supported for GPIO 1 irq 32, desc: 62f8fb50, depth: 0, count: 0, unhandled: 0 ->handle_irq(): 41c7b0ab, handle_bad_irq+0x0/0x40 ->irq_data.chip(): e03f1e72, 0xc2539218 ->action(): 0ecc7e6f ->action->handler(): 8a3db21e, irq_default_primary_handler+0x0/0x10 IRQ_NOPROBE set unexpected IRQ trap at vector 20
Fixes: ba8c90c61847 ("gpio: pca953x: Override IRQ for one of the expanders on Galileo Gen 2") Depends-on: 0ea683931adb ("gpio: dwapb: Convert driver to using the GPIO-lib-based IRQ-chip") Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Acked-by: Mika Westerberg mika.westerberg@linux.intel.com Reviewed-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpio/gpio-pca953x.c | 78 ++++++++++++-------------------------------- 1 file changed, 23 insertions(+), 55 deletions(-)
--- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -112,8 +112,29 @@ MODULE_DEVICE_TABLE(i2c, pca953x_id); #ifdef CONFIG_GPIO_PCA953X_IRQ
#include <linux/dmi.h> -#include <linux/gpio.h> -#include <linux/list.h> + +static const struct acpi_gpio_params pca953x_irq_gpios = { 0, 0, true }; + +static const struct acpi_gpio_mapping pca953x_acpi_irq_gpios[] = { + { "irq-gpios", &pca953x_irq_gpios, 1, ACPI_GPIO_QUIRK_ABSOLUTE_NUMBER }, + { } +}; + +static int pca953x_acpi_get_irq(struct device *dev) +{ + int ret; + + ret = devm_acpi_dev_add_driver_gpios(dev, pca953x_acpi_irq_gpios); + if (ret) + dev_warn(dev, "can't add GPIO ACPI mapping\n"); + + ret = acpi_dev_gpio_irq_get_by(ACPI_COMPANION(dev), "irq-gpios", 0); + if (ret < 0) + return ret; + + dev_info(dev, "ACPI interrupt quirk (IRQ %d)\n", ret); + return ret; +}
static const struct dmi_system_id pca953x_dmi_acpi_irq_info[] = { { @@ -132,59 +153,6 @@ static const struct dmi_system_id pca953 }, {} }; - -#ifdef CONFIG_ACPI -static int pca953x_acpi_get_pin(struct acpi_resource *ares, void *data) -{ - struct acpi_resource_gpio *agpio; - int *pin = data; - - if (acpi_gpio_get_irq_resource(ares, &agpio)) - *pin = agpio->pin_table[0]; - return 1; -} - -static int pca953x_acpi_find_pin(struct device *dev) -{ - struct acpi_device *adev = ACPI_COMPANION(dev); - int pin = -ENOENT, ret; - LIST_HEAD(r); - - ret = acpi_dev_get_resources(adev, &r, pca953x_acpi_get_pin, &pin); - acpi_dev_free_resource_list(&r); - if (ret < 0) - return ret; - - return pin; -} -#else -static inline int pca953x_acpi_find_pin(struct device *dev) { return -ENXIO; } -#endif - -static int pca953x_acpi_get_irq(struct device *dev) -{ - int pin, ret; - - pin = pca953x_acpi_find_pin(dev); - if (pin < 0) - return pin; - - dev_info(dev, "Applying ACPI interrupt quirk (GPIO %d)\n", pin); - - if (!gpio_is_valid(pin)) - return -EINVAL; - - ret = gpio_request(pin, "pca953x interrupt"); - if (ret) - return ret; - - ret = gpio_to_irq(pin); - - /* When pin is used as an IRQ, no need to keep it requested */ - gpio_free(pin); - - return ret; -} #endif
static const struct acpi_device_id pca953x_acpi_ids[] = {
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Johan Hovold johan@kernel.org
commit cf25ef6b631c6fc6c0435fc91eba8734cca20511 upstream.
Make sure to hold the gpio_lock when removing the gpio device from the gpio_devices list (when dropping the last reference) to avoid corrupting the list when there are concurrent accesses.
Fixes: ff2b13592299 ("gpio: make the gpiochip a real device") Cc: stable@vger.kernel.org # 4.6 Reviewed-by: Saravana Kannan saravanak@google.com Signed-off-by: Johan Hovold johan@kernel.org Signed-off-by: Bartosz Golaszewski bgolaszewski@baylibre.com [ johan: adjust context to 5.11 ] Signed-off-by: Johan Hovold johan@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpio/gpiolib.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -468,8 +468,12 @@ EXPORT_SYMBOL_GPL(gpiochip_line_is_valid static void gpiodevice_release(struct device *dev) { struct gpio_device *gdev = dev_get_drvdata(dev); + unsigned long flags;
+ spin_lock_irqsave(&gpio_lock, flags); list_del(&gdev->list); + spin_unlock_irqrestore(&gpio_lock, flags); + ida_free(&gpio_ida, gdev->id); kfree_const(gdev->label); kfree(gdev->descs);
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Daniel Vetter daniel.vetter@ffwll.ch
commit de066e116306baf3a6a62691ac63cfc0b1dabddb upstream.
Some of them have gaps, or fields we don't clear. Native ioctl code does full copies plus zero-extends on size mismatch, so nothing can leak. But compat is more hand-rolled so need to be careful.
None of these matter for performance, so just memset.
Also I didn't fix up the CONFIG_DRM_LEGACY or CONFIG_DRM_AGP ioctl, those are security holes anyway.
Acked-by: Maxime Ripard mripard@kernel.org Reported-by: syzbot+620cf21140fc7e772a5d@syzkaller.appspotmail.com # vblank ioctl Cc: syzbot+620cf21140fc7e772a5d@syzkaller.appspotmail.com Cc: stable@vger.kernel.org Signed-off-by: Daniel Vetter daniel.vetter@intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20210222100643.400935-1-daniel... (cherry picked from commit e926c474ebee404441c838d18224cd6f246a71b7) Signed-off-by: Maarten Lankhorst maarten.lankhorst@linux.intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/drm_ioc32.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
--- a/drivers/gpu/drm/drm_ioc32.c +++ b/drivers/gpu/drm/drm_ioc32.c @@ -99,6 +99,8 @@ static int compat_drm_version(struct fil if (copy_from_user(&v32, (void __user *)arg, sizeof(v32))) return -EFAULT;
+ memset(&v, 0, sizeof(v)); + v = (struct drm_version) { .name_len = v32.name_len, .name = compat_ptr(v32.name), @@ -137,6 +139,9 @@ static int compat_drm_getunique(struct f
if (copy_from_user(&uq32, (void __user *)arg, sizeof(uq32))) return -EFAULT; + + memset(&uq, 0, sizeof(uq)); + uq = (struct drm_unique){ .unique_len = uq32.unique_len, .unique = compat_ptr(uq32.unique), @@ -265,6 +270,8 @@ static int compat_drm_getclient(struct f if (copy_from_user(&c32, argp, sizeof(c32))) return -EFAULT;
+ memset(&client, 0, sizeof(client)); + client.idx = c32.idx;
err = drm_ioctl_kernel(file, drm_getclient, &client, 0); @@ -852,6 +859,8 @@ static int compat_drm_wait_vblank(struct if (copy_from_user(&req32, argp, sizeof(req32))) return -EFAULT;
+ memset(&req, 0, sizeof(req)); + req.request.type = req32.request.type; req.request.sequence = req32.request.sequence; req.request.signal = req32.request.signal; @@ -889,6 +898,8 @@ static int compat_drm_mode_addfb2(struct struct drm_mode_fb_cmd2 req64; int err;
+ memset(&req64, 0, sizeof(req64)); + if (copy_from_user(&req64, argp, offsetof(drm_mode_fb_cmd232_t, modifier))) return -EFAULT;
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Takashi Iwai tiwai@suse.de
commit 7a46f05e5e163c00e41892e671294286e53fe15c upstream.
There seem devices that don't work with the aux channel backlight control. For allowing such users to test with the other backlight control method, provide a new module option, aux_backlight, to specify enabling or disabling the aux backport support explicitly. As default, the aux support is detected by the hardware capability.
v2: make the backlight option generic in case we add future backlight types (Alex)
BugLink: https://bugzilla.opensuse.org/show_bug.cgi?id=1180749 BugLink: https://gitlab.freedesktop.org/drm/amd/-/issues/1438 Reviewed-by: Nicholas Kazlauskas nicholas.kazlauskas@amd.com Signed-off-by: Takashi Iwai tiwai@suse.de 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/amdgpu/amdgpu.h | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 4 ++++ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 5 +++++ 3 files changed, 10 insertions(+)
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -178,6 +178,7 @@ extern uint amdgpu_smu_memory_pool_size; extern uint amdgpu_dc_feature_mask; extern uint amdgpu_dc_debug_mask; extern uint amdgpu_dm_abm_level; +extern int amdgpu_backlight; extern struct amdgpu_mgpu_info mgpu_info; extern int amdgpu_ras_enable; extern uint amdgpu_ras_mask; --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -768,6 +768,10 @@ uint amdgpu_dm_abm_level = 0; MODULE_PARM_DESC(abmlevel, "ABM level (0 = off (default), 1-4 = backlight reduction level) "); module_param_named(abmlevel, amdgpu_dm_abm_level, uint, 0444);
+int amdgpu_backlight = -1; +MODULE_PARM_DESC(backlight, "Backlight control (0 = pwm, 1 = aux, -1 auto (default))"); +module_param_named(backlight, amdgpu_backlight, bint, 0444); + /** * DOC: tmz (int) * Trusted Memory Zone (TMZ) is a method to protect data being written --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -2140,6 +2140,11 @@ static void update_connector_ext_caps(st caps->ext_caps->bits.hdr_aux_backlight_control == 1) caps->aux_support = true;
+ if (amdgpu_backlight == 0) + caps->aux_support = false; + else if (amdgpu_backlight == 1) + caps->aux_support = true; + /* From the specification (CTA-861-G), for calculating the maximum * luminance we need to use: * Luminance = 50*2**(CV/32)
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Holger Hoffstätte holger@applied-asynchrony.com
commit 680174cfd1e1cea70a8f30ccb44d8fbdf996018e upstream.
After fixing nested FPU contexts caused by 41401ac67791 we're still seeing complaints about spurious kernel_fpu_end(). As it turns out this was already fixed for dcn20 in commit f41ed88cbd ("drm/amdgpu/display: use GFP_ATOMIC in dcn20_validate_bandwidth_internal") but never moved forward to dcn21.
Signed-off-by: Holger Hoffstätte holger@applied-asynchrony.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/dc/dcn21/dcn21_resource.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c @@ -1183,7 +1183,7 @@ static noinline bool dcn21_validate_band int vlevel = 0; int pipe_split_from[MAX_PIPES]; int pipe_cnt = 0; - display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st), GFP_KERNEL); + display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st), GFP_ATOMIC); DC_LOGGER_INIT(dc->ctx->logger);
BW_VAL_TRACE_COUNT();
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Holger Hoffstätte holger@applied-asynchrony.com
commit 15e8b95d5f7509e0b09289be8c422c459c9f0412 upstream.
Commit 41401ac67791 added FPU wrappers to dcn21_validate_bandwidth(), which was correct. Unfortunately a nested function alredy contained DC_FP_START()/DC_FP_END() calls, which results in nested FPU context enter/exit and complaints by kernel_fpu_begin_mask(). This can be observed e.g. with 5.10.20, which backported 41401ac67791 and now emits the following warning on boot:
WARNING: CPU: 6 PID: 858 at arch/x86/kernel/fpu/core.c:129 kernel_fpu_begin_mask+0xa5/0xc0 Call Trace: dcn21_calculate_wm+0x47/0xa90 [amdgpu] dcn21_validate_bandwidth_fp+0x15d/0x2b0 [amdgpu] dcn21_validate_bandwidth+0x29/0x40 [amdgpu] dc_validate_global_state+0x3c7/0x4c0 [amdgpu]
The warning is emitted due to the additional DC_FP_START/END calls in patch_bounding_box(), which is inlined into dcn21_calculate_wm(), its only caller. Removing the calls brings the code in line with dcn20 and makes the warning disappear.
Fixes: 41401ac67791 ("drm/amd/display: Add FPU wrappers to dcn21_validate_bandwidth()") Signed-off-by: Holger Hoffstätte holger@applied-asynchrony.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/dc/dcn21/dcn21_resource.c | 4 ---- 1 file changed, 4 deletions(-)
--- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c @@ -1058,8 +1058,6 @@ static void patch_bounding_box(struct dc { int i;
- DC_FP_START(); - if (dc->bb_overrides.sr_exit_time_ns) { for (i = 0; i < WM_SET_COUNT; i++) { dc->clk_mgr->bw_params->wm_table.entries[i].sr_exit_time_us = @@ -1084,8 +1082,6 @@ static void patch_bounding_box(struct dc dc->bb_overrides.dram_clock_change_latency_ns / 1000.0; } } - - DC_FP_END(); }
void dcn21_calculate_wm(
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Kenneth Feng kenneth.feng@amd.com
commit 50ceb1fe7acd50831180f4b5597bf7b39e8059c8 upstream.
Currently the pcie dpm has two problems. 1. Only the high dpm level speed/width can be overrided if the requested values are out of the pcie capability. 2. The high dpm level is always overrided though sometimes it's not necesarry.
Signed-off-by: Kenneth Feng kenneth.feng@amd.com Reviewed-by: Alex Deucher alexander.deucher@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/pm/powerplay/hwmgr/vega10_hwmgr.c | 48 +++++++++++++ drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c | 66 ++++++++++++++++++ drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c | 48 +++++++------ 3 files changed, 141 insertions(+), 21 deletions(-)
--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c @@ -1506,6 +1506,48 @@ static int vega10_populate_single_lclk_l return 0; }
+static int vega10_override_pcie_parameters(struct pp_hwmgr *hwmgr) +{ + struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev); + struct vega10_hwmgr *data = + (struct vega10_hwmgr *)(hwmgr->backend); + uint32_t pcie_gen = 0, pcie_width = 0; + PPTable_t *pp_table = &(data->smc_state_table.pp_table); + int i; + + if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4) + pcie_gen = 3; + else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) + pcie_gen = 2; + else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2) + pcie_gen = 1; + else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1) + pcie_gen = 0; + + if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X16) + pcie_width = 6; + else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X12) + pcie_width = 5; + else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X8) + pcie_width = 4; + else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X4) + pcie_width = 3; + else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X2) + pcie_width = 2; + else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X1) + pcie_width = 1; + + for (i = 0; i < NUM_LINK_LEVELS; i++) { + if (pp_table->PcieGenSpeed[i] > pcie_gen) + pp_table->PcieGenSpeed[i] = pcie_gen; + + if (pp_table->PcieLaneCount[i] > pcie_width) + pp_table->PcieLaneCount[i] = pcie_width; + } + + return 0; +} + static int vega10_populate_smc_link_levels(struct pp_hwmgr *hwmgr) { int result = -1; @@ -2557,6 +2599,11 @@ static int vega10_init_smc_table(struct "Failed to initialize Link Level!", return result);
+ result = vega10_override_pcie_parameters(hwmgr); + PP_ASSERT_WITH_CODE(!result, + "Failed to override pcie parameters!", + return result); + result = vega10_populate_all_graphic_levels(hwmgr); PP_ASSERT_WITH_CODE(!result, "Failed to initialize Graphics Level!", @@ -2923,6 +2970,7 @@ static int vega10_start_dpm(struct pp_hw return 0; }
+ static int vega10_enable_disable_PCC_limit_feature(struct pp_hwmgr *hwmgr, bool enable) { struct vega10_hwmgr *data = hwmgr->backend; --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c @@ -481,6 +481,67 @@ static void vega12_init_dpm_state(struct dpm_state->hard_max_level = 0xffff; }
+static int vega12_override_pcie_parameters(struct pp_hwmgr *hwmgr) +{ + struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev); + struct vega12_hwmgr *data = + (struct vega12_hwmgr *)(hwmgr->backend); + uint32_t pcie_gen = 0, pcie_width = 0, smu_pcie_arg, pcie_gen_arg, pcie_width_arg; + PPTable_t *pp_table = &(data->smc_state_table.pp_table); + int i; + int ret; + + if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4) + pcie_gen = 3; + else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) + pcie_gen = 2; + else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2) + pcie_gen = 1; + else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN1) + pcie_gen = 0; + + if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X16) + pcie_width = 6; + else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X12) + pcie_width = 5; + else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X8) + pcie_width = 4; + else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X4) + pcie_width = 3; + else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X2) + pcie_width = 2; + else if (adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X1) + pcie_width = 1; + + /* Bit 31:16: LCLK DPM level. 0 is DPM0, and 1 is DPM1 + * Bit 15:8: PCIE GEN, 0 to 3 corresponds to GEN1 to GEN4 + * Bit 7:0: PCIE lane width, 1 to 7 corresponds is x1 to x32 + */ + for (i = 0; i < NUM_LINK_LEVELS; i++) { + pcie_gen_arg = (pp_table->PcieGenSpeed[i] > pcie_gen) ? pcie_gen : + pp_table->PcieGenSpeed[i]; + pcie_width_arg = (pp_table->PcieLaneCount[i] > pcie_width) ? pcie_width : + pp_table->PcieLaneCount[i]; + + if (pcie_gen_arg != pp_table->PcieGenSpeed[i] || pcie_width_arg != + pp_table->PcieLaneCount[i]) { + smu_pcie_arg = (i << 16) | (pcie_gen_arg << 8) | pcie_width_arg; + ret = smum_send_msg_to_smc_with_parameter(hwmgr, + PPSMC_MSG_OverridePcieParameters, smu_pcie_arg, + NULL); + PP_ASSERT_WITH_CODE(!ret, + "[OverridePcieParameters] Attempt to override pcie params failed!", + return ret); + } + + /* update the pptable */ + pp_table->PcieGenSpeed[i] = pcie_gen_arg; + pp_table->PcieLaneCount[i] = pcie_width_arg; + } + + return 0; +} + static int vega12_get_number_of_dpm_level(struct pp_hwmgr *hwmgr, PPCLK_e clk_id, uint32_t *num_of_levels) { @@ -969,6 +1030,11 @@ static int vega12_enable_dpm_tasks(struc "Failed to enable all smu features!", return result);
+ result = vega12_override_pcie_parameters(hwmgr); + PP_ASSERT_WITH_CODE(!result, + "[EnableDPMTasks] Failed to override pcie parameters!", + return result); + tmp_result = vega12_power_control_set_level(hwmgr); PP_ASSERT_WITH_CODE(!tmp_result, "Failed to power control set level!", --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c @@ -832,7 +832,9 @@ static int vega20_override_pcie_paramete struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev); struct vega20_hwmgr *data = (struct vega20_hwmgr *)(hwmgr->backend); - uint32_t pcie_gen = 0, pcie_width = 0, smu_pcie_arg; + uint32_t pcie_gen = 0, pcie_width = 0, smu_pcie_arg, pcie_gen_arg, pcie_width_arg; + PPTable_t *pp_table = &(data->smc_state_table.pp_table); + int i; int ret;
if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN4) @@ -861,17 +863,27 @@ static int vega20_override_pcie_paramete * Bit 15:8: PCIE GEN, 0 to 3 corresponds to GEN1 to GEN4 * Bit 7:0: PCIE lane width, 1 to 7 corresponds is x1 to x32 */ - smu_pcie_arg = (1 << 16) | (pcie_gen << 8) | pcie_width; - ret = smum_send_msg_to_smc_with_parameter(hwmgr, - PPSMC_MSG_OverridePcieParameters, smu_pcie_arg, - NULL); - PP_ASSERT_WITH_CODE(!ret, - "[OverridePcieParameters] Attempt to override pcie params failed!", - return ret); + for (i = 0; i < NUM_LINK_LEVELS; i++) { + pcie_gen_arg = (pp_table->PcieGenSpeed[i] > pcie_gen) ? pcie_gen : + pp_table->PcieGenSpeed[i]; + pcie_width_arg = (pp_table->PcieLaneCount[i] > pcie_width) ? pcie_width : + pp_table->PcieLaneCount[i]; + + if (pcie_gen_arg != pp_table->PcieGenSpeed[i] || pcie_width_arg != + pp_table->PcieLaneCount[i]) { + smu_pcie_arg = (i << 16) | (pcie_gen_arg << 8) | pcie_width_arg; + ret = smum_send_msg_to_smc_with_parameter(hwmgr, + PPSMC_MSG_OverridePcieParameters, smu_pcie_arg, + NULL); + PP_ASSERT_WITH_CODE(!ret, + "[OverridePcieParameters] Attempt to override pcie params failed!", + return ret); + }
- data->pcie_parameters_override = true; - data->pcie_gen_level1 = pcie_gen; - data->pcie_width_level1 = pcie_width; + /* update the pptable */ + pp_table->PcieGenSpeed[i] = pcie_gen_arg; + pp_table->PcieLaneCount[i] = pcie_width_arg; + }
return 0; } @@ -3320,9 +3332,7 @@ static int vega20_print_clock_levels(str data->od8_settings.od8_settings_array; OverDriveTable_t *od_table = &(data->smc_state_table.overdrive_table); - struct phm_ppt_v3_information *pptable_information = - (struct phm_ppt_v3_information *)hwmgr->pptable; - PPTable_t *pptable = (PPTable_t *)pptable_information->smc_pptable; + PPTable_t *pptable = &(data->smc_state_table.pp_table); struct pp_clock_levels_with_latency clocks; struct vega20_single_dpm_table *fclk_dpm_table = &(data->dpm_table.fclk_table); @@ -3421,13 +3431,9 @@ static int vega20_print_clock_levels(str current_lane_width = vega20_get_current_pcie_link_width_level(hwmgr); for (i = 0; i < NUM_LINK_LEVELS; i++) { - if (i == 1 && data->pcie_parameters_override) { - gen_speed = data->pcie_gen_level1; - lane_width = data->pcie_width_level1; - } else { - gen_speed = pptable->PcieGenSpeed[i]; - lane_width = pptable->PcieLaneCount[i]; - } + gen_speed = pptable->PcieGenSpeed[i]; + lane_width = pptable->PcieLaneCount[i]; + size += sprintf(buf + size, "%d: %s %s %dMhz %s\n", i, (gen_speed == 0) ? "2.5GT/s," : (gen_speed == 1) ? "5.0GT/s," :
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Alex Deucher alexander.deucher@amd.com
commit a2f8d988698d7d3645b045f4940415b045140b81 upstream.
Avoid the extra wrapper function.
Reviewed-by: Nicholas Kazlauskas nicholas.kazlauskas@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 | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-)
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -3043,19 +3043,6 @@ static void amdgpu_dm_update_backlight_c #endif }
-static int set_backlight_via_aux(struct dc_link *link, uint32_t brightness) -{ - bool rc; - - if (!link) - return 1; - - rc = dc_link_set_backlight_level_nits(link, true, brightness, - AUX_BL_DEFAULT_TRANSITION_TIME_MS); - - return rc ? 0 : 1; -} - static int get_brightness_range(const struct amdgpu_dm_backlight_caps *caps, unsigned *min, unsigned *max) { @@ -3118,9 +3105,10 @@ static int amdgpu_dm_backlight_update_st brightness = convert_brightness_from_user(&caps, bd->props.brightness); // Change brightness based on AUX property if (caps.aux_support) - return set_backlight_via_aux(link, brightness); - - rc = dc_link_set_backlight_level(dm->backlight_link, brightness, 0); + rc = dc_link_set_backlight_level_nits(link, true, brightness, + AUX_BL_DEFAULT_TRANSITION_TIME_MS); + else + rc = dc_link_set_backlight_level(dm->backlight_link, brightness, 0);
return rc ? 0 : 1; }
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Alex Deucher alexander.deucher@amd.com
commit dfd8b7fbd985ec1cf76fe10f2875a50b10833740 upstream.
It just spams the logs.
Reviewed-by: Nicholas Kazlauskas nicholas.kazlauskas@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/dc/core/dc_link.c | 1 - 1 file changed, 1 deletion(-)
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -2555,7 +2555,6 @@ bool dc_link_set_backlight_level(const s if (pipe_ctx->plane_state == NULL) frame_ramp = 0; } else { - ASSERT(false); return false; }
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Alex Deucher alexander.deucher@amd.com
commit 0ad3e64eb46d8c47de3af552e282894e3893e973 upstream.
Need to fetch it via aux.
Reviewed-by: Nicholas Kazlauskas nicholas.kazlauskas@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 | 24 ++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-)
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -3116,11 +3116,27 @@ static int amdgpu_dm_backlight_update_st static int amdgpu_dm_backlight_get_brightness(struct backlight_device *bd) { struct amdgpu_display_manager *dm = bl_get_data(bd); - int ret = dc_link_get_backlight_level(dm->backlight_link); + struct amdgpu_dm_backlight_caps caps;
- if (ret == DC_ERROR_UNEXPECTED) - return bd->props.brightness; - return convert_brightness_to_user(&dm->backlight_caps, ret); + amdgpu_dm_update_backlight_caps(dm); + caps = dm->backlight_caps; + + if (caps.aux_support) { + struct dc_link *link = (struct dc_link *)dm->backlight_link; + u32 avg, peak; + bool rc; + + rc = dc_link_get_backlight_level_nits(link, &avg, &peak); + if (!rc) + return bd->props.brightness; + return convert_brightness_to_user(&caps, avg); + } else { + int ret = dc_link_get_backlight_level(dm->backlight_link); + + if (ret == DC_ERROR_UNEXPECTED) + return bd->props.brightness; + return convert_brightness_to_user(&caps, ret); + } }
static const struct backlight_ops amdgpu_dm_backlight_ops = {
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Neil Roberts nroberts@igalia.com
commit d611b4a0907cece060699f2fd347c492451cd2aa upstream.
When a buffer is madvised as not needed and then purged, any attempts to access the buffer from user-space should cause a bus fault. This patch adds a check for that.
Cc: stable@vger.kernel.org Fixes: 17acb9f35ed7 ("drm/shmem: Add madvise state and purge helpers") Signed-off-by: Neil Roberts nroberts@igalia.com Reviewed-by: Steven Price steven.price@arm.com Signed-off-by: Steven Price steven.price@arm.com Link: https://patchwork.freedesktop.org/patch/msgid/20210223155125.199577-2-nrober... Signed-off-by: Maarten Lankhorst maarten.lankhorst@linux.intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/drm_gem_shmem_helper.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-)
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c @@ -534,14 +534,24 @@ static vm_fault_t drm_gem_shmem_fault(st struct drm_gem_object *obj = vma->vm_private_data; struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj); loff_t num_pages = obj->size >> PAGE_SHIFT; + vm_fault_t ret; struct page *page;
- if (vmf->pgoff >= num_pages || WARN_ON_ONCE(!shmem->pages)) - return VM_FAULT_SIGBUS; + mutex_lock(&shmem->pages_lock);
- page = shmem->pages[vmf->pgoff]; + if (vmf->pgoff >= num_pages || + WARN_ON_ONCE(!shmem->pages) || + shmem->madv < 0) { + ret = VM_FAULT_SIGBUS; + } else { + page = shmem->pages[vmf->pgoff];
- return vmf_insert_page(vma, vmf->address, page); + ret = vmf_insert_page(vma, vmf->address, page); + } + + mutex_unlock(&shmem->pages_lock); + + return ret; }
static void drm_gem_shmem_vm_open(struct vm_area_struct *vma)
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Neil Roberts nroberts@igalia.com
commit 11d5a4745e00e73745774671dbf2fb07bd6e2363 upstream.
When mmapping the shmem, it would previously adjust the pgoff in the vm_area_struct to remove the fake offset that is added to be able to identify the buffer. This patch removes the adjustment and makes the fault handler use the vm_fault address to calculate the page offset instead. Although using this address is apparently discouraged, several DRM drivers seem to be doing it anyway.
The problem with removing the pgoff is that it prevents drm_vma_node_unmap from working because that searches the mapping tree by address. That doesn't work because all of the mappings are at offset 0. drm_vma_node_unmap is being used by the shmem helpers when purging the buffer.
This fixes a bug in Panfrost which is using drm_gem_shmem_purge. Without this the mapping for the purged buffer can still be accessed which might mean it would access random pages from other buffers
v2: Don't check whether the unsigned page_offset is less than 0.
Cc: stable@vger.kernel.org Fixes: 17acb9f35ed7 ("drm/shmem: Add madvise state and purge helpers") Signed-off-by: Neil Roberts nroberts@igalia.com Reviewed-by: Steven Price steven.price@arm.com Signed-off-by: Steven Price steven.price@arm.com Link: https://patchwork.freedesktop.org/patch/msgid/20210223155125.199577-3-nrober... Signed-off-by: Maarten Lankhorst maarten.lankhorst@linux.intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/drm_gem_shmem_helper.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c @@ -536,15 +536,19 @@ static vm_fault_t drm_gem_shmem_fault(st loff_t num_pages = obj->size >> PAGE_SHIFT; vm_fault_t ret; struct page *page; + pgoff_t page_offset; + + /* We don't use vmf->pgoff since that has the fake offset */ + page_offset = (vmf->address - vma->vm_start) >> PAGE_SHIFT;
mutex_lock(&shmem->pages_lock);
- if (vmf->pgoff >= num_pages || + if (page_offset >= num_pages || WARN_ON_ONCE(!shmem->pages) || shmem->madv < 0) { ret = VM_FAULT_SIGBUS; } else { - page = shmem->pages[vmf->pgoff]; + page = shmem->pages[page_offset];
ret = vmf_insert_page(vma, vmf->address, page); } @@ -600,9 +604,6 @@ int drm_gem_shmem_mmap(struct drm_gem_ob struct drm_gem_shmem_object *shmem; int ret;
- /* Remove the fake offset */ - vma->vm_pgoff -= drm_vma_node_start(&obj->vma_node); - if (obj->import_attach) { /* Drop the reference drm_gem_mmap_obj() acquired.*/ drm_gem_object_put(obj);
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Thomas Zimmermann tzimmermann@suse.de
commit 659ab7a49cbebe0deffcbe1f9560e82006b21817 upstream.
USB devices cannot perform DMA and hence have no dma_mask set in their device structure. Therefore importing dmabuf into a USB-based driver fails, which breaks joining and mirroring of display in X11.
For USB devices, pick the associated USB controller as attachment device. This allows the DRM import helpers to perform the DMA setup. If the DMA controller does not support DMA transfers, we're out of luck and cannot import. Our current USB-based DRM drivers don't use DMA, so the actual DMA device is not important.
Tested by joining/mirroring displays of udl and radeon under Gnome/X11.
v8: * release dmadev if device initialization fails (Noralf) * fix commit description (Noralf) v7: * fix use-before-init bug in gm12u320 (Dan) v6: * implement workaround in DRM drivers and hold reference to DMA device while USB device is in use * remove dev_is_usb() (Greg) * collapse USB helper into usb_intf_get_dma_device() (Alan) * integrate Daniel's TODO statement (Daniel) * fix typos (Greg) v5: * provide a helper for USB interfaces (Alan) * add FIXME item to documentation and TODO list (Daniel) v4: * implement workaround with USB helper functions (Greg) * use struct usb_device->bus->sysdev as DMA device (Takashi) v3: * drop gem_create_object * use DMA mask of USB controller, if any (Daniel, Christian, Noralf) v2: * move fix to importer side (Christian, Daniel) * update SHMEM and CMA helpers for new PRIME callbacks
Signed-off-by: Thomas Zimmermann tzimmermann@suse.de Fixes: 6eb0233ec2d0 ("usb: don't inherity DMA properties for USB devices") Tested-by: Pavel Machek pavel@ucw.cz Reviewed-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Acked-by: Christian König christian.koenig@amd.com Acked-by: Daniel Vetter daniel.vetter@ffwll.ch Acked-by: Noralf Trønnes noralf@tronnes.org Cc: Christoph Hellwig hch@lst.de Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: stable@vger.kernel.org # v5.10+ Signed-off-by: Thomas Zimmermann tzimmermann@suse.de Link: https://patchwork.freedesktop.org/patch/msgid/20210303133229.3288-1-tzimmerm... Signed-off-by: Maarten Lankhorst maarten.lankhorst@linux.intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- Documentation/gpu/todo.rst | 21 +++++++++++++++++++ drivers/gpu/drm/tiny/gm12u320.c | 44 ++++++++++++++++++++++++++++++++-------- drivers/gpu/drm/udl/udl_drv.c | 17 +++++++++++++++ drivers/gpu/drm/udl/udl_drv.h | 1 drivers/gpu/drm/udl/udl_main.c | 10 +++++++++ drivers/usb/core/usb.c | 32 +++++++++++++++++++++++++++++ include/linux/usb.h | 2 + 7 files changed, 119 insertions(+), 8 deletions(-)
--- a/Documentation/gpu/todo.rst +++ b/Documentation/gpu/todo.rst @@ -560,6 +560,27 @@ Some of these date from the very introdu
Level: Intermediate
+Remove automatic page mapping from dma-buf importing +---------------------------------------------------- + +When importing dma-bufs, the dma-buf and PRIME frameworks automatically map +imported pages into the importer's DMA area. drm_gem_prime_fd_to_handle() and +drm_gem_prime_handle_to_fd() require that importers call dma_buf_attach() +even if they never do actual device DMA, but only CPU access through +dma_buf_vmap(). This is a problem for USB devices, which do not support DMA +operations. + +To fix the issue, automatic page mappings should be removed from the +buffer-sharing code. Fixing this is a bit more involved, since the import/export +cache is also tied to &drm_gem_object.import_attach. Meanwhile we paper over +this problem for USB devices by fishing out the USB host controller device, as +long as that supports DMA. Otherwise importing can still needlessly fail. + +Contact: Thomas Zimmermann tzimmermann@suse.de, Daniel Vetter + +Level: Advanced + + Better Testing ==============
--- a/drivers/gpu/drm/tiny/gm12u320.c +++ b/drivers/gpu/drm/tiny/gm12u320.c @@ -83,6 +83,7 @@ MODULE_PARM_DESC(eco_mode, "Turn on Eco
struct gm12u320_device { struct drm_device dev; + struct device *dmadev; struct drm_simple_display_pipe pipe; struct drm_connector conn; struct usb_device *udev; @@ -598,6 +599,22 @@ static const uint64_t gm12u320_pipe_modi DRM_FORMAT_MOD_INVALID };
+/* + * FIXME: Dma-buf sharing requires DMA support by the importing device. + * This function is a workaround to make USB devices work as well. + * See todo.rst for how to fix the issue in the dma-buf framework. + */ +static struct drm_gem_object *gm12u320_gem_prime_import(struct drm_device *dev, + struct dma_buf *dma_buf) +{ + struct gm12u320_device *gm12u320 = to_gm12u320(dev); + + if (!gm12u320->dmadev) + return ERR_PTR(-ENODEV); + + return drm_gem_prime_import_dev(dev, dma_buf, gm12u320->dmadev); +} + DEFINE_DRM_GEM_FOPS(gm12u320_fops);
static struct drm_driver gm12u320_drm_driver = { @@ -611,6 +628,7 @@ static struct drm_driver gm12u320_drm_dr
.fops = &gm12u320_fops, DRM_GEM_SHMEM_DRIVER_OPS, + .gem_prime_import = gm12u320_gem_prime_import, };
static const struct drm_mode_config_funcs gm12u320_mode_config_funcs = { @@ -637,16 +655,19 @@ static int gm12u320_usb_probe(struct usb struct gm12u320_device, dev); if (IS_ERR(gm12u320)) return PTR_ERR(gm12u320); + dev = &gm12u320->dev; + + gm12u320->dmadev = usb_intf_get_dma_device(to_usb_interface(dev->dev)); + if (!gm12u320->dmadev) + drm_warn(dev, "buffer sharing not supported"); /* not an error */
gm12u320->udev = interface_to_usbdev(interface); INIT_DELAYED_WORK(&gm12u320->fb_update.work, gm12u320_fb_update_work); mutex_init(&gm12u320->fb_update.lock);
- dev = &gm12u320->dev; - ret = drmm_mode_config_init(dev); if (ret) - return ret; + goto err_put_device;
dev->mode_config.min_width = GM12U320_USER_WIDTH; dev->mode_config.max_width = GM12U320_USER_WIDTH; @@ -656,15 +677,15 @@ static int gm12u320_usb_probe(struct usb
ret = gm12u320_usb_alloc(gm12u320); if (ret) - return ret; + goto err_put_device;
ret = gm12u320_set_ecomode(gm12u320); if (ret) - return ret; + goto err_put_device;
ret = gm12u320_conn_init(gm12u320); if (ret) - return ret; + goto err_put_device;
ret = drm_simple_display_pipe_init(&gm12u320->dev, &gm12u320->pipe, @@ -674,24 +695,31 @@ static int gm12u320_usb_probe(struct usb gm12u320_pipe_modifiers, &gm12u320->conn); if (ret) - return ret; + goto err_put_device;
drm_mode_config_reset(dev);
usb_set_intfdata(interface, dev); ret = drm_dev_register(dev, 0); if (ret) - return ret; + goto err_put_device;
drm_fbdev_generic_setup(dev, 0);
return 0; + +err_put_device: + put_device(gm12u320->dmadev); + return ret; }
static void gm12u320_usb_disconnect(struct usb_interface *interface) { struct drm_device *dev = usb_get_intfdata(interface); + struct gm12u320_device *gm12u320 = to_gm12u320(dev);
+ put_device(gm12u320->dmadev); + gm12u320->dmadev = NULL; drm_dev_unplug(dev); drm_atomic_helper_shutdown(dev); } --- a/drivers/gpu/drm/udl/udl_drv.c +++ b/drivers/gpu/drm/udl/udl_drv.c @@ -32,6 +32,22 @@ static int udl_usb_resume(struct usb_int return drm_mode_config_helper_resume(dev); }
+/* + * FIXME: Dma-buf sharing requires DMA support by the importing device. + * This function is a workaround to make USB devices work as well. + * See todo.rst for how to fix the issue in the dma-buf framework. + */ +static struct drm_gem_object *udl_driver_gem_prime_import(struct drm_device *dev, + struct dma_buf *dma_buf) +{ + struct udl_device *udl = to_udl(dev); + + if (!udl->dmadev) + return ERR_PTR(-ENODEV); + + return drm_gem_prime_import_dev(dev, dma_buf, udl->dmadev); +} + DEFINE_DRM_GEM_FOPS(udl_driver_fops);
static struct drm_driver driver = { @@ -42,6 +58,7 @@ static struct drm_driver driver = {
.fops = &udl_driver_fops, DRM_GEM_SHMEM_DRIVER_OPS, + .gem_prime_import = udl_driver_gem_prime_import,
.name = DRIVER_NAME, .desc = DRIVER_DESC, --- a/drivers/gpu/drm/udl/udl_drv.h +++ b/drivers/gpu/drm/udl/udl_drv.h @@ -50,6 +50,7 @@ struct urb_list { struct udl_device { struct drm_device drm; struct device *dev; + struct device *dmadev; struct usb_device *udev;
struct drm_simple_display_pipe display_pipe; --- a/drivers/gpu/drm/udl/udl_main.c +++ b/drivers/gpu/drm/udl/udl_main.c @@ -314,6 +314,10 @@ int udl_init(struct udl_device *udl)
DRM_DEBUG("\n");
+ udl->dmadev = usb_intf_get_dma_device(to_usb_interface(dev->dev)); + if (!udl->dmadev) + drm_warn(dev, "buffer sharing not supported"); /* not an error */ + mutex_init(&udl->gem_lock);
if (!udl_parse_vendor_descriptor(dev, udl->udev)) { @@ -342,12 +346,18 @@ int udl_init(struct udl_device *udl) err: if (udl->urbs.count) udl_free_urb_list(dev); + put_device(udl->dmadev); DRM_ERROR("%d\n", ret); return ret; }
int udl_drop_usb(struct drm_device *dev) { + struct udl_device *udl = to_udl(dev); + udl_free_urb_list(dev); + put_device(udl->dmadev); + udl->dmadev = NULL; + return 0; } --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -748,6 +748,38 @@ void usb_put_intf(struct usb_interface * } EXPORT_SYMBOL_GPL(usb_put_intf);
+/** + * usb_intf_get_dma_device - acquire a reference on the usb interface's DMA endpoint + * @intf: the usb interface + * + * While a USB device cannot perform DMA operations by itself, many USB + * controllers can. A call to usb_intf_get_dma_device() returns the DMA endpoint + * for the given USB interface, if any. The returned device structure must be + * released with put_device(). + * + * See also usb_get_dma_device(). + * + * Returns: A reference to the usb interface's DMA endpoint; or NULL if none + * exists. + */ +struct device *usb_intf_get_dma_device(struct usb_interface *intf) +{ + struct usb_device *udev = interface_to_usbdev(intf); + struct device *dmadev; + + if (!udev->bus) + return NULL; + + dmadev = get_device(udev->bus->sysdev); + if (!dmadev || !dmadev->dma_mask) { + put_device(dmadev); + return NULL; + } + + return dmadev; +} +EXPORT_SYMBOL_GPL(usb_intf_get_dma_device); + /* USB device locking * * USB devices and interfaces are locked using the semaphore in their --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -746,6 +746,8 @@ extern int usb_lock_device_for_reset(str extern int usb_reset_device(struct usb_device *dev); extern void usb_queue_reset_device(struct usb_interface *dev);
+extern struct device *usb_intf_get_dma_device(struct usb_interface *intf); + #ifdef CONFIG_ACPI extern int usb_acpi_set_power_state(struct usb_device *hdev, int index, bool enable);
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Artem Lapkin art@khadas.com
commit fa0c16caf3d73ab4d2e5d6fa2ef2394dbec91791 upstream.
Problem: random stucks on reboot stage about 1/20 stuck/reboots // debug kernel log [ 4.496660] reboot: kernel restart prepare CMD:(null) [ 4.498114] meson_ee_pwrc c883c000.system-controller:power-controller: shutdown begin [ 4.503949] meson_ee_pwrc c883c000.system-controller:power-controller: shutdown domain 0:VPU... ...STUCK...
Solution: add shutdown function to meson_drm driver // debug kernel log [ 5.231896] reboot: kernel restart prepare CMD:(null) [ 5.246135] [drm:meson_drv_shutdown] ... [ 5.259271] meson_ee_pwrc c883c000.system-controller:power-controller: shutdown begin [ 5.274688] meson_ee_pwrc c883c000.system-controller:power-controller: shutdown domain 0:VPU... [ 5.338331] reboot: Restarting system [ 5.358293] psci: PSCI_0_2_FN_SYSTEM_RESET reboot_mode:0 cmd:(null) bl31 reboot reason: 0xd bl31 reboot reason: 0x0 system cmd 1. ...REBOOT...
Tested: on VIM1 VIM2 VIM3 VIM3L khadas sbcs - 1000+ successful reboots and Odroid boards, WeTek Play2 (GXBB)
Fixes: bbbe775ec5b5 ("drm: Add support for Amlogic Meson Graphic Controller") Signed-off-by: Artem Lapkin art@khadas.com Tested-by: Christian Hewitt christianshewitt@gmail.com Acked-by: Neil Armstrong narmstrong@baylibre.com Acked-by: Kevin Hilman khilman@baylibre.com Signed-off-by: Neil Armstrong narmstrong@baylibre.com Link: https://patchwork.freedesktop.org/patch/msgid/20210302042202.3728113-1-art@k... Signed-off-by: Maarten Lankhorst maarten.lankhorst@linux.intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/meson/meson_drv.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
--- a/drivers/gpu/drm/meson/meson_drv.c +++ b/drivers/gpu/drm/meson/meson_drv.c @@ -482,6 +482,16 @@ static int meson_probe_remote(struct pla return count; }
+static void meson_drv_shutdown(struct platform_device *pdev) +{ + struct meson_drm *priv = dev_get_drvdata(&pdev->dev); + struct drm_device *drm = priv->drm; + + DRM_DEBUG_DRIVER("\n"); + drm_kms_helper_poll_fini(drm); + drm_atomic_helper_shutdown(drm); +} + static int meson_drv_probe(struct platform_device *pdev) { struct component_match *match = NULL; @@ -553,6 +563,7 @@ static const struct dev_pm_ops meson_drv
static struct platform_driver meson_drm_platform_driver = { .probe = meson_drv_probe, + .shutdown = meson_drv_shutdown, .driver = { .name = "meson-drm", .of_match_table = dt_match,
This reverts commit d66083c0d6f5125a4d982aa177dd71ab4cd3d212 and commit d4ec1ffbdaa8939a208656e9c1440742c457ef16.
On v5.10 stable, reboot gets stuck on gxl and g12a chip family (at least). This was tested on the aml-s905x-cc from libretch and the u200 reference design.
Bisecting on the v5.10 stable branch lead to commit d4ec1ffbdaa8 ("drm: meson_drv add shutdown function").
Reverting it (and a fixes on the it) sloves the problem.
Signed-off-by: Jerome Brunet jbrunet@baylibre.com ---
Hi Greg,
Things are fine on master but it breaks on v5.10-y. I did not check v5.14-y yet. I'll try next week.
drivers/gpu/drm/meson/meson_drv.c | 12 ------------ 1 file changed, 12 deletions(-)
diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c index 2753067c08e6..3d1de9cbb1c8 100644 --- a/drivers/gpu/drm/meson/meson_drv.c +++ b/drivers/gpu/drm/meson/meson_drv.c @@ -482,17 +482,6 @@ static int meson_probe_remote(struct platform_device *pdev, return count; }
-static void meson_drv_shutdown(struct platform_device *pdev) -{ - struct meson_drm *priv = dev_get_drvdata(&pdev->dev); - - if (!priv) - return; - - drm_kms_helper_poll_fini(priv->drm); - drm_atomic_helper_shutdown(priv->drm); -} - static int meson_drv_probe(struct platform_device *pdev) { struct component_match *match = NULL; @@ -564,7 +553,6 @@ static const struct dev_pm_ops meson_drv_pm_ops = {
static struct platform_driver meson_drm_platform_driver = { .probe = meson_drv_probe, - .shutdown = meson_drv_shutdown, .driver = { .name = "meson-drm", .of_match_table = dt_match,
On Sat, Dec 04, 2021 at 10:31:57PM +0100, Jerome Brunet wrote:
This reverts commit d66083c0d6f5125a4d982aa177dd71ab4cd3d212 and commit d4ec1ffbdaa8939a208656e9c1440742c457ef16.
No, please, at most let us revert the commits individually.
On v5.10 stable, reboot gets stuck on gxl and g12a chip family (at least). This was tested on the aml-s905x-cc from libretch and the u200 reference design.
Bisecting on the v5.10 stable branch lead to commit d4ec1ffbdaa8 ("drm: meson_drv add shutdown function").
Reverting it (and a fixes on the it) sloves the problem.
Signed-off-by: Jerome Brunet jbrunet@baylibre.com
Hi Greg,
Things are fine on master but it breaks on v5.10-y. I did not check v5.14-y yet. I'll try next week.
Please check 5.15.y (5.14 is long end-of-life).
thanks,
greg k-h
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Noralf Trønnes noralf@tronnes.org
commit 64e194e278673bceb68fb2dde7dbc3d812bfceb3 upstream.
dma-buf importing was reworked in commit 7d2cd72a9aa3 ("drm/shmem-helpers: Simplify dma-buf importing"). Before that commit drm_gem_shmem_prime_import_sg_table() did set ->pages_use_count=1 and drm_gem_shmem_vunmap_locked() could call drm_gem_shmem_put_pages() unconditionally. Now without the use count set, put pages is called also on dma-bufs. Fix this by only putting pages if it's not imported.
Signed-off-by: Noralf Trønnes noralf@tronnes.org Fixes: 7d2cd72a9aa3 ("drm/shmem-helpers: Simplify dma-buf importing") Cc: Daniel Vetter daniel.vetter@ffwll.ch Cc: Thomas Zimmermann tzimmermann@suse.de Acked-by: Thomas Zimmermann tzimmermann@suse.de Tested-by: Thomas Zimmermann tzimmermann@suse.de Link: https://patchwork.freedesktop.org/patch/msgid/20210219122203.51130-1-noralf@... (cherry picked from commit cdea72518a2b38207146e92e1c9e2fac15975679) Signed-off-by: Thomas Zimmermann tzimmermann@suse.de Signed-off-by: Maarten Lankhorst maarten.lankhorst@linux.intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/drm_gem_shmem_helper.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c @@ -340,13 +340,14 @@ static void drm_gem_shmem_vunmap_locked( if (--shmem->vmap_use_count > 0) return;
- if (obj->import_attach) + if (obj->import_attach) { dma_buf_vunmap(obj->import_attach->dmabuf, shmem->vaddr); - else + } else { vunmap(shmem->vaddr); + drm_gem_shmem_put_pages(shmem); + }
shmem->vaddr = NULL; - drm_gem_shmem_put_pages(shmem); }
/*
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Tvrtko Ursulin tvrtko.ursulin@intel.com
commit a829f033e966d5e4aa27c3ef2b381f51734e4a7f upstream.
Commit 311a50e76a33 ("drm/i915: Add support for mandatory cmdparsing") introduced mandatory command parsing but setup failures were not translated into wedging the GPU which was probably the intent.
Possible errors come in two categories. Either the sanity check on internal tables has failed, which should be caught in CI unless an affected platform would be missed in testing; or memory allocation failure happened during driver load, which should be extremely unlikely but for correctness should still be handled.
v2: * Tidy coding style. (Chris)
[airlied: cherry-picked to avoid rc1 base] Signed-off-by: Tvrtko Ursulin tvrtko.ursulin@intel.com Fixes: 311a50e76a33 ("drm/i915: Add support for mandatory cmdparsing") Cc: Jon Bloomfield jon.bloomfield@intel.com Cc: Joonas Lahtinen joonas.lahtinen@linux.intel.com Cc: Chris Wilson chris.p.wilson@intel.com Reviewed-by: Chris Wilson chris.p.wilson@intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20210302114213.1102223-1-tvrtk... (cherry picked from commit 5a1a659762d35a6dc51047c9127c011303c77b7f) Signed-off-by: Rodrigo Vivi rodrigo.vivi@intel.com Signed-off-by: Dave Airlie airlied@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/i915/gt/intel_engine_cs.c | 7 ++++++- drivers/gpu/drm/i915/i915_cmd_parser.c | 19 +++++++++++++------ drivers/gpu/drm/i915/i915_drv.h | 2 +- 3 files changed, 20 insertions(+), 8 deletions(-)
--- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c @@ -708,9 +708,12 @@ static int engine_setup_common(struct in goto err_status; }
+ err = intel_engine_init_cmd_parser(engine); + if (err) + goto err_cmd_parser; + intel_engine_init_active(engine, ENGINE_PHYSICAL); intel_engine_init_execlists(engine); - intel_engine_init_cmd_parser(engine); intel_engine_init__pm(engine); intel_engine_init_retire(engine);
@@ -724,6 +727,8 @@ static int engine_setup_common(struct in
return 0;
+err_cmd_parser: + intel_breadcrumbs_free(engine->breadcrumbs); err_status: cleanup_status_page(engine); return err; --- a/drivers/gpu/drm/i915/i915_cmd_parser.c +++ b/drivers/gpu/drm/i915/i915_cmd_parser.c @@ -939,7 +939,7 @@ static void fini_hash_table(struct intel * struct intel_engine_cs based on whether the platform requires software * command parsing. */ -void intel_engine_init_cmd_parser(struct intel_engine_cs *engine) +int intel_engine_init_cmd_parser(struct intel_engine_cs *engine) { const struct drm_i915_cmd_table *cmd_tables; int cmd_table_count; @@ -947,7 +947,7 @@ void intel_engine_init_cmd_parser(struct
if (!IS_GEN(engine->i915, 7) && !(IS_GEN(engine->i915, 9) && engine->class == COPY_ENGINE_CLASS)) - return; + return 0;
switch (engine->class) { case RENDER_CLASS: @@ -1012,19 +1012,19 @@ void intel_engine_init_cmd_parser(struct break; default: MISSING_CASE(engine->class); - return; + goto out; }
if (!validate_cmds_sorted(engine, cmd_tables, cmd_table_count)) { drm_err(&engine->i915->drm, "%s: command descriptions are not sorted\n", engine->name); - return; + goto out; } if (!validate_regs_sorted(engine)) { drm_err(&engine->i915->drm, "%s: registers are not sorted\n", engine->name); - return; + goto out; }
ret = init_hash_table(engine, cmd_tables, cmd_table_count); @@ -1032,10 +1032,17 @@ void intel_engine_init_cmd_parser(struct drm_err(&engine->i915->drm, "%s: initialised failed!\n", engine->name); fini_hash_table(engine); - return; + goto out; }
engine->flags |= I915_ENGINE_USING_CMD_PARSER; + +out: + if (intel_engine_requires_cmd_parser(engine) && + !intel_engine_using_cmd_parser(engine)) + return -EINVAL; + + return 0; }
/** --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1946,7 +1946,7 @@ const char *i915_cache_level_str(struct
/* i915_cmd_parser.c */ int i915_cmd_parser_get_version(struct drm_i915_private *dev_priv); -void intel_engine_init_cmd_parser(struct intel_engine_cs *engine); +int intel_engine_init_cmd_parser(struct intel_engine_cs *engine); void intel_engine_cleanup_cmd_parser(struct intel_engine_cs *engine); int intel_engine_cmd_parser(struct intel_engine_cs *engine, struct i915_vma *batch,
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Eric Farman farman@linux.ibm.com
commit d9c48a948d29bcb22f4fe61a81b718ef6de561a0 upstream.
Fixes: 120e214e504f ("vfio: ccw: realize VFIO_DEVICE_G(S)ET_IRQ_INFO ioctls") Signed-off-by: Eric Farman farman@linux.ibm.com Signed-off-by: Heiko Carstens hca@linux.ibm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/s390/cio/vfio_ccw_ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/s390/cio/vfio_ccw_ops.c +++ b/drivers/s390/cio/vfio_ccw_ops.c @@ -578,7 +578,7 @@ static ssize_t vfio_ccw_mdev_ioctl(struc if (info.count == -1) return -EINVAL;
- return copy_to_user((void __user *)arg, &info, minsz); + return copy_to_user((void __user *)arg, &info, minsz) ? -EFAULT : 0; } case VFIO_DEVICE_SET_IRQS: {
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Wang Qing wangqing@vivo.com
commit 942df4be7ab40195e2a839e9de81951a5862bc5b upstream.
The copy_to_user() function returns the number of bytes remaining to be copied, but we want to return -EFAULT if the copy doesn't complete.
Fixes: e06670c5fe3b ("s390: vfio-ap: implement VFIO_DEVICE_GET_INFO ioctl") Signed-off-by: Wang Qing wangqing@vivo.com Reviewed-by: Tony Krowiak akrowiak@linux.ibm.com Signed-off-by: Heiko Carstens hca@linux.ibm.com Link: https://lore.kernel.org/r/1614600502-16714-1-git-send-email-wangqing@vivo.co... Signed-off-by: Heiko Carstens hca@linux.ibm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/s390/crypto/vfio_ap_ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/s390/crypto/vfio_ap_ops.c +++ b/drivers/s390/crypto/vfio_ap_ops.c @@ -1279,7 +1279,7 @@ static int vfio_ap_mdev_get_device_info( info.num_regions = 0; info.num_irqs = 0;
- return copy_to_user((void __user *)arg, &info, minsz); + return copy_to_user((void __user *)arg, &info, minsz) ? -EFAULT : 0; }
static ssize_t vfio_ap_mdev_ioctl(struct mdev_device *mdev,
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Colin Ian King colin.king@canonical.com
commit 738acd49eb018feb873e0fac8f9517493f6ce2c7 upstream.
The surface_id struct field in head is not being initialized and static analysis warns that this is being passed through to dev->monitors_config->heads[i] on an assignment. Clear up this warning by initializing it to zero.
Addresses-Coverity: ("Uninitialized scalar variable") Fixes: a6d3c4d79822 ("qxl: hook monitors_config updates into crtc, not encoder.") Signed-off-by: Colin Ian King colin.king@canonical.com Link: http://patchwork.freedesktop.org/patch/msgid/20210304094928.2280722-1-colin.... Signed-off-by: Gerd Hoffmann kraxel@redhat.com Signed-off-by: Maarten Lankhorst maarten.lankhorst@linux.intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/qxl/qxl_display.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c @@ -327,6 +327,7 @@ static void qxl_crtc_update_monitors_con
head.id = i; head.flags = 0; + head.surface_id = 0; oldcount = qdev->monitors_config->count; if (crtc->state->active) { struct drm_display_mode *mode = &crtc->mode;
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Sergey Shtylyov s.shtylyov@omprussia.ru
commit 165bc5a4f30eee4735845aa7dbd6b738643f2603 upstream.
According to the RZ/A2M Group User's Manual: Hardware, Rev. 2.00, the TRSCER register has bit 9 reserved, hence we can't use the driver's default TRSCER mask. Add the explicit initializer for sh_eth_cpu_data:: trscer_err_mask for R7S9210.
Fixes: 6e0bb04d0e4f ("sh_eth: Add R7S9210 support") Signed-off-by: Sergey Shtylyov s.shtylyov@omprussia.ru Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/renesas/sh_eth.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -780,6 +780,8 @@ static struct sh_eth_cpu_data r7s9210_da
.fdr_value = 0x0000070f,
+ .trscer_err_mask = DESC_I_RINT8 | DESC_I_RINT5, + .apr = 1, .mpr = 1, .tpauser = 1,
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Maxim Mikityanskiy maxtram95@gmail.com
commit 8a7e27fd5cd696ba564a3f62cedef7269cfd0723 upstream.
usbtv doesn't support power management, so on system suspend the .disconnect callback of the driver is called. The teardown sequence includes a call to snd_card_free. Its implementation waits until the refcount of the sound card device drops to zero, however, if its file is open, snd_card_file_add takes a reference, which can't be dropped during the suspend, because the userspace processes are already frozen at this point. snd_card_free waits for completion forever, leading to a hang on suspend.
This commit fixes this deadlock condition by replacing snd_card_free with snd_card_free_when_closed, that doesn't wait until all references are released, allowing suspend to progress.
Fixes: 63ddf68de52e ("[media] usbtv: add audio support") Signed-off-by: Maxim Mikityanskiy maxtram95@gmail.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/media/usb/usbtv/usbtv-audio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/media/usb/usbtv/usbtv-audio.c +++ b/drivers/media/usb/usbtv/usbtv-audio.c @@ -371,7 +371,7 @@ void usbtv_audio_free(struct usbtv *usbt cancel_work_sync(&usbtv->snd_trigger);
if (usbtv->snd && usbtv->udev) { - snd_card_free(usbtv->snd); + snd_card_free_when_closed(usbtv->snd); usbtv->snd = NULL; } }
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Dafna Hirschfeld dafna.hirschfeld@collabora.com
commit 2025a48cfd92d541c5ee47deee97f8a46d00c4ac upstream.
The histogram mode is set using 'rkisp1_params_set_bits'. Only the bits of the mode should be the value argument for that function. Otherwise bits outside the mode mask are turned on which is not what was intended.
Fixes: bae1155cf579 ("media: staging: rkisp1: add output device for parameters") Signed-off-by: Dafna Hirschfeld dafna.hirschfeld@collabora.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/staging/media/rkisp1/rkisp1-params.c | 1 - 1 file changed, 1 deletion(-)
--- a/drivers/staging/media/rkisp1/rkisp1-params.c +++ b/drivers/staging/media/rkisp1/rkisp1-params.c @@ -1291,7 +1291,6 @@ static void rkisp1_params_config_paramet memset(hst.hist_weight, 0x01, sizeof(hst.hist_weight)); rkisp1_hst_config(params, &hst); rkisp1_param_set_bits(params, RKISP1_CIF_ISP_HIST_PROP, - ~RKISP1_CIF_ISP_HIST_PROP_MODE_MASK | rkisp1_hst_params_default_config.mode);
/* set the range */
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Biju Das biju.das.jz@bp.renesas.com
commit 6732f313938027a910e1f7351951ff52c0329e70 upstream.
RZ/G2L SoC has no UIF. This patch fixes null pointer access, when UIF module is not used.
Fixes: 5e824f989e6e8("media: v4l: vsp1: Integrate DISCOM in display pipeline") Signed-off-by: Biju Das biju.das.jz@bp.renesas.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/media/platform/vsp1/vsp1_drm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/media/platform/vsp1/vsp1_drm.c +++ b/drivers/media/platform/vsp1/vsp1_drm.c @@ -462,9 +462,9 @@ static int vsp1_du_pipeline_setup_inputs * make sure it is present in the pipeline's list of entities if it * wasn't already. */ - if (!use_uif) { + if (drm_pipe->uif && !use_uif) { drm_pipe->uif->pipe = NULL; - } else if (!drm_pipe->uif->pipe) { + } else if (drm_pipe->uif && !drm_pipe->uif->pipe) { drm_pipe->uif->pipe = pipe; list_add_tail(&drm_pipe->uif->list_pipe, &pipe->entities); }
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Biju Das biju.das.jz@bp.renesas.com
commit ac8d82f586c8692b501cb974604a71ef0e22a04c upstream.
RZ/G2L SoC has only BRS. This patch fixes null pointer access,when only BRS is enabled.
Fixes: cbb7fa49c7466("media: v4l: vsp1: Rename BRU to BRx") Signed-off-by: Biju Das biju.das.jz@bp.renesas.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/media/platform/vsp1/vsp1_drm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/media/platform/vsp1/vsp1_drm.c +++ b/drivers/media/platform/vsp1/vsp1_drm.c @@ -245,7 +245,7 @@ static int vsp1_du_pipeline_setup_brx(st brx = &vsp1->bru->entity; else if (pipe->brx && !drm_pipe->force_brx_release) brx = pipe->brx; - else if (!vsp1->bru->entity.pipe) + else if (vsp1_feature(vsp1, VSP1_HAS_BRU) && !vsp1->bru->entity.pipe) brx = &vsp1->bru->entity; else brx = &vsp1->brs->entity;
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Hans Verkuil hverkuil@xs4all.nl
commit f09f9f93afad770a04b35235a0aa465fcc8d6e3d upstream.
The rc-cec keymap is unusual in that it can't be built as a module, instead it is registered directly in rc-main.c if CONFIG_MEDIA_CEC_RC is set. This is because it can be called from drm_dp_cec_set_edid() via cec_register_adapter() in an asynchronous context, and it is not allowed to use request_module() to load rc-cec.ko in that case. Trying to do so results in a 'WARN_ON_ONCE(wait && current_is_async())'.
Since this keymap is only used if CONFIG_MEDIA_CEC_RC is set, we just compile this keymap into the rc-core module and never as a separate module.
Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Fixes: 2c6d1fffa1d9 (drm: add support for DisplayPort CEC-Tunneling-over-AUX) Reported-by: Hans de Goede hdegoede@redhat.com 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/Makefile | 1 + drivers/media/rc/keymaps/Makefile | 1 - drivers/media/rc/keymaps/rc-cec.c | 28 +++++++++++----------------- drivers/media/rc/rc-main.c | 6 ++++++ include/media/rc-map.h | 7 +++++++ 5 files changed, 25 insertions(+), 18 deletions(-)
--- a/drivers/media/rc/Makefile +++ b/drivers/media/rc/Makefile @@ -5,6 +5,7 @@ obj-y += keymaps/ obj-$(CONFIG_RC_CORE) += rc-core.o rc-core-y := rc-main.o rc-ir-raw.o rc-core-$(CONFIG_LIRC) += lirc_dev.o +rc-core-$(CONFIG_MEDIA_CEC_RC) += keymaps/rc-cec.o rc-core-$(CONFIG_BPF_LIRC_MODE2) += bpf-lirc.o obj-$(CONFIG_IR_NEC_DECODER) += ir-nec-decoder.o obj-$(CONFIG_IR_RC5_DECODER) += ir-rc5-decoder.o --- a/drivers/media/rc/keymaps/Makefile +++ b/drivers/media/rc/keymaps/Makefile @@ -21,7 +21,6 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t rc-behold.o \ rc-behold-columbus.o \ rc-budget-ci-old.o \ - rc-cec.o \ rc-cinergy-1400.o \ rc-cinergy.o \ rc-d680-dmb.o \ --- a/drivers/media/rc/keymaps/rc-cec.c +++ b/drivers/media/rc/keymaps/rc-cec.c @@ -1,6 +1,16 @@ // SPDX-License-Identifier: GPL-2.0-or-later /* Keytable for the CEC remote control * + * This keymap is unusual in that it can't be built as a module, + * instead it is registered directly in rc-main.c if CONFIG_MEDIA_CEC_RC + * is set. This is because it can be called from drm_dp_cec_set_edid() via + * cec_register_adapter() in an asynchronous context, and it is not + * allowed to use request_module() to load rc-cec.ko in that case. + * + * Since this keymap is only used if CONFIG_MEDIA_CEC_RC is set, we + * just compile this keymap into the rc-core module and never as a + * separate module. + * * Copyright (c) 2015 by Kamil Debski */
@@ -152,7 +162,7 @@ static struct rc_map_table cec[] = { /* 0x77-0xff: Reserved */ };
-static struct rc_map_list cec_map = { +struct rc_map_list cec_map = { .map = { .scan = cec, .size = ARRAY_SIZE(cec), @@ -160,19 +170,3 @@ static struct rc_map_list cec_map = { .name = RC_MAP_CEC, } }; - -static int __init init_rc_map_cec(void) -{ - return rc_map_register(&cec_map); -} - -static void __exit exit_rc_map_cec(void) -{ - rc_map_unregister(&cec_map); -} - -module_init(init_rc_map_cec); -module_exit(exit_rc_map_cec); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Kamil Debski"); --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -2069,6 +2069,9 @@ static int __init rc_core_init(void)
led_trigger_register_simple("rc-feedback", &led_feedback); rc_map_register(&empty_map); +#ifdef CONFIG_MEDIA_CEC_RC + rc_map_register(&cec_map); +#endif
return 0; } @@ -2078,6 +2081,9 @@ static void __exit rc_core_exit(void) lirc_dev_exit(); class_unregister(&rc_class); led_trigger_unregister_simple(led_feedback); +#ifdef CONFIG_MEDIA_CEC_RC + rc_map_unregister(&cec_map); +#endif rc_map_unregister(&empty_map); }
--- a/include/media/rc-map.h +++ b/include/media/rc-map.h @@ -175,6 +175,13 @@ struct rc_map_list { struct rc_map map; };
+#ifdef CONFIG_MEDIA_CEC_RC +/* + * rc_map_list from rc-cec.c + */ +extern struct rc_map_list cec_map; +#endif + /* Routines from rc-map.c */
/**
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Aurelien Aptel aaptel@suse.com
commit a249cc8bc2e2fed680047d326eb9a50756724198 upstream.
With multichannel, operations like the queries from "ls -lR" can cause all credits to be used and errors to be returned since max_credits was not being set correctly on the secondary channels and thus the client was requesting 0 credits incorrectly in some cases (which can lead to not having enough credits to perform any operation on that channel).
Signed-off-by: Aurelien Aptel aaptel@suse.com CC: stable@vger.kernel.org # v5.8+ Reviewed-by: Shyam Prasad N sprasad@microsoft.com Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/cifs/connect.c | 10 +++++----- fs/cifs/sess.c | 1 + 2 files changed, 6 insertions(+), 5 deletions(-)
--- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -2629,6 +2629,11 @@ smbd_connected: tcp_ses->min_offload = volume_info->min_offload; tcp_ses->tcpStatus = CifsNeedNegotiate;
+ if ((volume_info->max_credits < 20) || (volume_info->max_credits > 60000)) + tcp_ses->max_credits = SMB2_MAX_CREDITS_AVAILABLE; + else + tcp_ses->max_credits = volume_info->max_credits; + tcp_ses->nr_targets = 1; tcp_ses->ignore_signature = volume_info->ignore_signature; /* thread spawned, put it on the list */ @@ -4077,11 +4082,6 @@ static int mount_get_conns(struct smb_vo
*nserver = server;
- if ((vol->max_credits < 20) || (vol->max_credits > 60000)) - server->max_credits = SMB2_MAX_CREDITS_AVAILABLE; - else - server->max_credits = vol->max_credits; - /* get a reference to a SMB session */ ses = cifs_get_smb_ses(server, vol); if (IS_ERR(ses)) { --- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c @@ -224,6 +224,7 @@ cifs_ses_add_channel(struct cifs_ses *se vol.noautotune = ses->server->noautotune; vol.sockopt_tcp_nodelay = ses->server->tcp_nodelay; vol.echo_interval = ses->server->echo_interval / HZ; + vol.max_credits = ses->server->max_credits;
/* * This will be used for encoding/decoding user/domain/pw
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Jian Shen shenjian15@huawei.com
[ Upstream commit ae85ddda0f1b341b2d25f5a5e0eff1d42b6ef3df ]
Currently, some bit filed definitions of flow director TCAM configuration command are incorrect. Since the wrong MSB is always 0, and these fields are assgined in order, so it still works.
Fix it by redefine them.
Fixes: 117328680288 ("net: hns3: Add input key and action config support for flow director") Signed-off-by: Jian Shen shenjian15@huawei.com Signed-off-by: Huazhong Tan tanhuazhong@huawei.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h index 096e26a2e16b..36690fc5c1af 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h @@ -1031,16 +1031,16 @@ struct hclge_fd_tcam_config_3_cmd { #define HCLGE_FD_AD_DROP_B 0 #define HCLGE_FD_AD_DIRECT_QID_B 1 #define HCLGE_FD_AD_QID_S 2 -#define HCLGE_FD_AD_QID_M GENMASK(12, 2) +#define HCLGE_FD_AD_QID_M GENMASK(11, 2) #define HCLGE_FD_AD_USE_COUNTER_B 12 #define HCLGE_FD_AD_COUNTER_NUM_S 13 #define HCLGE_FD_AD_COUNTER_NUM_M GENMASK(20, 13) #define HCLGE_FD_AD_NXT_STEP_B 20 #define HCLGE_FD_AD_NXT_KEY_S 21 -#define HCLGE_FD_AD_NXT_KEY_M GENMASK(26, 21) +#define HCLGE_FD_AD_NXT_KEY_M GENMASK(25, 21) #define HCLGE_FD_AD_WR_RULE_ID_B 0 #define HCLGE_FD_AD_RULE_ID_S 1 -#define HCLGE_FD_AD_RULE_ID_M GENMASK(13, 1) +#define HCLGE_FD_AD_RULE_ID_M GENMASK(12, 1)
struct hclge_fd_ad_config_cmd { u8 stage;
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Julian Wiedmann jwi@linux.ibm.com
[ Upstream commit db4ffdcef7c9a842e55228c9faef7abf8b72382f ]
For TX buffers that require an additional async notification via QAOB, the TX completion code can now manage all the necessary processing if the notification has already occurred (or is occurring concurrently).
In such cases we can avoid replacing the metadata that is associated with the buffer's slot on the ring, and just keep using the current one.
As qeth_clear_output_buffer() will also handle any kmem cache-allocated memory that was mapped into the TX buffer, qeth_qdio_handle_aob() doesn't need to worry about it.
While at it, also remove the unneeded forward declaration for qeth_init_qdio_out_buf().
Signed-off-by: Julian Wiedmann jwi@linux.ibm.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/s390/net/qeth_core_main.c | 89 ++++++++++++++++++------------- 1 file changed, 51 insertions(+), 38 deletions(-)
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 77cd714978bd..78a866424022 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -75,7 +75,6 @@ static void qeth_notify_skbs(struct qeth_qdio_out_q *queue, enum iucv_tx_notify notification); static void qeth_tx_complete_buf(struct qeth_qdio_out_buffer *buf, bool error, int budget); -static int qeth_init_qdio_out_buf(struct qeth_qdio_out_q *, int);
static void qeth_close_dev_handler(struct work_struct *work) { @@ -517,18 +516,6 @@ static void qeth_qdio_handle_aob(struct qeth_card *card, buffer = (struct qeth_qdio_out_buffer *) aob->user1; QETH_CARD_TEXT_(card, 5, "%lx", aob->user1);
- /* Free dangling allocations. The attached skbs are handled by - * qeth_cleanup_handled_pending(). - */ - for (i = 0; - i < aob->sb_count && i < QETH_MAX_BUFFER_ELEMENTS(card); - i++) { - void *data = phys_to_virt(aob->sba[i]); - - if (data && buffer->is_header[i]) - kmem_cache_free(qeth_core_header_cache, data); - } - if (aob->aorc) { QETH_CARD_TEXT_(card, 2, "aorc%02X", aob->aorc); new_state = QETH_QDIO_BUF_QAOB_ERROR; @@ -536,10 +523,9 @@ static void qeth_qdio_handle_aob(struct qeth_card *card,
switch (atomic_xchg(&buffer->state, new_state)) { case QETH_QDIO_BUF_PRIMED: - /* Faster than TX completion code. */ - notification = qeth_compute_cq_notification(aob->aorc, 0); - qeth_notify_skbs(buffer->q, buffer, notification); - atomic_set(&buffer->state, QETH_QDIO_BUF_HANDLED_DELAYED); + /* Faster than TX completion code, let it handle the async + * completion for us. + */ break; case QETH_QDIO_BUF_PENDING: /* TX completion code is active and will handle the async @@ -550,6 +536,19 @@ static void qeth_qdio_handle_aob(struct qeth_card *card, /* TX completion code is already finished. */ notification = qeth_compute_cq_notification(aob->aorc, 1); qeth_notify_skbs(buffer->q, buffer, notification); + + /* Free dangling allocations. The attached skbs are handled by + * qeth_cleanup_handled_pending(). + */ + for (i = 0; + i < aob->sb_count && i < QETH_MAX_BUFFER_ELEMENTS(card); + i++) { + void *data = phys_to_virt(aob->sba[i]); + + if (data && buffer->is_header[i]) + kmem_cache_free(qeth_core_header_cache, data); + } + atomic_set(&buffer->state, QETH_QDIO_BUF_HANDLED_DELAYED); break; default: @@ -5870,9 +5869,13 @@ static void qeth_iqd_tx_complete(struct qeth_qdio_out_q *queue, QDIO_OUTBUF_STATE_FLAG_PENDING)) { WARN_ON_ONCE(card->options.cq != QETH_CQ_ENABLED);
- if (atomic_cmpxchg(&buffer->state, QETH_QDIO_BUF_PRIMED, - QETH_QDIO_BUF_PENDING) == - QETH_QDIO_BUF_PRIMED) { + QETH_CARD_TEXT_(card, 5, "pel%u", bidx); + + switch (atomic_cmpxchg(&buffer->state, + QETH_QDIO_BUF_PRIMED, + QETH_QDIO_BUF_PENDING)) { + case QETH_QDIO_BUF_PRIMED: + /* We have initial ownership, no QAOB (yet): */ qeth_notify_skbs(queue, buffer, TX_NOTIFY_PENDING);
/* Handle race with qeth_qdio_handle_aob(): */ @@ -5880,39 +5883,49 @@ static void qeth_iqd_tx_complete(struct qeth_qdio_out_q *queue, QETH_QDIO_BUF_NEED_QAOB)) { case QETH_QDIO_BUF_PENDING: /* No concurrent QAOB notification. */ - break; + + /* Prepare the queue slot for immediate re-use: */ + qeth_scrub_qdio_buffer(buffer->buffer, queue->max_elements); + if (qeth_init_qdio_out_buf(queue, bidx)) { + QETH_CARD_TEXT(card, 2, "outofbuf"); + qeth_schedule_recovery(card); + } + + /* Skip clearing the buffer: */ + return; case QETH_QDIO_BUF_QAOB_OK: qeth_notify_skbs(queue, buffer, TX_NOTIFY_DELAYED_OK); - atomic_set(&buffer->state, - QETH_QDIO_BUF_HANDLED_DELAYED); + error = false; break; case QETH_QDIO_BUF_QAOB_ERROR: qeth_notify_skbs(queue, buffer, TX_NOTIFY_DELAYED_GENERALERROR); - atomic_set(&buffer->state, - QETH_QDIO_BUF_HANDLED_DELAYED); + error = true; break; default: WARN_ON_ONCE(1); } - } - - QETH_CARD_TEXT_(card, 5, "pel%u", bidx);
- /* prepare the queue slot for re-use: */ - qeth_scrub_qdio_buffer(buffer->buffer, queue->max_elements); - if (qeth_init_qdio_out_buf(queue, bidx)) { - QETH_CARD_TEXT(card, 2, "outofbuf"); - qeth_schedule_recovery(card); + break; + case QETH_QDIO_BUF_QAOB_OK: + /* qeth_qdio_handle_aob() already received a QAOB: */ + qeth_notify_skbs(queue, buffer, TX_NOTIFY_OK); + error = false; + break; + case QETH_QDIO_BUF_QAOB_ERROR: + /* qeth_qdio_handle_aob() already received a QAOB: */ + qeth_notify_skbs(queue, buffer, TX_NOTIFY_GENERALERROR); + error = true; + break; + default: + WARN_ON_ONCE(1); } - - return; - } - - if (card->options.cq == QETH_CQ_ENABLED) + } else if (card->options.cq == QETH_CQ_ENABLED) { qeth_notify_skbs(queue, buffer, qeth_compute_cq_notification(sflags, 0)); + } + qeth_clear_output_buffer(queue, buffer, error, budget); }
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Julian Wiedmann jwi@linux.ibm.com
[ Upstream commit 75cf3854dcdf7b5c583538cae12ffa054d237d93 ]
Reuse the QETH_QDIO_BUF_EMPTY state to indicate that a TX buffer has been completed with a QAOB notification, and may be cleaned up by qeth_cleanup_handled_pending().
Signed-off-by: Julian Wiedmann jwi@linux.ibm.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/s390/net/qeth_core.h | 2 -- drivers/s390/net/qeth_core_main.c | 5 ++--- 2 files changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index 2f7e06ec9a30..ea969b8fe687 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -424,8 +424,6 @@ enum qeth_qdio_out_buffer_state { /* Received QAOB notification on CQ: */ QETH_QDIO_BUF_QAOB_OK, QETH_QDIO_BUF_QAOB_ERROR, - /* Handled via transfer pending / completion queue. */ - QETH_QDIO_BUF_HANDLED_DELAYED, };
struct qeth_qdio_out_buffer { diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 78a866424022..e2cdb5c2fc66 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -477,8 +477,7 @@ static void qeth_cleanup_handled_pending(struct qeth_qdio_out_q *q, int bidx,
while (c) { if (forced_cleanup || - atomic_read(&c->state) == - QETH_QDIO_BUF_HANDLED_DELAYED) { + atomic_read(&c->state) == QETH_QDIO_BUF_EMPTY) { struct qeth_qdio_out_buffer *f = c;
QETH_CARD_TEXT(f->q->card, 5, "fp"); @@ -549,7 +548,7 @@ static void qeth_qdio_handle_aob(struct qeth_card *card, kmem_cache_free(qeth_core_header_cache, data); }
- atomic_set(&buffer->state, QETH_QDIO_BUF_HANDLED_DELAYED); + atomic_set(&buffer->state, QETH_QDIO_BUF_EMPTY); break; default: WARN_ON_ONCE(1);
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Julian Wiedmann jwi@linux.ibm.com
[ Upstream commit c20383ad1656b0f6354dd50e4acd894f9d94090d ]
The current design attaches a pending TX buffer to a custom single-linked list, which is anchored at the buffer's slot on the TX ring. The buffer is then checked for final completion whenever this slot is processed during a subsequent TX NAPI poll cycle.
But if there's insufficient traffic on the ring, we might never make enough progress to get back to this ring slot and discover the pending buffer's final TX completion. In particular if this missing TX completion blocks the application from sending further traffic.
So convert the custom single-linked list code to a per-queue list_head, and scan this list on every TX NAPI cycle.
Fixes: 0da9581ddb0f ("qeth: exploit asynchronous delivery of storage blocks") Signed-off-by: Julian Wiedmann jwi@linux.ibm.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/s390/net/qeth_core.h | 3 +- drivers/s390/net/qeth_core_main.c | 69 +++++++++++++------------------ 2 files changed, 30 insertions(+), 42 deletions(-)
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index ea969b8fe687..bf8404b0e74f 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -436,7 +436,7 @@ struct qeth_qdio_out_buffer { int is_header[QDIO_MAX_ELEMENTS_PER_BUFFER];
struct qeth_qdio_out_q *q; - struct qeth_qdio_out_buffer *next_pending; + struct list_head list_entry; };
struct qeth_card; @@ -500,6 +500,7 @@ struct qeth_qdio_out_q { struct qdio_buffer *qdio_bufs[QDIO_MAX_BUFFERS_PER_Q]; struct qeth_qdio_out_buffer *bufs[QDIO_MAX_BUFFERS_PER_Q]; struct qdio_outbuf_state *bufstates; /* convenience pointer */ + struct list_head pending_bufs; struct qeth_out_q_stats stats; spinlock_t lock; unsigned int priority; diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index e2cdb5c2fc66..db785030293b 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -73,8 +73,6 @@ static void qeth_free_qdio_queues(struct qeth_card *card); static void qeth_notify_skbs(struct qeth_qdio_out_q *queue, struct qeth_qdio_out_buffer *buf, enum iucv_tx_notify notification); -static void qeth_tx_complete_buf(struct qeth_qdio_out_buffer *buf, bool error, - int budget);
static void qeth_close_dev_handler(struct work_struct *work) { @@ -465,41 +463,6 @@ static enum iucv_tx_notify qeth_compute_cq_notification(int sbalf15, return n; }
-static void qeth_cleanup_handled_pending(struct qeth_qdio_out_q *q, int bidx, - int forced_cleanup) -{ - if (q->card->options.cq != QETH_CQ_ENABLED) - return; - - if (q->bufs[bidx]->next_pending != NULL) { - struct qeth_qdio_out_buffer *head = q->bufs[bidx]; - struct qeth_qdio_out_buffer *c = q->bufs[bidx]->next_pending; - - while (c) { - if (forced_cleanup || - atomic_read(&c->state) == QETH_QDIO_BUF_EMPTY) { - struct qeth_qdio_out_buffer *f = c; - - QETH_CARD_TEXT(f->q->card, 5, "fp"); - QETH_CARD_TEXT_(f->q->card, 5, "%lx", (long) f); - /* release here to avoid interleaving between - outbound tasklet and inbound tasklet - regarding notifications and lifecycle */ - qeth_tx_complete_buf(c, forced_cleanup, 0); - - c = f->next_pending; - WARN_ON_ONCE(head->next_pending != f); - head->next_pending = c; - kmem_cache_free(qeth_qdio_outbuf_cache, f); - } else { - head = c; - c = c->next_pending; - } - - } - } -} - static void qeth_qdio_handle_aob(struct qeth_card *card, unsigned long phys_aob_addr) { @@ -537,7 +500,7 @@ static void qeth_qdio_handle_aob(struct qeth_card *card, qeth_notify_skbs(buffer->q, buffer, notification);
/* Free dangling allocations. The attached skbs are handled by - * qeth_cleanup_handled_pending(). + * qeth_tx_complete_pending_bufs(). */ for (i = 0; i < aob->sb_count && i < QETH_MAX_BUFFER_ELEMENTS(card); @@ -1484,14 +1447,35 @@ static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue, atomic_set(&buf->state, QETH_QDIO_BUF_EMPTY); }
+static void qeth_tx_complete_pending_bufs(struct qeth_card *card, + struct qeth_qdio_out_q *queue, + bool drain) +{ + struct qeth_qdio_out_buffer *buf, *tmp; + + list_for_each_entry_safe(buf, tmp, &queue->pending_bufs, list_entry) { + if (drain || atomic_read(&buf->state) == QETH_QDIO_BUF_EMPTY) { + QETH_CARD_TEXT(card, 5, "fp"); + QETH_CARD_TEXT_(card, 5, "%lx", (long) buf); + + qeth_tx_complete_buf(buf, drain, 0); + + list_del(&buf->list_entry); + kmem_cache_free(qeth_qdio_outbuf_cache, buf); + } + } +} + static void qeth_drain_output_queue(struct qeth_qdio_out_q *q, bool free) { int j;
+ qeth_tx_complete_pending_bufs(q->card, q, true); + for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j) { if (!q->bufs[j]) continue; - qeth_cleanup_handled_pending(q, j, 1); + qeth_clear_output_buffer(q, q->bufs[j], true, 0); if (free) { kmem_cache_free(qeth_qdio_outbuf_cache, q->bufs[j]); @@ -2611,7 +2595,6 @@ static int qeth_init_qdio_out_buf(struct qeth_qdio_out_q *q, int bidx) skb_queue_head_init(&newbuf->skb_list); lockdep_set_class(&newbuf->skb_list.lock, &qdio_out_skb_queue_key); newbuf->q = q; - newbuf->next_pending = q->bufs[bidx]; atomic_set(&newbuf->state, QETH_QDIO_BUF_EMPTY); q->bufs[bidx] = newbuf; return 0; @@ -2693,6 +2676,7 @@ static int qeth_alloc_qdio_queues(struct qeth_card *card) card->qdio.out_qs[i] = queue; queue->card = card; queue->queue_no = i; + INIT_LIST_HEAD(&queue->pending_bufs); spin_lock_init(&queue->lock); timer_setup(&queue->timer, qeth_tx_completion_timer, 0); queue->coalesce_usecs = QETH_TX_COALESCE_USECS; @@ -5890,6 +5874,8 @@ static void qeth_iqd_tx_complete(struct qeth_qdio_out_q *queue, qeth_schedule_recovery(card); }
+ list_add(&buffer->list_entry, + &queue->pending_bufs); /* Skip clearing the buffer: */ return; case QETH_QDIO_BUF_QAOB_OK: @@ -5945,6 +5931,8 @@ static int qeth_tx_poll(struct napi_struct *napi, int budget) unsigned int bytes = 0; int completed;
+ qeth_tx_complete_pending_bufs(card, queue, false); + if (qeth_out_queue_is_empty(queue)) { napi_complete(napi); return 0; @@ -5977,7 +5965,6 @@ static int qeth_tx_poll(struct napi_struct *napi, int budget)
qeth_handle_send_error(card, buffer, error); qeth_iqd_tx_complete(queue, bidx, error, budget); - qeth_cleanup_handled_pending(queue, bidx, false); }
netdev_tx_completed_queue(txq, packets, bytes);
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Julian Wiedmann jwi@linux.ibm.com
[ Upstream commit 7eefda7f353ef86ad82a2dc8329e8a3538c08ab6 ]
The cited commit reworked the state machine for pending TX buffers. In qeth_iqd_tx_complete() it turned PENDING into a transient state, and uses NEED_QAOB for buffers that get parked while waiting for their QAOB completion.
But it missed to adjust the check in qeth_tx_complete_buf(). So if qeth_tx_complete_pending_bufs() is called during teardown to drain the parked TX buffers, we no longer raise a notification for af_iucv.
Instead of updating the checked state, just move this code into qeth_tx_complete_pending_bufs() itself. This also gets rid of the special-case in the common TX completion path.
Fixes: 8908f36d20d8 ("s390/qeth: fix af_iucv notification race") Signed-off-by: Julian Wiedmann jwi@linux.ibm.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/s390/net/qeth_core_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index db785030293b..03f96177e58e 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -1383,9 +1383,6 @@ static void qeth_tx_complete_buf(struct qeth_qdio_out_buffer *buf, bool error, struct qeth_qdio_out_q *queue = buf->q; struct sk_buff *skb;
- if (atomic_read(&buf->state) == QETH_QDIO_BUF_PENDING) - qeth_notify_skbs(queue, buf, TX_NOTIFY_GENERALERROR); - /* Empty buffer? */ if (buf->next_element_to_fill == 0) return; @@ -1458,6 +1455,9 @@ static void qeth_tx_complete_pending_bufs(struct qeth_card *card, QETH_CARD_TEXT(card, 5, "fp"); QETH_CARD_TEXT_(card, 5, "%lx", (long) buf);
+ if (drain) + qeth_notify_skbs(queue, buf, + TX_NOTIFY_GENERALERROR); qeth_tx_complete_buf(buf, drain, 0);
list_del(&buf->list_entry);
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Vladimir Oltean vladimir.oltean@nxp.com
[ Upstream commit a3b0b6479700a5b0af2c631cb2ec0fb7a0d978f2 ]
At the moment, taggers are left with the task of ensuring that the skb headers are writable (which they aren't, if the frames were cloned for TX timestamping, for flooding by the bridge, etc), and that there is enough space in the skb data area for the DSA tag to be pushed.
Moreover, the life of tail taggers is even harder, because they need to ensure that short frames have enough padding, a problem that normal taggers don't have.
The principle of the DSA framework is that everything except for the most intimate hardware specifics (like in this case, the actual packing of the DSA tag bits) should be done inside the core, to avoid having code paths that are very rarely tested.
So provide a TX reallocation procedure that should cover the known needs of DSA today.
Note that this patch also gives the network stack a good hint about the headroom/tailroom it's going to need. Up till now it wasn't doing that. So the reallocation procedure should really be there only for the exceptional cases, and for cloned packets which need to be unshared.
Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Tested-by: Christian Eggers ceggers@arri.de # For tail taggers only Tested-by: Kurt Kanzenbach kurt@linutronix.de Reviewed-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/dsa/slave.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+)
diff --git a/net/dsa/slave.c b/net/dsa/slave.c index 3bc5ca40c9fb..c6806eef906f 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -548,6 +548,30 @@ netdev_tx_t dsa_enqueue_skb(struct sk_buff *skb, struct net_device *dev) } EXPORT_SYMBOL_GPL(dsa_enqueue_skb);
+static int dsa_realloc_skb(struct sk_buff *skb, struct net_device *dev) +{ + int needed_headroom = dev->needed_headroom; + int needed_tailroom = dev->needed_tailroom; + + /* For tail taggers, we need to pad short frames ourselves, to ensure + * that the tail tag does not fail at its role of being at the end of + * the packet, once the master interface pads the frame. Account for + * that pad length here, and pad later. + */ + if (unlikely(needed_tailroom && skb->len < ETH_ZLEN)) + needed_tailroom += ETH_ZLEN - skb->len; + /* skb_headroom() returns unsigned int... */ + needed_headroom = max_t(int, needed_headroom - skb_headroom(skb), 0); + needed_tailroom = max_t(int, needed_tailroom - skb_tailroom(skb), 0); + + if (likely(!needed_headroom && !needed_tailroom && !skb_cloned(skb))) + /* No reallocation needed, yay! */ + return 0; + + return pskb_expand_head(skb, needed_headroom, needed_tailroom, + GFP_ATOMIC); +} + static netdev_tx_t dsa_slave_xmit(struct sk_buff *skb, struct net_device *dev) { struct dsa_slave_priv *p = netdev_priv(dev); @@ -567,6 +591,17 @@ static netdev_tx_t dsa_slave_xmit(struct sk_buff *skb, struct net_device *dev) */ dsa_skb_tx_timestamp(p, skb);
+ if (dsa_realloc_skb(skb, dev)) { + dev_kfree_skb_any(skb); + return NETDEV_TX_OK; + } + + /* needed_tailroom should still be 'warm' in the cache line from + * dsa_realloc_skb(), which has also ensured that padding is safe. + */ + if (dev->needed_tailroom) + eth_skb_pad(skb); + /* Transmit function may have to reallocate the original SKB, * in which case it must have freed it. Only free it here on error. */ @@ -1791,6 +1826,16 @@ int dsa_slave_create(struct dsa_port *port) slave_dev->netdev_ops = &dsa_slave_netdev_ops; if (ds->ops->port_max_mtu) slave_dev->max_mtu = ds->ops->port_max_mtu(ds, port->index); + if (cpu_dp->tag_ops->tail_tag) + slave_dev->needed_tailroom = cpu_dp->tag_ops->overhead; + else + slave_dev->needed_headroom = cpu_dp->tag_ops->overhead; + /* Try to save one extra realloc later in the TX path (in the master) + * by also inheriting the master's needed headroom and tailroom. + * The 8021q driver also does this. + */ + slave_dev->needed_headroom += master->needed_headroom; + slave_dev->needed_tailroom += master->needed_tailroom; SET_NETDEV_DEVTYPE(slave_dev, &dsa_type);
netdev_for_each_tx_queue(slave_dev, dsa_slave_set_lockdep_class_one,
+Andrew, Vivien,
On Mon, Mar 15, 2021 at 02:53:26PM +0100, gregkh@linuxfoundation.org wrote:
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Vladimir Oltean vladimir.oltean@nxp.com
[ Upstream commit a3b0b6479700a5b0af2c631cb2ec0fb7a0d978f2 ]
At the moment, taggers are left with the task of ensuring that the skb headers are writable (which they aren't, if the frames were cloned for TX timestamping, for flooding by the bridge, etc), and that there is enough space in the skb data area for the DSA tag to be pushed.
Moreover, the life of tail taggers is even harder, because they need to ensure that short frames have enough padding, a problem that normal taggers don't have.
The principle of the DSA framework is that everything except for the most intimate hardware specifics (like in this case, the actual packing of the DSA tag bits) should be done inside the core, to avoid having code paths that are very rarely tested.
So provide a TX reallocation procedure that should cover the known needs of DSA today.
Note that this patch also gives the network stack a good hint about the headroom/tailroom it's going to need. Up till now it wasn't doing that. So the reallocation procedure should really be there only for the exceptional cases, and for cloned packets which need to be unshared.
Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Tested-by: Christian Eggers ceggers@arri.de # For tail taggers only Tested-by: Kurt Kanzenbach kurt@linutronix.de Reviewed-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org
For context, Sasha explains here: https://www.spinics.net/lists/stable-commits/msg190151.html (the conversation is somewhat truncated, unfortunately, because stable-commits@vger.kernel.org ate my replies) that 13 patches were backported to get the unrelated commit 9200f515c41f ("net: dsa: tag_mtk: fix 802.1ad VLAN egress") to apply cleanly with git-am.
I am not strictly against this, even though I would have liked to know that the maintainers were explicitly informed about it.
Greg, could you make your stable backporting emails include the output of ./get_maintainer.pl into the list of recipients? Thanks.
On Mon, Mar 15, 2021 at 07:56:02PM +0000, Vladimir Oltean wrote:
Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Tested-by: Christian Eggers ceggers@arri.de # For tail taggers only Tested-by: Kurt Kanzenbach kurt@linutronix.de Reviewed-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org
For context, Sasha explains here: https://www.spinics.net/lists/stable-commits/msg190151.html (the conversation is somewhat truncated, unfortunately, because stable-commits@vger.kernel.org ate my replies) that 13 patches were backported to get the unrelated commit 9200f515c41f ("net: dsa: tag_mtk: fix 802.1ad VLAN egress") to apply cleanly with git-am.
I am not strictly against this, even though I would have liked to know that the maintainers were explicitly informed about it.
Greg, could you make your stable backporting emails include the output of ./get_maintainer.pl into the list of recipients? Thanks.
Did it not happen here? I've looked at Greg's script[1] and it seemed to me like it does go through get_maintainer.pl.
[1] https://github.com/gregkh/gregkh-linux/blob/master/scripts/generate_cc_list
On Mon, Mar 15, 2021 at 05:06:16PM -0400, Sasha Levin wrote:
On Mon, Mar 15, 2021 at 07:56:02PM +0000, Vladimir Oltean wrote:
Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Tested-by: Christian Eggers ceggers@arri.de # For tail taggers only Tested-by: Kurt Kanzenbach kurt@linutronix.de Reviewed-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org
For context, Sasha explains here: https://www.spinics.net/lists/stable-commits/msg190151.html (the conversation is somewhat truncated, unfortunately, because stable-commits@vger.kernel.org ate my replies) that 13 patches were backported to get the unrelated commit 9200f515c41f ("net: dsa: tag_mtk: fix 802.1ad VLAN egress") to apply cleanly with git-am.
I am not strictly against this, even though I would have liked to know that the maintainers were explicitly informed about it.
Greg, could you make your stable backporting emails include the output of ./get_maintainer.pl into the list of recipients? Thanks.
Did it not happen here? I've looked at Greg's script[1] and it seemed to me like it does go through get_maintainer.pl.
[1] https://github.com/gregkh/gregkh-linux/blob/master/scripts/generate_cc_list
That's just a script I use for "normal" kernel development when creating patches, not for stable stuff.
thanks,
greg k-h
On Mon, Mar 15, 2021 at 07:56:02PM +0000, Vladimir Oltean wrote:
+Andrew, Vivien,
On Mon, Mar 15, 2021 at 02:53:26PM +0100, gregkh@linuxfoundation.org wrote:
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Vladimir Oltean vladimir.oltean@nxp.com
[ Upstream commit a3b0b6479700a5b0af2c631cb2ec0fb7a0d978f2 ]
At the moment, taggers are left with the task of ensuring that the skb headers are writable (which they aren't, if the frames were cloned for TX timestamping, for flooding by the bridge, etc), and that there is enough space in the skb data area for the DSA tag to be pushed.
Moreover, the life of tail taggers is even harder, because they need to ensure that short frames have enough padding, a problem that normal taggers don't have.
The principle of the DSA framework is that everything except for the most intimate hardware specifics (like in this case, the actual packing of the DSA tag bits) should be done inside the core, to avoid having code paths that are very rarely tested.
So provide a TX reallocation procedure that should cover the known needs of DSA today.
Note that this patch also gives the network stack a good hint about the headroom/tailroom it's going to need. Up till now it wasn't doing that. So the reallocation procedure should really be there only for the exceptional cases, and for cloned packets which need to be unshared.
Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Tested-by: Christian Eggers ceggers@arri.de # For tail taggers only Tested-by: Kurt Kanzenbach kurt@linutronix.de Reviewed-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org
For context, Sasha explains here: https://www.spinics.net/lists/stable-commits/msg190151.html (the conversation is somewhat truncated, unfortunately, because stable-commits@vger.kernel.org ate my replies) that 13 patches were backported to get the unrelated commit 9200f515c41f ("net: dsa: tag_mtk: fix 802.1ad VLAN egress") to apply cleanly with git-am.
I am not strictly against this, even though I would have liked to know that the maintainers were explicitly informed about it.
Greg, could you make your stable backporting emails include the output of ./get_maintainer.pl into the list of recipients? Thanks.
I cc: everyone on the signed-off-by list on the patch, why would we need to add more? A maintainer should always be on that list automatically.
thanks,
greg k-h
On Tue, Mar 16, 2021 at 06:46:10AM +0100, gregkh@linuxfoundation.org wrote:
On Mon, Mar 15, 2021 at 07:56:02PM +0000, Vladimir Oltean wrote:
+Andrew, Vivien,
On Mon, Mar 15, 2021 at 02:53:26PM +0100, gregkh@linuxfoundation.org wrote:
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Vladimir Oltean vladimir.oltean@nxp.com
[ Upstream commit a3b0b6479700a5b0af2c631cb2ec0fb7a0d978f2 ]
At the moment, taggers are left with the task of ensuring that the skb headers are writable (which they aren't, if the frames were cloned for TX timestamping, for flooding by the bridge, etc), and that there is enough space in the skb data area for the DSA tag to be pushed.
Moreover, the life of tail taggers is even harder, because they need to ensure that short frames have enough padding, a problem that normal taggers don't have.
The principle of the DSA framework is that everything except for the most intimate hardware specifics (like in this case, the actual packing of the DSA tag bits) should be done inside the core, to avoid having code paths that are very rarely tested.
So provide a TX reallocation procedure that should cover the known needs of DSA today.
Note that this patch also gives the network stack a good hint about the headroom/tailroom it's going to need. Up till now it wasn't doing that. So the reallocation procedure should really be there only for the exceptional cases, and for cloned packets which need to be unshared.
Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Tested-by: Christian Eggers ceggers@arri.de # For tail taggers only Tested-by: Kurt Kanzenbach kurt@linutronix.de Reviewed-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org
For context, Sasha explains here: https://www.spinics.net/lists/stable-commits/msg190151.html (the conversation is somewhat truncated, unfortunately, because stable-commits@vger.kernel.org ate my replies) that 13 patches were backported to get the unrelated commit 9200f515c41f ("net: dsa: tag_mtk: fix 802.1ad VLAN egress") to apply cleanly with git-am.
I am not strictly against this, even though I would have liked to know that the maintainers were explicitly informed about it.
Greg, could you make your stable backporting emails include the output of ./get_maintainer.pl into the list of recipients? Thanks.
I cc: everyone on the signed-off-by list on the patch, why would we need to add more? A maintainer should always be on that list automatically.
Oh, hm, could this be an issue with subsystems that have a shared maintainership model? In that scenario not all maintainers will sign-off on a commit.
On Tue, Mar 16, 2021 at 09:54:01AM -0400, Sasha Levin wrote:
On Tue, Mar 16, 2021 at 06:46:10AM +0100, gregkh@linuxfoundation.org wrote:
On Mon, Mar 15, 2021 at 07:56:02PM +0000, Vladimir Oltean wrote:
+Andrew, Vivien,
On Mon, Mar 15, 2021 at 02:53:26PM +0100, gregkh@linuxfoundation.org wrote:
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Vladimir Oltean vladimir.oltean@nxp.com
[ Upstream commit a3b0b6479700a5b0af2c631cb2ec0fb7a0d978f2 ]
At the moment, taggers are left with the task of ensuring that the skb headers are writable (which they aren't, if the frames were cloned for TX timestamping, for flooding by the bridge, etc), and that there is enough space in the skb data area for the DSA tag to be pushed.
Moreover, the life of tail taggers is even harder, because they need to ensure that short frames have enough padding, a problem that normal taggers don't have.
The principle of the DSA framework is that everything except for the most intimate hardware specifics (like in this case, the actual packing of the DSA tag bits) should be done inside the core, to avoid having code paths that are very rarely tested.
So provide a TX reallocation procedure that should cover the known needs of DSA today.
Note that this patch also gives the network stack a good hint about the headroom/tailroom it's going to need. Up till now it wasn't doing that. So the reallocation procedure should really be there only for the exceptional cases, and for cloned packets which need to be unshared.
Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Tested-by: Christian Eggers ceggers@arri.de # For tail taggers only Tested-by: Kurt Kanzenbach kurt@linutronix.de Reviewed-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org
For context, Sasha explains here: https://www.spinics.net/lists/stable-commits/msg190151.html (the conversation is somewhat truncated, unfortunately, because stable-commits@vger.kernel.org ate my replies) that 13 patches were backported to get the unrelated commit 9200f515c41f ("net: dsa: tag_mtk: fix 802.1ad VLAN egress") to apply cleanly with git-am.
I am not strictly against this, even though I would have liked to know that the maintainers were explicitly informed about it.
Greg, could you make your stable backporting emails include the output of ./get_maintainer.pl into the list of recipients? Thanks.
I cc: everyone on the signed-off-by list on the patch, why would we need to add more? A maintainer should always be on that list automatically.
Oh, hm, could this be an issue with subsystems that have a shared maintainership model? In that scenario not all maintainers will sign-off on a commit.
So a shared maintainer trusts their co-maintainer for reviewing patches for Linus's tree and all future kernels, but NOT into an old backported stable tree? I doubt that, trust should be the same for both.
thanks,
greg k-h
On Tue, Mar 16, 2021 at 05:05:11PM +0100, gregkh@linuxfoundation.org wrote:
On Tue, Mar 16, 2021 at 09:54:01AM -0400, Sasha Levin wrote:
On Tue, Mar 16, 2021 at 06:46:10AM +0100, gregkh@linuxfoundation.org wrote:
I cc: everyone on the signed-off-by list on the patch, why would we need to add more? A maintainer should always be on that list automatically.
Oh, hm, could this be an issue with subsystems that have a shared maintainership model? In that scenario not all maintainers will sign-off on a commit.
So a shared maintainer trusts their co-maintainer for reviewing patches for Linus's tree and all future kernels, but NOT into an old backported stable tree? I doubt that, trust should be the same for both.
I don't think it's necessarily a trust issue, but is an availability issue: one of the reasons shared maintainership models exist is so that one maintainer can go on vacation (or focus other work) while the other maintainer(s) take over. If we send a review request to that maintainer he might be away and we'll never get our review.
On Tue, Mar 16, 2021 at 05:05:11PM +0100, gregkh@linuxfoundation.org wrote:
On Tue, Mar 16, 2021 at 09:54:01AM -0400, Sasha Levin wrote:
On Tue, Mar 16, 2021 at 06:46:10AM +0100, gregkh@linuxfoundation.org wrote:
On Mon, Mar 15, 2021 at 07:56:02PM +0000, Vladimir Oltean wrote:
+Andrew, Vivien,
On Mon, Mar 15, 2021 at 02:53:26PM +0100, gregkh@linuxfoundation.org wrote:
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Vladimir Oltean vladimir.oltean@nxp.com
[ Upstream commit a3b0b6479700a5b0af2c631cb2ec0fb7a0d978f2 ]
At the moment, taggers are left with the task of ensuring that the skb headers are writable (which they aren't, if the frames were cloned for TX timestamping, for flooding by the bridge, etc), and that there is enough space in the skb data area for the DSA tag to be pushed.
Moreover, the life of tail taggers is even harder, because they need to ensure that short frames have enough padding, a problem that normal taggers don't have.
The principle of the DSA framework is that everything except for the most intimate hardware specifics (like in this case, the actual packing of the DSA tag bits) should be done inside the core, to avoid having code paths that are very rarely tested.
So provide a TX reallocation procedure that should cover the known needs of DSA today.
Note that this patch also gives the network stack a good hint about the headroom/tailroom it's going to need. Up till now it wasn't doing that. So the reallocation procedure should really be there only for the exceptional cases, and for cloned packets which need to be unshared.
Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Tested-by: Christian Eggers ceggers@arri.de # For tail taggers only Tested-by: Kurt Kanzenbach kurt@linutronix.de Reviewed-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org
For context, Sasha explains here: https://www.spinics.net/lists/stable-commits/msg190151.html (the conversation is somewhat truncated, unfortunately, because stable-commits@vger.kernel.org ate my replies) that 13 patches were backported to get the unrelated commit 9200f515c41f ("net: dsa: tag_mtk: fix 802.1ad VLAN egress") to apply cleanly with git-am.
I am not strictly against this, even though I would have liked to know that the maintainers were explicitly informed about it.
Greg, could you make your stable backporting emails include the output of ./get_maintainer.pl into the list of recipients? Thanks.
I cc: everyone on the signed-off-by list on the patch, why would we need to add more? A maintainer should always be on that list automatically.
Oh, hm, could this be an issue with subsystems that have a shared maintainership model? In that scenario not all maintainers will sign-off on a commit.
So a shared maintainer trusts their co-maintainer for reviewing patches for Linus's tree and all future kernels, but NOT into an old backported stable tree? I doubt that, trust should be the same for both.
Greg, the problem is that we have the following maintainership layout:
General networking maintainers (David Miller && Jakub Kicinski) -> DSA framework maintainers -> DSA hardware driver maintainers
But there is a single tree with mandatory sign-off from a single maintainer, and that would be David or Jakub. And in rare cases it may happen for patches to get accepted without the written ACK of any of the sub-maintainers.
If the question is whether I trust David or Jakub to pay attention on why are 13 patches that don't fix anything being backported to stable, and then take the time to check/test whether anything is going to be broken in subtle ways because code was backported in places it was never meant to belong, then yeah, sorry, but no.
In this case, things could have gone a lot worse: the model you're following makes it possible to backport a breaking change into a subsystem and the maintainer can never find out until there'a a bug report.
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Christian Eggers ceggers@arri.de
[ Upstream commit 88fda8eefd9a7a7175bf4dad1d02cc0840581111 ]
The caller (dsa_slave_xmit) guarantees that the frame length is at least ETH_ZLEN and that enough memory for tail tagging is available.
Signed-off-by: Christian Eggers ceggers@arri.de Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Reviewed-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/dsa/tag_ksz.c | 73 ++++++----------------------------------------- 1 file changed, 9 insertions(+), 64 deletions(-)
diff --git a/net/dsa/tag_ksz.c b/net/dsa/tag_ksz.c index 0a5aa982c60d..4820dbcedfa2 100644 --- a/net/dsa/tag_ksz.c +++ b/net/dsa/tag_ksz.c @@ -14,46 +14,6 @@ #define KSZ_EGRESS_TAG_LEN 1 #define KSZ_INGRESS_TAG_LEN 1
-static struct sk_buff *ksz_common_xmit(struct sk_buff *skb, - struct net_device *dev, int len) -{ - struct sk_buff *nskb; - int padlen; - - padlen = (skb->len >= ETH_ZLEN) ? 0 : ETH_ZLEN - skb->len; - - if (skb_tailroom(skb) >= padlen + len) { - /* Let dsa_slave_xmit() free skb */ - if (__skb_put_padto(skb, skb->len + padlen, false)) - return NULL; - - nskb = skb; - } else { - nskb = alloc_skb(NET_IP_ALIGN + skb->len + - padlen + len, GFP_ATOMIC); - if (!nskb) - return NULL; - skb_reserve(nskb, NET_IP_ALIGN); - - skb_reset_mac_header(nskb); - skb_set_network_header(nskb, - skb_network_header(skb) - skb->head); - skb_set_transport_header(nskb, - skb_transport_header(skb) - skb->head); - skb_copy_and_csum_dev(skb, skb_put(nskb, skb->len)); - - /* Let skb_put_padto() free nskb, and let dsa_slave_xmit() free - * skb - */ - if (skb_put_padto(nskb, nskb->len + padlen)) - return NULL; - - consume_skb(skb); - } - - return nskb; -} - static struct sk_buff *ksz_common_rcv(struct sk_buff *skb, struct net_device *dev, unsigned int port, unsigned int len) @@ -90,23 +50,18 @@ static struct sk_buff *ksz_common_rcv(struct sk_buff *skb, static struct sk_buff *ksz8795_xmit(struct sk_buff *skb, struct net_device *dev) { struct dsa_port *dp = dsa_slave_to_port(dev); - struct sk_buff *nskb; u8 *tag; u8 *addr;
- nskb = ksz_common_xmit(skb, dev, KSZ_INGRESS_TAG_LEN); - if (!nskb) - return NULL; - /* Tag encoding */ - tag = skb_put(nskb, KSZ_INGRESS_TAG_LEN); - addr = skb_mac_header(nskb); + tag = skb_put(skb, KSZ_INGRESS_TAG_LEN); + addr = skb_mac_header(skb);
*tag = 1 << dp->index; if (is_link_local_ether_addr(addr)) *tag |= KSZ8795_TAIL_TAG_OVERRIDE;
- return nskb; + return skb; }
static struct sk_buff *ksz8795_rcv(struct sk_buff *skb, struct net_device *dev, @@ -156,18 +111,13 @@ static struct sk_buff *ksz9477_xmit(struct sk_buff *skb, struct net_device *dev) { struct dsa_port *dp = dsa_slave_to_port(dev); - struct sk_buff *nskb; __be16 *tag; u8 *addr; u16 val;
- nskb = ksz_common_xmit(skb, dev, KSZ9477_INGRESS_TAG_LEN); - if (!nskb) - return NULL; - /* Tag encoding */ - tag = skb_put(nskb, KSZ9477_INGRESS_TAG_LEN); - addr = skb_mac_header(nskb); + tag = skb_put(skb, KSZ9477_INGRESS_TAG_LEN); + addr = skb_mac_header(skb);
val = BIT(dp->index);
@@ -176,7 +126,7 @@ static struct sk_buff *ksz9477_xmit(struct sk_buff *skb,
*tag = cpu_to_be16(val);
- return nskb; + return skb; }
static struct sk_buff *ksz9477_rcv(struct sk_buff *skb, struct net_device *dev, @@ -213,24 +163,19 @@ static struct sk_buff *ksz9893_xmit(struct sk_buff *skb, struct net_device *dev) { struct dsa_port *dp = dsa_slave_to_port(dev); - struct sk_buff *nskb; u8 *addr; u8 *tag;
- nskb = ksz_common_xmit(skb, dev, KSZ_INGRESS_TAG_LEN); - if (!nskb) - return NULL; - /* Tag encoding */ - tag = skb_put(nskb, KSZ_INGRESS_TAG_LEN); - addr = skb_mac_header(nskb); + tag = skb_put(skb, KSZ_INGRESS_TAG_LEN); + addr = skb_mac_header(skb);
*tag = BIT(dp->index);
if (is_link_local_ether_addr(addr)) *tag |= KSZ9893_TAIL_TAG_OVERRIDE;
- return nskb; + return skb; }
static const struct dsa_device_ops ksz9893_netdev_ops = {
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Christian Eggers ceggers@arri.de
[ Upstream commit ef3f72fee286bd270453ce2344feb7295a798508 ]
The caller (dsa_slave_xmit) guarantees that the frame length is at least ETH_ZLEN and that enough memory for tail tagging is available.
Signed-off-by: Christian Eggers ceggers@arri.de Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Reviewed-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/dsa/tag_trailer.c | 31 ++----------------------------- 1 file changed, 2 insertions(+), 29 deletions(-)
diff --git a/net/dsa/tag_trailer.c b/net/dsa/tag_trailer.c index 3a1cc24a4f0a..5b97ede56a0f 100644 --- a/net/dsa/tag_trailer.c +++ b/net/dsa/tag_trailer.c @@ -13,42 +13,15 @@ static struct sk_buff *trailer_xmit(struct sk_buff *skb, struct net_device *dev) { struct dsa_port *dp = dsa_slave_to_port(dev); - struct sk_buff *nskb; - int padlen; u8 *trailer;
- /* - * We have to make sure that the trailer ends up as the very - * last 4 bytes of the packet. This means that we have to pad - * the packet to the minimum ethernet frame size, if necessary, - * before adding the trailer. - */ - padlen = 0; - if (skb->len < 60) - padlen = 60 - skb->len; - - nskb = alloc_skb(NET_IP_ALIGN + skb->len + padlen + 4, GFP_ATOMIC); - if (!nskb) - return NULL; - skb_reserve(nskb, NET_IP_ALIGN); - - skb_reset_mac_header(nskb); - skb_set_network_header(nskb, skb_network_header(skb) - skb->head); - skb_set_transport_header(nskb, skb_transport_header(skb) - skb->head); - skb_copy_and_csum_dev(skb, skb_put(nskb, skb->len)); - consume_skb(skb); - - if (padlen) { - skb_put_zero(nskb, padlen); - } - - trailer = skb_put(nskb, 4); + trailer = skb_put(skb, 4); trailer[0] = 0x80; trailer[1] = 1 << dp->index; trailer[2] = 0x10; trailer[3] = 0x00;
- return nskb; + return skb; }
static struct sk_buff *trailer_rcv(struct sk_buff *skb, struct net_device *dev,
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Vladimir Oltean vladimir.oltean@nxp.com
[ Upstream commit 9bbda29ae1044bc4c1c01a5b7c44688c4765785f ]
Now that we have a central TX reallocation procedure that accounts for the tagger's needed headroom in a generic way, we can remove the skb_cow_head call.
Cc: John Crispin john@phrozen.org Cc: Alexander Lobakin alobakin@pm.me Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Reviewed-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/dsa/tag_qca.c | 3 --- 1 file changed, 3 deletions(-)
diff --git a/net/dsa/tag_qca.c b/net/dsa/tag_qca.c index 1b9e8507112b..88181b52f480 100644 --- a/net/dsa/tag_qca.c +++ b/net/dsa/tag_qca.c @@ -34,9 +34,6 @@ static struct sk_buff *qca_tag_xmit(struct sk_buff *skb, struct net_device *dev) __be16 *phdr; u16 hdr;
- if (skb_cow_head(skb, QCA_HDR_LEN) < 0) - return NULL; - skb_push(skb, QCA_HDR_LEN);
memmove(skb->data, skb->data + QCA_HDR_LEN, 2 * ETH_ALEN);
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Vladimir Oltean vladimir.oltean@nxp.com
[ Upstream commit 9c5c3bd00557e57c1049f7861f11e5e39f0fb42d ]
Now that we have a central TX reallocation procedure that accounts for the tagger's needed headroom in a generic way, we can remove the skb_cow_head call.
Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Reviewed-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/dsa/tag_ocelot.c | 7 ------- 1 file changed, 7 deletions(-)
diff --git a/net/dsa/tag_ocelot.c b/net/dsa/tag_ocelot.c index 3b468aca5c53..16a1afd5b8e1 100644 --- a/net/dsa/tag_ocelot.c +++ b/net/dsa/tag_ocelot.c @@ -143,13 +143,6 @@ static struct sk_buff *ocelot_xmit(struct sk_buff *skb, struct ocelot_port *ocelot_port; u8 *prefix, *injection; u64 qos_class, rew_op; - int err; - - err = skb_cow_head(skb, OCELOT_TOTAL_TAG_LEN); - if (unlikely(err < 0)) { - netdev_err(netdev, "Cannot make room for tag.\n"); - return NULL; - }
ocelot_port = ocelot->ports[dp->index];
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Vladimir Oltean vladimir.oltean@nxp.com
[ Upstream commit 941f66beb7bb4e0e4726aa31336d9ccc1c3a3dc2 ]
Now that we have a central TX reallocation procedure that accounts for the tagger's needed headroom in a generic way, we can remove the skb_cow_head call.
Cc: DENG Qingfang dqfext@gmail.com Cc: Sean Wang sean.wang@mediatek.com Cc: John Crispin john@phrozen.org Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Reviewed-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/dsa/tag_mtk.c | 3 --- 1 file changed, 3 deletions(-)
diff --git a/net/dsa/tag_mtk.c b/net/dsa/tag_mtk.c index 4cdd9cf428fb..38dcdded74c0 100644 --- a/net/dsa/tag_mtk.c +++ b/net/dsa/tag_mtk.c @@ -34,9 +34,6 @@ static struct sk_buff *mtk_tag_xmit(struct sk_buff *skb, * table with VID. */ if (!skb_vlan_tagged(skb)) { - if (skb_cow_head(skb, MTK_HDR_LEN) < 0) - return NULL; - skb_push(skb, MTK_HDR_LEN); memmove(skb->data, skb->data + MTK_HDR_LEN, 2 * ETH_ALEN); is_vlan_skb = false;
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Vladimir Oltean vladimir.oltean@nxp.com
[ Upstream commit 6ed94135f58372cdec34cafb60f7596893b0b371 ]
Now that we have a central TX reallocation procedure that accounts for the tagger's needed headroom in a generic way, we can remove the skb_cow_head call.
Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Reviewed-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/dsa/tag_lan9303.c | 9 --------- 1 file changed, 9 deletions(-)
diff --git a/net/dsa/tag_lan9303.c b/net/dsa/tag_lan9303.c index ccfb6f641bbf..aa1318dccaf0 100644 --- a/net/dsa/tag_lan9303.c +++ b/net/dsa/tag_lan9303.c @@ -58,15 +58,6 @@ static struct sk_buff *lan9303_xmit(struct sk_buff *skb, struct net_device *dev) __be16 *lan9303_tag; u16 tag;
- /* insert a special VLAN tag between the MAC addresses - * and the current ethertype field. - */ - if (skb_cow_head(skb, LAN9303_TAG_LEN) < 0) { - dev_dbg(&dev->dev, - "Cannot make room for the special tag. Dropping packet\n"); - return NULL; - } - /* provide 'LAN9303_TAG_LEN' bytes additional space */ skb_push(skb, LAN9303_TAG_LEN);
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Vladimir Oltean vladimir.oltean@nxp.com
[ Upstream commit c6c4e1237dfe731644e79fa06d073625f28cd945 ]
Now that we have a central TX reallocation procedure that accounts for the tagger's needed headroom in a generic way, we can remove the skb_cow_head call.
Note that the VLAN code path needs a smaller extra headroom than the regular EtherType DSA path. That isn't a problem, because this tagger declares the larger tag length (8 bytes vs 4) as the protocol overhead, so we are covered in both cases.
Cc: Andrew Lunn andrew@lunn.ch Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Reviewed-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/dsa/tag_edsa.c | 4 ---- 1 file changed, 4 deletions(-)
diff --git a/net/dsa/tag_edsa.c b/net/dsa/tag_edsa.c index 120614240319..abf70a29deb4 100644 --- a/net/dsa/tag_edsa.c +++ b/net/dsa/tag_edsa.c @@ -35,8 +35,6 @@ static struct sk_buff *edsa_xmit(struct sk_buff *skb, struct net_device *dev) * current ethertype field if the packet is untagged. */ if (skb->protocol == htons(ETH_P_8021Q)) { - if (skb_cow_head(skb, DSA_HLEN) < 0) - return NULL; skb_push(skb, DSA_HLEN);
memmove(skb->data, skb->data + DSA_HLEN, 2 * ETH_ALEN); @@ -60,8 +58,6 @@ static struct sk_buff *edsa_xmit(struct sk_buff *skb, struct net_device *dev) edsa_header[6] &= ~0x10; } } else { - if (skb_cow_head(skb, EDSA_HLEN) < 0) - return NULL; skb_push(skb, EDSA_HLEN);
memmove(skb->data, skb->data + EDSA_HLEN, 2 * ETH_ALEN);
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Vladimir Oltean vladimir.oltean@nxp.com
[ Upstream commit 2f0d030c5ffec6660f79a32b4f522155f75a9d71 ]
Now that we have a central TX reallocation procedure that accounts for the tagger's needed headroom in a generic way, we can remove the skb_cow_head call.
Cc: Florian Fainelli f.fainelli@gmail.com Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Reviewed-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/dsa/tag_brcm.c | 3 --- 1 file changed, 3 deletions(-)
diff --git a/net/dsa/tag_brcm.c b/net/dsa/tag_brcm.c index ad72dff8d524..e934dace3922 100644 --- a/net/dsa/tag_brcm.c +++ b/net/dsa/tag_brcm.c @@ -66,9 +66,6 @@ static struct sk_buff *brcm_tag_xmit_ll(struct sk_buff *skb, u16 queue = skb_get_queue_mapping(skb); u8 *brcm_tag;
- if (skb_cow_head(skb, BRCM_TAG_LEN) < 0) - return NULL; - /* The Ethernet switch we are interfaced with needs packets to be at * least 64 bytes (including FCS) otherwise they will be discarded when * they enter the switch port logic. When Broadcom tags are enabled, we
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Vladimir Oltean vladimir.oltean@nxp.com
[ Upstream commit 952a06345015867e3bd37f8d9045fc1429637d43 ]
Now that we have a central TX reallocation procedure that accounts for the tagger's needed headroom in a generic way, we can remove the skb_cow_head call.
Similar to the EtherType DSA tagger, the old Marvell tagger can transform an 802.1Q header if present into a DSA tag, so there is no headroom required in that case. But we are ensuring that it exists, regardless (practically speaking, the headroom must be 4 bytes larger than it needs to be).
Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Reviewed-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/dsa/tag_dsa.c | 5 ----- 1 file changed, 5 deletions(-)
diff --git a/net/dsa/tag_dsa.c b/net/dsa/tag_dsa.c index 0b756fae68a5..63d690a0fca6 100644 --- a/net/dsa/tag_dsa.c +++ b/net/dsa/tag_dsa.c @@ -23,9 +23,6 @@ static struct sk_buff *dsa_xmit(struct sk_buff *skb, struct net_device *dev) * the ethertype field for untagged packets. */ if (skb->protocol == htons(ETH_P_8021Q)) { - if (skb_cow_head(skb, 0) < 0) - return NULL; - /* * Construct tagged FROM_CPU DSA tag from 802.1q tag. */ @@ -41,8 +38,6 @@ static struct sk_buff *dsa_xmit(struct sk_buff *skb, struct net_device *dev) dsa_header[2] &= ~0x10; } } else { - if (skb_cow_head(skb, DSA_HLEN) < 0) - return NULL; skb_push(skb, DSA_HLEN);
memmove(skb->data, skb->data + DSA_HLEN, 2 * ETH_ALEN);
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Vladimir Oltean vladimir.oltean@nxp.com
[ Upstream commit 9b9826ae117f211bcbdc75db844d5fd8b159fc59 ]
Now that we have a central TX reallocation procedure that accounts for the tagger's needed headroom in a generic way, we can remove the skb_cow_head call.
This one is interesting, the DSA tag is 8 bytes on RX and 4 bytes on TX. Because DSA is unaware of asymmetrical tag lengths, the overhead/needed headroom is declared as 8 bytes and therefore 4 bytes larger than it needs to be. If this becomes a problem, and the GSWIP driver can't be converted to a uniform header length, we might need to make DSA aware of separate RX/TX overhead values.
Cc: Hauke Mehrtens hauke@hauke-m.de Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Reviewed-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/dsa/tag_gswip.c | 5 ----- 1 file changed, 5 deletions(-)
diff --git a/net/dsa/tag_gswip.c b/net/dsa/tag_gswip.c index 408d4af390a0..2f5bd5e338ab 100644 --- a/net/dsa/tag_gswip.c +++ b/net/dsa/tag_gswip.c @@ -60,13 +60,8 @@ static struct sk_buff *gswip_tag_xmit(struct sk_buff *skb, struct net_device *dev) { struct dsa_port *dp = dsa_slave_to_port(dev); - int err; u8 *gswip_tag;
- err = skb_cow_head(skb, GSWIP_TX_HEADER_LEN); - if (err) - return NULL; - skb_push(skb, GSWIP_TX_HEADER_LEN);
gswip_tag = skb->data;
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Vladimir Oltean vladimir.oltean@nxp.com
[ Upstream commit 86c4ad9a7876777c12fd5a7010152e4141fcb94d ]
Now that we have a central TX reallocation procedure that accounts for the tagger's needed headroom in a generic way, we can remove the skb_cow_head call.
Cc: Per Forlin per.forlin@axis.com Cc: Oleksij Rempel linux@rempel-privat.de Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Tested-by: Oleksij Rempel linux@rempel-privat.de Reviewed-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/dsa/tag_ar9331.c | 3 --- 1 file changed, 3 deletions(-)
diff --git a/net/dsa/tag_ar9331.c b/net/dsa/tag_ar9331.c index 55b00694cdba..002cf7f952e2 100644 --- a/net/dsa/tag_ar9331.c +++ b/net/dsa/tag_ar9331.c @@ -31,9 +31,6 @@ static struct sk_buff *ar9331_tag_xmit(struct sk_buff *skb, __le16 *phdr; u16 hdr;
- if (skb_cow_head(skb, AR9331_HDR_LEN) < 0) - return NULL; - phdr = skb_push(skb, AR9331_HDR_LEN);
hdr = FIELD_PREP(AR9331_HDR_VERSION_MASK, AR9331_HDR_VERSION);
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: DENG Qingfang dqfext@gmail.com
[ Upstream commit 9200f515c41f4cbaeffd8fdd1d8b6373a18b1b67 ]
A different TPID bit is used for 802.1ad VLAN frames.
Reported-by: Ilario Gelmetti iochesonome@gmail.com Fixes: f0af34317f4b ("net: dsa: mediatek: combine MediaTek tag with VLAN tag") Signed-off-by: DENG Qingfang dqfext@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/dsa/tag_mtk.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/net/dsa/tag_mtk.c b/net/dsa/tag_mtk.c index 38dcdded74c0..59748487664f 100644 --- a/net/dsa/tag_mtk.c +++ b/net/dsa/tag_mtk.c @@ -13,6 +13,7 @@ #define MTK_HDR_LEN 4 #define MTK_HDR_XMIT_UNTAGGED 0 #define MTK_HDR_XMIT_TAGGED_TPID_8100 1 +#define MTK_HDR_XMIT_TAGGED_TPID_88A8 2 #define MTK_HDR_RECV_SOURCE_PORT_MASK GENMASK(2, 0) #define MTK_HDR_XMIT_DP_BIT_MASK GENMASK(5, 0) #define MTK_HDR_XMIT_SA_DIS BIT(6) @@ -21,8 +22,8 @@ static struct sk_buff *mtk_tag_xmit(struct sk_buff *skb, struct net_device *dev) { struct dsa_port *dp = dsa_slave_to_port(dev); + u8 xmit_tpid; u8 *mtk_tag; - bool is_vlan_skb = true; unsigned char *dest = eth_hdr(skb)->h_dest; bool is_multicast_skb = is_multicast_ether_addr(dest) && !is_broadcast_ether_addr(dest); @@ -33,10 +34,17 @@ static struct sk_buff *mtk_tag_xmit(struct sk_buff *skb, * the both special and VLAN tag at the same time and then look up VLAN * table with VID. */ - if (!skb_vlan_tagged(skb)) { + switch (skb->protocol) { + case htons(ETH_P_8021Q): + xmit_tpid = MTK_HDR_XMIT_TAGGED_TPID_8100; + break; + case htons(ETH_P_8021AD): + xmit_tpid = MTK_HDR_XMIT_TAGGED_TPID_88A8; + break; + default: + xmit_tpid = MTK_HDR_XMIT_UNTAGGED; skb_push(skb, MTK_HDR_LEN); memmove(skb->data, skb->data + MTK_HDR_LEN, 2 * ETH_ALEN); - is_vlan_skb = false; }
mtk_tag = skb->data + 2 * ETH_ALEN; @@ -44,8 +52,7 @@ static struct sk_buff *mtk_tag_xmit(struct sk_buff *skb, /* Mark tag attribute on special tag insertion to notify hardware * whether that's a combined special tag with 802.1Q header. */ - mtk_tag[0] = is_vlan_skb ? MTK_HDR_XMIT_TAGGED_TPID_8100 : - MTK_HDR_XMIT_UNTAGGED; + mtk_tag[0] = xmit_tpid; mtk_tag[1] = (1 << dp->index) & MTK_HDR_XMIT_DP_BIT_MASK;
/* Disable SA learning for multicast frames */ @@ -53,7 +60,7 @@ static struct sk_buff *mtk_tag_xmit(struct sk_buff *skb, mtk_tag[1] |= MTK_HDR_XMIT_SA_DIS;
/* Tag control information is kept for 802.1Q */ - if (!is_vlan_skb) { + if (xmit_tpid == MTK_HDR_XMIT_UNTAGGED) { mtk_tag[2] = 0; mtk_tag[3] = 0; }
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit 4560b2a3ecdd5d587c4c6eea4339899f173a559a ]
When CONFIG_OF is disabled, there is a harmless warning about an unused variable:
enetc_pf.c: In function 'enetc_phylink_create': enetc_pf.c:981:17: error: unused variable 'dev' [-Werror=unused-variable]
Slightly rearrange the code to pass around the of_node as a function argument, which avoids the problem without hurting readability.
Fixes: 71b77a7a27a3 ("enetc: Migrate to PHYLINK and PCS_LYNX") Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Claudiu Manoil claudiu.manoil@nxp.com Link: https://lore.kernel.org/r/20201204120800.17193-1-claudiu.manoil@nxp.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- .../net/ethernet/freescale/enetc/enetc_pf.c | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c b/drivers/net/ethernet/freescale/enetc/enetc_pf.c index b35096455293..f29058dddb36 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c +++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c @@ -859,13 +859,12 @@ static bool enetc_port_has_pcs(struct enetc_pf *pf) pf->if_mode == PHY_INTERFACE_MODE_USXGMII); }
-static int enetc_mdiobus_create(struct enetc_pf *pf) +static int enetc_mdiobus_create(struct enetc_pf *pf, struct device_node *node) { - struct device *dev = &pf->si->pdev->dev; struct device_node *mdio_np; int err;
- mdio_np = of_get_child_by_name(dev->of_node, "mdio"); + mdio_np = of_get_child_by_name(node, "mdio"); if (mdio_np) { err = enetc_mdio_probe(pf, mdio_np);
@@ -1009,18 +1008,17 @@ static const struct phylink_mac_ops enetc_mac_phylink_ops = { .mac_link_down = enetc_pl_mac_link_down, };
-static int enetc_phylink_create(struct enetc_ndev_priv *priv) +static int enetc_phylink_create(struct enetc_ndev_priv *priv, + struct device_node *node) { struct enetc_pf *pf = enetc_si_priv(priv->si); - struct device *dev = &pf->si->pdev->dev; struct phylink *phylink; int err;
pf->phylink_config.dev = &priv->ndev->dev; pf->phylink_config.type = PHYLINK_NETDEV;
- phylink = phylink_create(&pf->phylink_config, - of_fwnode_handle(dev->of_node), + phylink = phylink_create(&pf->phylink_config, of_fwnode_handle(node), pf->if_mode, &enetc_mac_phylink_ops); if (IS_ERR(phylink)) { err = PTR_ERR(phylink); @@ -1086,13 +1084,14 @@ static int enetc_init_port_rss_memory(struct enetc_si *si) static int enetc_pf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { + struct device_node *node = pdev->dev.of_node; struct enetc_ndev_priv *priv; struct net_device *ndev; struct enetc_si *si; struct enetc_pf *pf; int err;
- if (pdev->dev.of_node && !of_device_is_available(pdev->dev.of_node)) { + if (node && !of_device_is_available(node)) { dev_info(&pdev->dev, "device is disabled, skipping\n"); return -ENODEV; } @@ -1161,12 +1160,12 @@ static int enetc_pf_probe(struct pci_dev *pdev, goto err_alloc_msix; }
- if (!of_get_phy_mode(pdev->dev.of_node, &pf->if_mode)) { - err = enetc_mdiobus_create(pf); + if (!of_get_phy_mode(node, &pf->if_mode)) { + err = enetc_mdiobus_create(pf, node); if (err) goto err_mdiobus_create;
- err = enetc_phylink_create(priv); + err = enetc_phylink_create(priv, node); if (err) goto err_phylink_create; }
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Vladimir Oltean vladimir.oltean@nxp.com
[ Upstream commit 3222b5b613db558e9a494bbf53f3c984d90f71ea ]
Michael reports that since linux-next-20210211, the AER messages for ECC errors have started reappearing, and this time they can be reliably reproduced with the first ping on one of his LS1028A boards.
$ ping 1[ 33.258069] pcieport 0000:00:1f.0: AER: Multiple Corrected error received: 0000:00:00.0 72.16.0.1 PING [ 33.267050] pcieport 0000:00:1f.0: AER: can't find device of ID0000 172.16.0.1 (172.16.0.1): 56 data bytes 64 bytes from 172.16.0.1: seq=0 ttl=64 time=17.124 ms 64 bytes from 172.16.0.1: seq=1 ttl=64 time=0.273 ms
$ devmem 0x1f8010e10 32 0xC0000006
It isn't clear why this is necessary, but it seems that for the errors to go away, we must clear the entire RFS and RSS memory, not just for the ports in use.
Sadly the code is structured in such a way that we can't have unified logic for the used and unused ports. For the minimal initialization of an unused port, we need just to enable and ioremap the PF memory space, and a control buffer descriptor ring. Unused ports must then free the CBDR because the driver will exit, but used ports can not pick up from where that code path left, since the CBDR API does not reinitialize a ring when setting it up, so its producer and consumer indices are out of sync between the software and hardware state. So a separate enetc_init_unused_port function was created, and it gets called right after the PF memory space is enabled.
Fixes: 07bf34a50e32 ("net: enetc: initialize the RFS and RSS memories") Reported-by: Michael Walle michael@walle.cc Cc: Jesse Brandeburg jesse.brandeburg@intel.com Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Tested-by: Michael Walle michael@walle.cc Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/freescale/enetc/enetc.c | 8 ++--- drivers/net/ethernet/freescale/enetc/enetc.h | 4 +++ .../net/ethernet/freescale/enetc/enetc_pf.c | 33 ++++++++++++++++--- 3 files changed, 36 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c index 019a0fa3d9a5..df4a858c8001 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc.c +++ b/drivers/net/ethernet/freescale/enetc/enetc.c @@ -1035,7 +1035,7 @@ static void enetc_free_rxtx_rings(struct enetc_ndev_priv *priv) enetc_free_tx_ring(priv->tx_ring[i]); }
-static int enetc_alloc_cbdr(struct device *dev, struct enetc_cbdr *cbdr) +int enetc_alloc_cbdr(struct device *dev, struct enetc_cbdr *cbdr) { int size = cbdr->bd_count * sizeof(struct enetc_cbd);
@@ -1056,7 +1056,7 @@ static int enetc_alloc_cbdr(struct device *dev, struct enetc_cbdr *cbdr) return 0; }
-static void enetc_free_cbdr(struct device *dev, struct enetc_cbdr *cbdr) +void enetc_free_cbdr(struct device *dev, struct enetc_cbdr *cbdr) { int size = cbdr->bd_count * sizeof(struct enetc_cbd);
@@ -1064,7 +1064,7 @@ static void enetc_free_cbdr(struct device *dev, struct enetc_cbdr *cbdr) cbdr->bd_base = NULL; }
-static void enetc_setup_cbdr(struct enetc_hw *hw, struct enetc_cbdr *cbdr) +void enetc_setup_cbdr(struct enetc_hw *hw, struct enetc_cbdr *cbdr) { /* set CBDR cache attributes */ enetc_wr(hw, ENETC_SICAR2, @@ -1084,7 +1084,7 @@ static void enetc_setup_cbdr(struct enetc_hw *hw, struct enetc_cbdr *cbdr) cbdr->cir = hw->reg + ENETC_SICBDRCIR; }
-static void enetc_clear_cbdr(struct enetc_hw *hw) +void enetc_clear_cbdr(struct enetc_hw *hw) { enetc_wr(hw, ENETC_SICBDRMR, 0); } diff --git a/drivers/net/ethernet/freescale/enetc/enetc.h b/drivers/net/ethernet/freescale/enetc/enetc.h index 6bc23f9b53fa..15d19cbd5a95 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc.h +++ b/drivers/net/ethernet/freescale/enetc/enetc.h @@ -311,6 +311,10 @@ int enetc_setup_tc(struct net_device *ndev, enum tc_setup_type type, void enetc_set_ethtool_ops(struct net_device *ndev);
/* control buffer descriptor ring (CBDR) */ +int enetc_alloc_cbdr(struct device *dev, struct enetc_cbdr *cbdr); +void enetc_free_cbdr(struct device *dev, struct enetc_cbdr *cbdr); +void enetc_setup_cbdr(struct enetc_hw *hw, struct enetc_cbdr *cbdr); +void enetc_clear_cbdr(struct enetc_hw *hw); int enetc_set_mac_flt_entry(struct enetc_si *si, int index, char *mac_addr, int si_map); int enetc_clear_mac_flt_entry(struct enetc_si *si, int index); diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c b/drivers/net/ethernet/freescale/enetc/enetc_pf.c index f29058dddb36..83187cd59fdd 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c +++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c @@ -1081,6 +1081,26 @@ static int enetc_init_port_rss_memory(struct enetc_si *si) return err; }
+static void enetc_init_unused_port(struct enetc_si *si) +{ + struct device *dev = &si->pdev->dev; + struct enetc_hw *hw = &si->hw; + int err; + + si->cbd_ring.bd_count = ENETC_CBDR_DEFAULT_SIZE; + err = enetc_alloc_cbdr(dev, &si->cbd_ring); + if (err) + return; + + enetc_setup_cbdr(hw, &si->cbd_ring); + + enetc_init_port_rfs_memory(si); + enetc_init_port_rss_memory(si); + + enetc_clear_cbdr(hw); + enetc_free_cbdr(dev, &si->cbd_ring); +} + static int enetc_pf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -1091,11 +1111,6 @@ static int enetc_pf_probe(struct pci_dev *pdev, struct enetc_pf *pf; int err;
- if (node && !of_device_is_available(node)) { - dev_info(&pdev->dev, "device is disabled, skipping\n"); - return -ENODEV; - } - err = enetc_pci_probe(pdev, KBUILD_MODNAME, sizeof(*pf)); if (err) { dev_err(&pdev->dev, "PCI probing failed\n"); @@ -1109,6 +1124,13 @@ static int enetc_pf_probe(struct pci_dev *pdev, goto err_map_pf_space; }
+ if (node && !of_device_is_available(node)) { + enetc_init_unused_port(si); + dev_info(&pdev->dev, "device is disabled, skipping\n"); + err = -ENODEV; + goto err_device_disabled; + } + pf = enetc_si_priv(si); pf->si = si; pf->total_vfs = pci_sriov_get_totalvfs(pdev); @@ -1191,6 +1213,7 @@ err_alloc_si_res: si->ndev = NULL; free_netdev(ndev); err_alloc_netdev: +err_device_disabled: err_map_pf_space: enetc_pci_remove(pdev);
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Ritesh Singh ritesi@codeaurora.org
[ Upstream commit 690ace20ff790f443c3cbaf12e1769e4eb0072db ]
Peer creation in firmware fails, if last peer deletion is still in progress. Hence, add wait for the event after deleting every peer from host driver to synchronize with firmware.
Signed-off-by: Ritesh Singh ritesi@codeaurora.org Signed-off-by: Maharaja Kennadyrajan mkenna@codeaurora.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/1605514143-17652-3-git-send-email-mkenna@codeauror... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath11k/core.c | 1 + drivers/net/wireless/ath/ath11k/core.h | 1 + drivers/net/wireless/ath/ath11k/mac.c | 17 +++++++++- drivers/net/wireless/ath/ath11k/peer.c | 44 ++++++++++++++++++++++++-- drivers/net/wireless/ath/ath11k/peer.h | 2 ++ drivers/net/wireless/ath/ath11k/wmi.c | 17 ++++++++-- 6 files changed, 75 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index ebd6886a8c18..a68fe3a45a74 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -774,6 +774,7 @@ static void ath11k_core_restart(struct work_struct *work) complete(&ar->scan.started); complete(&ar->scan.completed); complete(&ar->peer_assoc_done); + complete(&ar->peer_delete_done); complete(&ar->install_key_done); complete(&ar->vdev_setup_done); complete(&ar->bss_survey_done); diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index 5a7915f75e1e..c8e36251068c 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -502,6 +502,7 @@ struct ath11k { u8 lmac_id;
struct completion peer_assoc_done; + struct completion peer_delete_done;
int install_key_status; struct completion install_key_done; diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index b5bd9b06da89..c8f1b786e746 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -4589,8 +4589,22 @@ static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw,
err_peer_del: if (arvif->vdev_type == WMI_VDEV_TYPE_AP) { + reinit_completion(&ar->peer_delete_done); + + ret = ath11k_wmi_send_peer_delete_cmd(ar, vif->addr, + arvif->vdev_id); + if (ret) { + ath11k_warn(ar->ab, "failed to delete peer vdev_id %d addr %pM\n", + arvif->vdev_id, vif->addr); + return ret; + } + + ret = ath11k_wait_for_peer_delete_done(ar, arvif->vdev_id, + vif->addr); + if (ret) + return ret; + ar->num_peers--; - ath11k_wmi_send_peer_delete_cmd(ar, vif->addr, arvif->vdev_id); }
err_vdev_del: @@ -6413,6 +6427,7 @@ int ath11k_mac_allocate(struct ath11k_base *ab) mutex_init(&ar->conf_mutex); init_completion(&ar->vdev_setup_done); init_completion(&ar->peer_assoc_done); + init_completion(&ar->peer_delete_done); init_completion(&ar->install_key_done); init_completion(&ar->bss_survey_done); init_completion(&ar->scan.started); diff --git a/drivers/net/wireless/ath/ath11k/peer.c b/drivers/net/wireless/ath/ath11k/peer.c index 61ad9300eafb..1866d82678fa 100644 --- a/drivers/net/wireless/ath/ath11k/peer.c +++ b/drivers/net/wireless/ath/ath11k/peer.c @@ -177,12 +177,36 @@ static int ath11k_wait_for_peer_deleted(struct ath11k *ar, int vdev_id, const u8 return ath11k_wait_for_peer_common(ar->ab, vdev_id, addr, false); }
+int ath11k_wait_for_peer_delete_done(struct ath11k *ar, u32 vdev_id, + const u8 *addr) +{ + int ret; + unsigned long time_left; + + ret = ath11k_wait_for_peer_deleted(ar, vdev_id, addr); + if (ret) { + ath11k_warn(ar->ab, "failed wait for peer deleted"); + return ret; + } + + time_left = wait_for_completion_timeout(&ar->peer_delete_done, + 3 * HZ); + if (time_left == 0) { + ath11k_warn(ar->ab, "Timeout in receiving peer delete response\n"); + return -ETIMEDOUT; + } + + return 0; +} + int ath11k_peer_delete(struct ath11k *ar, u32 vdev_id, u8 *addr) { int ret;
lockdep_assert_held(&ar->conf_mutex);
+ reinit_completion(&ar->peer_delete_done); + ret = ath11k_wmi_send_peer_delete_cmd(ar, addr, vdev_id); if (ret) { ath11k_warn(ar->ab, @@ -191,7 +215,7 @@ int ath11k_peer_delete(struct ath11k *ar, u32 vdev_id, u8 *addr) return ret; }
- ret = ath11k_wait_for_peer_deleted(ar, vdev_id, addr); + ret = ath11k_wait_for_peer_delete_done(ar, vdev_id, addr); if (ret) return ret;
@@ -247,8 +271,22 @@ int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif, spin_unlock_bh(&ar->ab->base_lock); ath11k_warn(ar->ab, "failed to find peer %pM on vdev %i after creation\n", param->peer_addr, param->vdev_id); - ath11k_wmi_send_peer_delete_cmd(ar, param->peer_addr, - param->vdev_id); + + reinit_completion(&ar->peer_delete_done); + + ret = ath11k_wmi_send_peer_delete_cmd(ar, param->peer_addr, + param->vdev_id); + if (ret) { + ath11k_warn(ar->ab, "failed to delete peer vdev_id %d addr %pM\n", + param->vdev_id, param->peer_addr); + return ret; + } + + ret = ath11k_wait_for_peer_delete_done(ar, param->vdev_id, + param->peer_addr); + if (ret) + return ret; + return -ENOENT; }
diff --git a/drivers/net/wireless/ath/ath11k/peer.h b/drivers/net/wireless/ath/ath11k/peer.h index 5d125ce8984e..bba2e00b6944 100644 --- a/drivers/net/wireless/ath/ath11k/peer.h +++ b/drivers/net/wireless/ath/ath11k/peer.h @@ -41,5 +41,7 @@ void ath11k_peer_cleanup(struct ath11k *ar, u32 vdev_id); int ath11k_peer_delete(struct ath11k *ar, u32 vdev_id, u8 *addr); int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif, struct ieee80211_sta *sta, struct peer_create_params *param); +int ath11k_wait_for_peer_delete_done(struct ath11k *ar, u32 vdev_id, + const u8 *addr);
#endif /* _PEER_H_ */ diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c index 04b8b002edfe..173ab6ceed1f 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -5532,15 +5532,26 @@ static int ath11k_ready_event(struct ath11k_base *ab, struct sk_buff *skb) static void ath11k_peer_delete_resp_event(struct ath11k_base *ab, struct sk_buff *skb) { struct wmi_peer_delete_resp_event peer_del_resp; + struct ath11k *ar;
if (ath11k_pull_peer_del_resp_ev(ab, skb, &peer_del_resp) != 0) { ath11k_warn(ab, "failed to extract peer delete resp"); return; }
- /* TODO: Do we need to validate whether ath11k_peer_find() return NULL - * Why this is needed when there is HTT event for peer delete - */ + rcu_read_lock(); + ar = ath11k_mac_get_ar_by_vdev_id(ab, peer_del_resp.vdev_id); + if (!ar) { + ath11k_warn(ab, "invalid vdev id in peer delete resp ev %d", + peer_del_resp.vdev_id); + rcu_read_unlock(); + return; + } + + complete(&ar->peer_delete_done); + rcu_read_unlock(); + ath11k_dbg(ab, ATH11K_DBG_WMI, "peer delete resp for vdev id %d addr %pM\n", + peer_del_resp.vdev_id, peer_del_resp.peer_macaddr.addr); }
static inline const char *ath11k_wmi_vdev_resp_print(u32 vdev_resp_status)
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
From: Carl Huang cjhuang@codeaurora.org
[ Upstream commit aa44b2f3ecd41f90b7e477158036648a49d21a32 ]
For QCA6390, bss peer must be created before vdev is to start. This change is to start vdev if a bss peer is created. Otherwise, ath11k delays to start vdev.
This fixes an issue in a case where HT/VHT/HE settings change between authentication and association, e.g., due to the user space request to disable HT.
Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1
Signed-off-by: Carl Huang cjhuang@codeaurora.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20201211051358.9191-1-cjhuang@codeaurora.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath11k/mac.c | 8 ++++++-- drivers/net/wireless/ath/ath11k/peer.c | 17 +++++++++++++++++ drivers/net/wireless/ath/ath11k/peer.h | 2 ++ 3 files changed, 25 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index c8f1b786e746..f3c5023f8a45 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -2986,6 +2986,7 @@ static int ath11k_mac_station_add(struct ath11k *ar, }
if (ab->hw_params.vdev_start_delay && + !arvif->is_started && arvif->vdev_type != WMI_VDEV_TYPE_AP) { ret = ath11k_start_vdev_delay(ar->hw, vif); if (ret) { @@ -5248,7 +5249,8 @@ ath11k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, /* for QCA6390 bss peer must be created before vdev_start */ if (ab->hw_params.vdev_start_delay && arvif->vdev_type != WMI_VDEV_TYPE_AP && - arvif->vdev_type != WMI_VDEV_TYPE_MONITOR) { + arvif->vdev_type != WMI_VDEV_TYPE_MONITOR && + !ath11k_peer_find_by_vdev_id(ab, arvif->vdev_id)) { memcpy(&arvif->chanctx, ctx, sizeof(*ctx)); ret = 0; goto out; @@ -5259,7 +5261,9 @@ ath11k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, goto out; }
- if (ab->hw_params.vdev_start_delay) { + if (ab->hw_params.vdev_start_delay && + (arvif->vdev_type == WMI_VDEV_TYPE_AP || + arvif->vdev_type == WMI_VDEV_TYPE_MONITOR)) { param.vdev_id = arvif->vdev_id; param.peer_type = WMI_PEER_TYPE_DEFAULT; param.peer_addr = ar->mac_addr; diff --git a/drivers/net/wireless/ath/ath11k/peer.c b/drivers/net/wireless/ath/ath11k/peer.c index 1866d82678fa..b69e7ebfa930 100644 --- a/drivers/net/wireless/ath/ath11k/peer.c +++ b/drivers/net/wireless/ath/ath11k/peer.c @@ -76,6 +76,23 @@ struct ath11k_peer *ath11k_peer_find_by_id(struct ath11k_base *ab, return NULL; }
+struct ath11k_peer *ath11k_peer_find_by_vdev_id(struct ath11k_base *ab, + int vdev_id) +{ + struct ath11k_peer *peer; + + spin_lock_bh(&ab->base_lock); + + list_for_each_entry(peer, &ab->peers, list) { + if (vdev_id == peer->vdev_id) { + spin_unlock_bh(&ab->base_lock); + return peer; + } + } + spin_unlock_bh(&ab->base_lock); + return NULL; +} + void ath11k_peer_unmap_event(struct ath11k_base *ab, u16 peer_id) { struct ath11k_peer *peer; diff --git a/drivers/net/wireless/ath/ath11k/peer.h b/drivers/net/wireless/ath/ath11k/peer.h index bba2e00b6944..8553ed061aea 100644 --- a/drivers/net/wireless/ath/ath11k/peer.h +++ b/drivers/net/wireless/ath/ath11k/peer.h @@ -43,5 +43,7 @@ int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif, struct ieee80211_sta *sta, struct peer_create_params *param); int ath11k_wait_for_peer_delete_done(struct ath11k *ar, u32 vdev_id, const u8 *addr); +struct ath11k_peer *ath11k_peer_find_by_vdev_id(struct ath11k_base *ab, + int vdev_id);
#endif /* _PEER_H_ */