5.4.14-stable review
Subsystems (4)
Greg Kroah-Hartman
maintainercover 5.4.14-stable review
This is the start of the stable review cycle for the 5.4.14 release. There are 222 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 Fri, 24 Jan 2020 09:25:24 +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.4.14-rc1.gz
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.4.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 5.4.14-rc1
Eddie James <[email protected]>
hwmon: (pmbus/ibm-cffps) Fix LED blink behavior
Eddie James <[email protected]>
hwmon: (pmbus/ibm-cffps) Switch LEDs to blocking brightness call
Stephan Gerhold <[email protected]>
regulator: ab8500: Remove SYSCLKREQ from enum ab8505_regulator_id
Anson Huang <[email protected]>
clk: imx7ulp: Correct DDR clock mux options
Anson Huang <[email protected]>
clk: imx7ulp: Correct system clock source option #7
Baolin Wang <[email protected]>
clk: sprd: Use IS_ERR() to validate the return value of syscon_regmap_lookup_by_phandle()
Andi Kleen <[email protected]>
perf script: Allow --time with --reltime
Masami Hiramatsu <[email protected]>
perf probe: Fix wrong address verification
Tzu-En Huang <[email protected]>
rtw88: fix potential read outside array boundary
Bart Van Assche <[email protected]>
scsi: lpfc: Fix a kernel warning triggered by lpfc_get_sgl_per_hdwq()
James Smart <[email protected]>
scsi: lpfc: Fix hdwq sgl locks and irq handling
James Smart <[email protected]>
scsi: lpfc: Fix list corruption detected in lpfc_put_sgl_per_hdwq
Bart Van Assche <[email protected]>
scsi: core: scsi_trace: Use get_unaligned_be*()
Martin Wilck <[email protected]>
scsi: qla2xxx: fix rports not being mark as lost in sync fabric scan
Huacai Chen <[email protected]>
scsi: qla2xxx: Fix qla2x00_request_irqs() for MSI
John Garry <[email protected]>
scsi: scsi_transport_sas: Fix memory leak when removing devices
Xiang Chen <[email protected]>
scsi: hisi_sas: Return directly if init hardware failed
James Smart <[email protected]>
scsi: lpfc: fix: Coverity: lpfc_get_scsi_buf_s3(): Null pointer dereferences
Bart Van Assche <[email protected]>
scsi: target: core: Fix a pr_debug() argument
Pan Bian <[email protected]>
scsi: bnx2i: fix potential use after free
Pan Bian <[email protected]>
scsi: qla4xxx: fix double free bug
Xiang Chen <[email protected]>
scsi: hisi_sas: Set the BIST init value before enabling BIST
Xiang Chen <[email protected]>
scsi: hisi_sas: Don't create debugfs dump folder twice
Dan Carpenter <[email protected]>
scsi: esas2r: unlock on error in esas2r_nvram_read_direct()
Jeff Mahoney <[email protected]>
reiserfs: fix handling of -EOPNOTSUPP in reiserfs_for_each_xattr
Johannes Berg <[email protected]>
um: virtio_uml: Disallow modular build
Johannes Berg <[email protected]>
um: Don't trace irqflags during shutdown
Sergei Shtylyov <[email protected]>
mtd: cfi_cmdset_0002: fix delayed error detection on HyperFlash
Sergei Shtylyov <[email protected]>
mtd: cfi_cmdset_0002: only check errors when ready in cfi_check_err_status()
Angelo Dureghello <[email protected]>
mtd: devices: fix mchp23k256 read and write
Sudeep Holla <[email protected]>
Revert "arm64: dts: juno: add dma-ranges property"
Tony Lindgren <[email protected]>
ARM: dts: Fix sgx sysconfig register for omap4
Andre Przywara <[email protected]>
arm64: dts: juno: Fix UART frequency
Grygorii Strashko <[email protected]>
ARM: dts: dra7: fix cpsw mdio fck clock
Andre Przywara <[email protected]>
arm64: dts: allwinner: a64: Re-add PMU node
Frieder Schrempf <[email protected]>
ARM: dts: imx6ul-kontron-n6310-s: Disable the snvs-poweroff driver
Rob Clark <[email protected]>
arm64: dts: qcom: sdm845-cheza: delete zap-shader
S.j. Wang <[email protected]>
arm64: dts: imx8mm-evk: Assigned clocks for audio plls
Biju Das <[email protected]>
arm64: dts: renesas: r8a774a1: Remove audio port node
Miquel Raynal <[email protected]>
arm64: dts: marvell: Fix CP110 NAND controller node multi-line comment alignment
Eric Dumazet <[email protected]>
tick/sched: Annotate lockless access to last_jiffies_update
Johannes Berg <[email protected]>
cfg80211: check for set_wiphy_params
Miquel Raynal <[email protected]>
arm64: dts: marvell: Add AP806-dual missing CPU clocks
Kieran Bingham <[email protected]>
arm64: dts: renesas: r8a77970: Fix PWM3
Christian Hewitt <[email protected]>
arm64: dts: meson-gxl-s905x-khadas-vim: fix gpio-keys-polled node
Jerome Brunet <[email protected]>
arm64: dts: meson: g12: fix audio fifo reg size
Jerome Brunet <[email protected]>
arm64: dts: meson: axg: fix audio fifo reg size
Dan Carpenter <[email protected]>
cw1200: Fix a signedness bug in cw1200_load_firmware()
Sai Prakash Ranjan <[email protected]>
arm64: dts: qcom: msm8998: Disable coresight by default
Jonathan Neuschäfer <[email protected]>
irqchip: Place CONFIG_SIFIVE_PLIC into the menu
Eric Dumazet <[email protected]>
tcp: refine rule to allow EPOLLOUT generation under mem pressure
Rob Herring <[email protected]>
dt-bindings: Add missing 'properties' keyword enclosing 'snps,tso'
Nathan Chancellor <[email protected]>
xen/blkfront: Adjust indentation in xlvbd_alloc_gendisk
Ido Schimmel <[email protected]>
devlink: Wait longer before warning about unset port type
Jose Abreu <[email protected]>
net: stmmac: tc: Do not setup flower filtering if RSS is enabled
Jose Abreu <[email protected]>
net: stmmac: selftests: Update status when disabling RSS
Petr Machata <[email protected]>
selftests: mlxsw: qos_mc_aware: Fix mausezahn invocation
Jose Abreu <[email protected]>
net: stmmac: selftests: Mark as fail when received VLAN ID != expected
Jose Abreu <[email protected]>
net: stmmac: selftests: Make it work in Synopsys AXS101 boards
Petr Machata <[email protected]>
mlxsw: spectrum_qdisc: Include MC TCs in Qdisc counters
Petr Machata <[email protected]>
mlxsw: spectrum: Wipe xstats.backlog of down ports
Ido Schimmel <[email protected]>
mlxsw: spectrum: Do not modify cloned SKBs during xmit
Sergei Shtylyov <[email protected]>
sh_eth: check sh_eth_cpu_data::dual_port when dumping registers
changzhu <[email protected]>
drm/amdgpu: allow direct upload save restore list for raven2
Navid Emamdoost <[email protected]>
i40e: prevent memory leak in i40e_setup_macvlans
Florian Fainelli <[email protected]>
net: dsa: bcm_sf2: Configure IMP port for 2Gb/sec
Eric Dumazet <[email protected]>
net: sched: act_ctinfo: fix memory leak
Alexander Lobakin <[email protected]>
net: dsa: tag_gswip: fix typo in tagger name
Vladimir Oltean <[email protected]>
net: dsa: sja1105: Don't error out on disabled ports with no phy-mode
Florian Fainelli <[email protected]>
net: systemport: Fixed queue mapping in internal ring map
Kunihiko Hayashi <[email protected]>
net: ethernet: ave: Avoid lockdep warning
Michael Chan <[email protected]>
bnxt_en: Do not treat DSN (Digital Serial Number) read failure as fatal.
Michael Chan <[email protected]>
bnxt_en: Fix ipv6 RFS filter matching logic.
Michael Chan <[email protected]>
bnxt_en: Fix NTUPLE firmware command failures.
Pengcheng Yang <[email protected]>
tcp: fix marked lost packets not being retransmitted
Johan Hovold <[email protected]>
r8152: add missing endpoint sanity check
Vladis Dronov <[email protected]>
ptp: free ptp device pin descriptors properly
Colin Ian King <[email protected]>
net/wan/fsl_ucc_hdlc: fix out of bounds write on array utdm_info
Eric Dumazet <[email protected]>
net: usb: lan78xx: limit size of local TSO packets
Eric Dumazet <[email protected]>
net/sched: act_ife: initalize ife->metalist earlier
Michael Grzeschik <[email protected]>
net: phy: dp83867: Set FORCE_LINK_GOOD to default after reset
Yonglong Liu <[email protected]>
net: hns: fix soft lockup when there is not enough memory
Yunsheng Lin <[email protected]>
net: hns3: pad the short frame before sending to the hardware
Alexander Lobakin <[email protected]>
net: dsa: tag_qca: fix doubled Tx statistics
Cong Wang <[email protected]>
net: avoid updating qdisc_xmit_lock_key in netdev_update_lockdep_key()
Mohammed Gamal <[email protected]>
hv_netvsc: Fix memory leak when removing rndis device
Eric Dumazet <[email protected]>
macvlan: use skb_reset_mac_header() in macvlan_queue_xmit()
Sven Eckelmann <[email protected]>
batman-adv: Fix DAT candidate selection on little endian systems
Martin KaFai Lau <[email protected]>
bpftool: Fix printing incorrect pointer in btf_dump_ptr
Lorenz Bauer <[email protected]>
net: bpf: Don't leak time wait and request sockets
Johan Hovold <[email protected]>
NFC: pn533: fix bulk-message timeout
Florian Westphal <[email protected]>
netfilter: nf_tables: fix flowtable list del corruption
Pablo Neira Ayuso <[email protected]>
netfilter: nf_tables: store transaction list locally while requesting module
Florian Westphal <[email protected]>
netfilter: nf_tables: remove WARN and add NLA_STRING upper limits
Florian Westphal <[email protected]>
netfilter: nft_tunnel: ERSPAN_VERSION must not be null
Florian Westphal <[email protected]>
netfilter: nft_tunnel: fix null-attribute check
Eyal Birger <[email protected]>
netfilter: nat: fix ICMP header corruption on ICMP errors
Florian Westphal <[email protected]>
netfilter: arp_tables: init netns pointer in xt_tgdtor_param struct
Cong Wang <[email protected]>
netfilter: fix a use-after-free in mtype_destroy()
Krzysztof Kozlowski <[email protected]>
i2c: iop3xx: Fix memory leak in probe error path
Lingpeng Chen <[email protected]>
bpf/sockmap: Read psock ingress_msg before sk_receive_queue
Felix Fietkau <[email protected]>
cfg80211: fix page refcount issue in A-MSDU decap
Felix Fietkau <[email protected]>
cfg80211: fix memory leak in cfg80211_cqm_rssi_update
Felix Fietkau <[email protected]>
cfg80211: fix memory leak in nl80211_probe_mesh_link
Markus Theil <[email protected]>
cfg80211: fix deadlocks in autodisconnect work
Dmitry Osipenko <[email protected]>
i2c: tegra: Properly disable runtime PM on driver's probe error
Dmitry Osipenko <[email protected]>
i2c: tegra: Fix suspending in active runtime PM state
John Fastabend <[email protected]>
bpf: Sockmap/tls, fix pop data with SK_DROP return code
John Fastabend <[email protected]>
bpf: Sockmap/tls, skmsg can have wrapped skmsg that needs extra chaining
John Fastabend <[email protected]>
bpf: Sockmap/tls, tls_sw can create a plaintext buf > encrypt buf
John Fastabend <[email protected]>
bpf: Sockmap/tls, msg_push_data may leave end mark in place
John Fastabend <[email protected]>
bpf: Sockmap, skmsg helper overestimates push, pull, and pop bounds
John Fastabend <[email protected]>
bpf: Sockmap/tls, push write_space updates through ulp updates
John Fastabend <[email protected]>
bpf: Sockmap, ensure sock lock held during tear down
John Fastabend <[email protected]>
bpf: Sockmap/tls, during free we may call tcp_bpf_unhash() in loop
Daniel Borkmann <[email protected]>
bpf: Fix incorrect verifier simulation of ARSH under ALU32
Mario Kleiner <[email protected]>
drm/amd/display: Reorder detect_edp_sink_caps before link settings read.
Bart Van Assche <[email protected]>
block: Fix the type of 'sts' in bsg_queue_rq()
Randy Dunlap <[email protected]>
net: fix kernel-doc warning in <linux/netdevice.h>
Tuong Lien <[email protected]>
tipc: fix retrans failure due to wrong destination
Tuong Lien <[email protected]>
tipc: fix potential hanging after b/rcast changing
Geert Uytterhoeven <[email protected]>
reset: Fix {of,devm}_reset_control_array_get kerneldoc return types
Jose Abreu <[email protected]>
net: stmmac: Enable 16KB buffer size
Jose Abreu <[email protected]>
net: stmmac: 16KB buffer must be 16 byte aligned
Marcel Ziswiler <[email protected]>
ARM: dts: imx7: Fix Toradex Colibri iMX7S 256MB NAND flash support
Jagan Teki <[email protected]>
ARM: dts: imx6q-icore-mipi: Use 1.5 version of i.Core MX6DL
Anson Huang <[email protected]>
ARM: dts: imx6sll-evk: Remove incorrect power supply assignment
Anson Huang <[email protected]>
ARM: dts: imx6sl-evk: Remove incorrect power supply assignment
Anson Huang <[email protected]>
ARM: dts: imx6sx-sdb: Remove incorrect power supply assignment
Anson Huang <[email protected]>
ARM: dts: imx6qdl-sabresd: Remove incorrect power supply assignment
Yang Shi <[email protected]>
mm: khugepaged: add trace status description for SCAN_PAGE_HAS_PRIVATE
Wen Yang <[email protected]>
mm/page-writeback.c: avoid potential division by zero in wb_min_max_ratio()
David Hildenbrand <[email protected]>
mm/memory_hotplug: don't free usage map when removing a re-added early section
Filipe Manana <[email protected]>
Btrfs: always copy scrub arguments back to user space
Josef Bacik <[email protected]>
btrfs: check rw_devices, not num_devices for balance
Johannes Thumshirn <[email protected]>
btrfs: fix memory leak in qgroup accounting
Qu Wenruo <[email protected]>
btrfs: relocation: fix reloc_root lifespan and access
Josef Bacik <[email protected]>
btrfs: do not delete mismatched root refs
Josef Bacik <[email protected]>
btrfs: fix invalid removal of root ref
Josef Bacik <[email protected]>
btrfs: rework arguments of btrfs_unlink_subvol
Vlastimil Babka <[email protected]>
mm, debug_pagealloc: don't rely on static keys too early
Adrian Huang <[email protected]>
mm: memcg/slab: call flush_memcg_workqueue() only if memcg workqueue is valid
Roman Gushchin <[email protected]>
mm: memcg/slab: fix percpu slab vmstats flushing
Kirill A. Shutemov <[email protected]>
mm/huge_memory.c: thp: fix conflict of above-47bit hint address and PMD alignment
Kirill A. Shutemov <[email protected]>
mm/shmem.c: thp, shmem: fix conflict of above-47bit hint address and PMD alignment
Jin Yao <[email protected]>
perf report: Fix incorrectly added dimensions as switch perf data file
Waiman Long <[email protected]>
locking/lockdep: Fix buffer overrun problem in stack_trace[]
Yuya Fujita <[email protected]>
perf hists: Fix variable name's inconsistency in hists__for_each() macro
Marek Szyprowski <[email protected]>
clk: samsung: exynos5420: Keep top G3D clocks enabled
Philipp Rudo <[email protected]>
s390/setup: Fix secure ipl message
Arvind Sankar <[email protected]>
efi/earlycon: Fix write-combine mapping on x86
Shakeel Butt <[email protected]>
x86/resctrl: Fix potential memory leak
YueHaibing <[email protected]>
drm/i915: Add missing include file <linux/math64.h>
Vignesh Raghavendra <[email protected]>
mtd: spi-nor: Fix selection of 4-byte addressing opcodes on Spansion
Long Li <[email protected]>
scsi: storvsc: Correctly set number of hardware queues for IDE disk
Harald Freudenberger <[email protected]>
s390/zcrypt: Fix CCA cipher key gen with clear key value function
Ard Biesheuvel <[email protected]>
x86/efistub: Disable paging at mixed mode entry
Kan Liang <[email protected]>
perf/x86/intel/uncore: Fix missing marker for snr_uncore_imc_freerunning_events
Waiman Long <[email protected]>
locking/rwsem: Fix kernel crash when spinning on RWSEM_OWNER_UNKNOWN
Tom Lendacky <[email protected]>
x86/CPU/AMD: Ensure clearing of SME/SEV features is maintained
Qian Cai <[email protected]>
x86/resctrl: Fix an imbalance in domain_remove_cpu()
Arnd Bergmann <[email protected]>
cpu/SMT: Fix x86 link error without CONFIG_SYSFS
Keiya Nobuta <[email protected]>
usb: core: hub: Improved device recognition on remote wakeup
Esben Haabendal <[email protected]>
mtd: rawnand: gpmi: Restore nfc timing setup after suspend/resume
Esben Haabendal <[email protected]>
mtd: rawnand: gpmi: Fix suspend/resume problem
Christian Brauner <[email protected]>
ptrace: reintroduce usage of subjective credentials in ptrace_has_cap()
Dan Carpenter <[email protected]>
scsi: mptfusion: Fix double fetch bug in ioctl
Arnd Bergmann <[email protected]>
scsi: fnic: fix invalid stack access
Ian Abbott <[email protected]>
staging: comedi: ni_routes: allow partial routing information
Ian Abbott <[email protected]>
staging: comedi: ni_routes: fix null dereference in ni_find_route_source()
Johan Hovold <[email protected]>
USB: serial: quatech2: handle unbound ports
Johan Hovold <[email protected]>
USB: serial: keyspan: handle unbound ports
Johan Hovold <[email protected]>
USB: serial: io_edgeport: add missing active-port sanity check
Johan Hovold <[email protected]>
USB: serial: io_edgeport: handle unbound ports on URB completion
Johan Hovold <[email protected]>
USB: serial: ch341: handle unbound port at reset_resume
Johan Hovold <[email protected]>
USB: serial: suppress driver bind attributes
Reinhard Speyerer <[email protected]>
USB: serial: option: add support for Quectel RM500Q in QDL mode
Johan Hovold <[email protected]>
USB: serial: opticon: fix control-message timeouts
Kristian Evensen <[email protected]>
USB: serial: option: Add support for Quectel RM500Q
Jerónimo Borque <[email protected]>
USB: serial: simple: Add Motorola Solutions TETRA MTP3xxx and MTP85xx
Lars Möllendorf <[email protected]>
iio: buffer: align the size of scan bytes to size of the largest element
Tomasz Duszynski <[email protected]>
iio: chemical: pms7003: fix unmet triggered buffer dependency
Guido Günther <[email protected]>
iio: light: vcnl4000: Fix scale for vcnl4040
Stephan Gerhold <[email protected]>
iio: imu: st_lsm6dsx: Fix selection of ST_LSM6DS3_ID
Alexandru Tachici <[email protected]>
iio: adc: ad7124: Fix DT channel configuration
Mark Rutland <[email protected]>
perf: Correctly handle failed perf_get_aux_event()
Arnd Bergmann <[email protected]>
ARM: davinci: select CONFIG_RESET_CONTROLLER
Kishon Vijay Abraham I <[email protected]>
ARM: dts: am571x-idk: Fix gpios property to have the correct gpio number
Ikjoon Jang <[email protected]>
cpuidle: teo: Fix intervals[] array indexing bug
Jens Axboe <[email protected]>
io_uring: only allow submit from owning task
Miklos Szeredi <[email protected]>
fuse: fix fuse_send_readpages() in the syncronous read case
Mikulas Patocka <[email protected]>
block: fix an integer overflow in logical block size
Chen-Yu Tsai <[email protected]>
clk: sunxi-ng: r40: Allow setting parent rate for external clock outputs
Jari Ruusu <[email protected]>
Fix built-in early-load Intel microcode alignment
Dinh Nguyen <[email protected]>
arm64: dts: agilex/stratix10: fix pmu interrupt numbers
Stefan Mavrodiev <[email protected]>
arm64: dts: allwinner: a64: olinuxino: Fix eMMC supply regulator
Stefan Mavrodiev <[email protected]>
arm64: dts: allwinner: a64: olinuxino: Fix SDIO supply regulator
Johan Hovold <[email protected]>
ALSA: usb-audio: fix sync-ep altsetting sanity check
Takashi Sakamoto <[email protected]>
ALSA: firewire-tascam: fix corruption due to spin lock without restoration in SoftIRQ context
Takashi Iwai <[email protected]>
ALSA: seq: Fix racy access for queue timer in proc read
Takashi Sakamoto <[email protected]>
ALSA: dice: fix fallback from protocol extension into limited functionality
Hans de Goede <[email protected]>
ASoC: Intel: bytcht_es8316: Fix Irbis NB41 netbook quirk
Marek Vasut <[email protected]>
ARM: dts: imx6q-dhcom: Fix SGTL5000 VDDIO regulator connection
Peng Fan <[email protected]>
ARM: dts: imx7ulp: fix reg of cpu node
Tony Lindgren <[email protected]>
ARM: OMAP2+: Fix ti_sysc_find_one_clockdomain to check for to_clk_hw_omap
Stephan Gerhold <[email protected]>
ASoC: msm8916-wcd-analog: Fix MIC BIAS Internal1
Stephan Gerhold <[email protected]>
ASoC: msm8916-wcd-analog: Fix selected events for MIC BIAS External1
Olivier Moysan <[email protected]>
ASoC: stm32: dfsdm: fix 16 bits record
Olivier Moysan <[email protected]>
ASoC: stm32: sai: fix possible circular locking
Stephan Gerhold <[email protected]>
ASoC: msm8916-wcd-digital: Reset RX interpolation path after use
Angus Ainslie (Purism) <[email protected]>
arm64: dts: imx8mq-librem5-devkit: use correct interrupt for the magnetometer
Kevin Hao <[email protected]>
Revert "gpio: thunderx: Switch to GPIOLIB_IRQCHIP"
Guenter Roeck <[email protected]>
clk: Don't try to enable critical clocks if prepare failed
Tony Lindgren <[email protected]>
bus: ti-sysc: Fix iterating over clocks
Adam Ford <[email protected]>
arm64: dts: imx8mm: Change SDMA1 ahb clock for imx8mm
Yinbo Zhu <[email protected]>
arm64: dts: ls1028a: fix endian setting for dcfg
Alexandre Belloni <[email protected]>
ARM: dts: imx6q-dhcom: fix rtc compatible
Martin Blumenstingl <[email protected]>
dt-bindings: reset: meson8b: fix duplicate reset IDs
Martin Blumenstingl <[email protected]>
soc: amlogic: meson-ee-pwrc: propagate errors from pm_genpd_init()
Martin Blumenstingl <[email protected]>
soc: amlogic: meson-ee-pwrc: propagate PD provider registration errors
Georgi Djakov <[email protected]>
clk: qcom: gcc-sdm845: Add missing flag to votable GDSCs
Martin Blumenstingl <[email protected]>
ARM: dts: meson8: fix the size of the PMU registers
-------------
Diffstat:
.../devicetree/bindings/net/snps,dwmac.yaml | 1 + Makefile | 4 +- arch/arm/boot/dts/am571x-idk.dts | 2 +- arch/arm/boot/dts/dra7-l4.dtsi | 2 +- arch/arm/boot/dts/imx6dl-icore-mipi.dts | 2 +- arch/arm/boot/dts/imx6q-dhcom-pdk2.dts | 2 +- arch/arm/boot/dts/imx6q-dhcom-som.dtsi | 2 +- arch/arm/boot/dts/imx6qdl-sabresd.dtsi | 4 - arch/arm/boot/dts/imx6sl-evk.dts | 4 - arch/arm/boot/dts/imx6sll-evk.dts | 4 - arch/arm/boot/dts/imx6sx-sdb-reva.dts | 4 - arch/arm/boot/dts/imx6sx-sdb.dts | 4 - arch/arm/boot/dts/imx6ul-kontron-n6310-s.dts | 4 - arch/arm/boot/dts/imx7s-colibri.dtsi | 4 + arch/arm/boot/dts/imx7ulp.dtsi | 4 +- arch/arm/boot/dts/meson8.dtsi | 2 +- arch/arm/boot/dts/omap4.dtsi | 4 +- arch/arm/mach-davinci/Kconfig | 1 + arch/arm/mach-omap2/pdata-quirks.c | 6 +- .../dts/allwinner/sun50i-a64-olinuxino-emmc.dts | 2 +- .../boot/dts/allwinner/sun50i-a64-olinuxino.dts | 2 +- arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 9 + arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi | 8 +- arch/arm64/boot/dts/amlogic/meson-axg.dtsi | 12 +- arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi | 12 +- .../dts/amlogic/meson-gxl-s905x-khadas-vim.dts | 4 +- arch/arm64/boot/dts/arm/juno-base.dtsi | 1 - arch/arm64/boot/dts/arm/juno-clocks.dtsi | 4 +- arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 2 +- arch/arm64/boot/dts/freescale/imx8mm-evk.dts | 2 + arch/arm64/boot/dts/freescale/imx8mm.dtsi | 10 +- .../boot/dts/freescale/imx8mq-librem5-devkit.dts | 2 +- arch/arm64/boot/dts/intel/socfpga_agilex.dtsi | 8 +- arch/arm64/boot/dts/marvell/armada-ap806-dual.dtsi | 2 + arch/arm64/boot/dts/marvell/armada-cp110.dtsi | 8 +- arch/arm64/boot/dts/qcom/msm8998-mtp.dtsi | 68 +++++++ arch/arm64/boot/dts/qcom/msm8998.dtsi | 51 +++-- arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi | 2 + arch/arm64/boot/dts/qcom/sdm845.dtsi | 2 +- arch/arm64/boot/dts/renesas/hihope-common.dtsi | 20 +- arch/arm64/boot/dts/renesas/r8a774a1.dtsi | 11 -- arch/arm64/boot/dts/renesas/r8a77970.dtsi | 2 +- arch/s390/kernel/setup.c | 2 +- arch/um/drivers/Kconfig | 2 +- arch/um/drivers/virtio_uml.c | 4 +- arch/um/os-Linux/main.c | 2 +- arch/x86/boot/compressed/head_64.S | 5 + arch/x86/events/intel/uncore_snbep.c | 1 + arch/x86/kernel/cpu/amd.c | 4 +- arch/x86/kernel/cpu/resctrl/core.c | 2 +- arch/x86/kernel/cpu/resctrl/rdtgroup.c | 6 +- block/blk-settings.c | 2 +- block/bsg-lib.c | 2 +- drivers/base/firmware_loader/builtin/Makefile | 2 +- drivers/block/xen-blkfront.c | 4 +- drivers/bus/ti-sysc.c | 10 +- drivers/clk/clk.c | 10 +- drivers/clk/imx/clk-imx7ulp.c | 6 +- drivers/clk/qcom/gcc-sdm845.c | 7 + drivers/clk/samsung/clk-exynos5420.c | 8 + drivers/clk/sprd/common.c | 2 +- drivers/clk/sunxi-ng/ccu-sun8i-r40.c | 6 +- drivers/cpuidle/governors/teo.c | 2 +- drivers/firmware/efi/earlycon.c | 16 +- drivers/gpio/Kconfig | 1 - drivers/gpio/gpio-thunderx.c | 163 ++++++++++------ drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 4 +- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 2 +- drivers/gpu/drm/i915/selftests/i915_random.h | 1 + drivers/hwmon/pmbus/ibm-cffps.c | 37 ++-- drivers/i2c/busses/i2c-iop3xx.c | 12 +- drivers/i2c/busses/i2c-tegra.c | 38 +++- drivers/iio/adc/ad7124.c | 12 +- drivers/iio/chemical/Kconfig | 1 + drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 3 +- drivers/iio/industrialio-buffer.c | 6 +- drivers/iio/light/vcnl4000.c | 3 +- drivers/irqchip/Kconfig | 4 +- drivers/md/dm-snap-persistent.c | 2 +- drivers/md/raid0.c | 2 +- drivers/message/fusion/mptctl.c | 213 +++++---------------- drivers/mtd/chips/cfi_cmdset_0002.c | 60 +++--- drivers/mtd/devices/mchp23k256.c | 20 +- drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c | 11 +- drivers/mtd/spi-nor/spi-nor.c | 4 +- drivers/net/dsa/bcm_sf2.c | 2 +- drivers/net/dsa/sja1105/sja1105_main.c | 2 +- drivers/net/ethernet/broadcom/bcmsysport.c | 7 +- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 29 ++- drivers/net/ethernet/broadcom/bnxt/bnxt.h | 4 +- drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c | 3 + drivers/net/ethernet/hisilicon/hns/hns_enet.c | 4 +- drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 6 + drivers/net/ethernet/intel/i40e/i40e_main.c | 1 + drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 31 +-- .../net/ethernet/mellanox/mlxsw/spectrum_qdisc.c | 30 ++- drivers/net/ethernet/renesas/sh_eth.c | 38 ++-- drivers/net/ethernet/socionext/sni_ave.c | 20 +- drivers/net/ethernet/stmicro/stmmac/common.h | 5 +- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 4 +- .../net/ethernet/stmicro/stmmac/stmmac_selftests.c | 46 +++-- drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c | 4 + drivers/net/hyperv/rndis_filter.c | 2 - drivers/net/macvlan.c | 5 +- drivers/net/phy/dp83867.c | 8 +- drivers/net/usb/lan78xx.c | 1 + drivers/net/usb/r8152.c | 3 + drivers/net/wan/fsl_ucc_hdlc.c | 2 +- drivers/net/wireless/realtek/rtw88/phy.c | 17 +- drivers/net/wireless/realtek/rtw88/phy.h | 9 + drivers/net/wireless/realtek/rtw88/rtw8822c.c | 4 +- drivers/net/wireless/st/cw1200/fwio.c | 6 +- drivers/nfc/pn533/usb.c | 2 +- drivers/ptp/ptp_clock.c | 4 +- drivers/reset/core.c | 6 +- drivers/s390/crypto/zcrypt_ccamisc.c | 4 +- drivers/scsi/bnx2i/bnx2i_iscsi.c | 2 +- drivers/scsi/esas2r/esas2r_flash.c | 1 + drivers/scsi/fnic/vnic_dev.c | 20 +- drivers/scsi/hisi_sas/hisi_sas_main.c | 3 - drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 11 +- drivers/scsi/lpfc/lpfc_scsi.c | 2 +- drivers/scsi/lpfc/lpfc_sli.c | 56 +++--- drivers/scsi/qla2xxx/qla_init.c | 6 +- drivers/scsi/qla2xxx/qla_isr.c | 6 +- drivers/scsi/qla4xxx/ql4_mbx.c | 3 - drivers/scsi/scsi_trace.c | 113 ++++------- drivers/scsi/scsi_transport_sas.c | 9 +- drivers/scsi/storvsc_drv.c | 4 +- drivers/soc/amlogic/meson-ee-pwrc.c | 24 ++- drivers/staging/comedi/drivers/ni_routes.c | 12 +- drivers/target/target_core_fabric_lib.c | 2 +- drivers/usb/core/hub.c | 1 + drivers/usb/serial/ch341.c | 6 +- drivers/usb/serial/io_edgeport.c | 16 +- drivers/usb/serial/keyspan.c | 4 + drivers/usb/serial/opticon.c | 2 +- drivers/usb/serial/option.c | 6 + drivers/usb/serial/quatech2.c | 6 + drivers/usb/serial/usb-serial-simple.c | 2 + drivers/usb/serial/usb-serial.c | 3 + fs/btrfs/inode.c | 73 +++---- fs/btrfs/ioctl.c | 14 +- fs/btrfs/qgroup.c | 6 +- fs/btrfs/relocation.c | 51 ++++- fs/btrfs/root-tree.c | 10 +- fs/btrfs/volumes.c | 6 +- fs/fuse/file.c | 4 +- fs/io_uring.c | 6 + fs/reiserfs/xattr.c | 8 +- include/dt-bindings/reset/amlogic,meson8b-reset.h | 6 +- include/linux/blkdev.h | 8 +- include/linux/mm.h | 18 +- include/linux/mmzone.h | 5 +- include/linux/netdevice.h | 2 +- include/linux/regulator/ab8500.h | 2 - include/linux/skmsg.h | 13 +- include/linux/tnum.h | 2 +- include/net/tcp.h | 6 +- include/trace/events/huge_memory.h | 3 +- init/main.c | 1 + kernel/bpf/tnum.c | 9 +- kernel/bpf/verifier.c | 13 +- kernel/cpu.c | 143 +++++++------- kernel/events/core.c | 4 +- kernel/locking/lockdep.c | 7 +- kernel/locking/rwsem.c | 4 +- kernel/ptrace.c | 15 +- kernel/time/tick-sched.c | 14 +- mm/huge_memory.c | 38 ++-- mm/memcontrol.c | 37 +--- mm/page-writeback.c | 4 +- mm/page_alloc.c | 37 ++-- mm/shmem.c | 7 +- mm/slab.c | 4 +- mm/slab_common.c | 3 +- mm/slub.c | 2 +- mm/sparse.c | 9 +- mm/vmalloc.c | 4 +- net/batman-adv/distributed-arp-table.c | 4 +- net/core/dev.c | 12 -- net/core/devlink.c | 2 +- net/core/filter.c | 20 +- net/core/skmsg.c | 2 + net/core/sock_map.c | 7 +- net/dsa/tag_gswip.c | 2 +- net/dsa/tag_qca.c | 3 - net/ipv4/netfilter/arp_tables.c | 19 +- net/ipv4/tcp.c | 6 +- net/ipv4/tcp_bpf.c | 17 +- net/ipv4/tcp_input.c | 7 +- net/ipv4/tcp_ulp.c | 6 +- net/netfilter/ipset/ip_set_bitmap_gen.h | 2 +- net/netfilter/nf_nat_proto.c | 13 ++ net/netfilter/nf_tables_api.c | 38 ++-- net/netfilter/nft_tunnel.c | 5 +- net/sched/act_ctinfo.c | 11 ++ net/sched/act_ife.c | 7 +- net/tipc/bcast.c | 24 ++- net/tipc/socket.c | 32 ++-- net/tls/tls_main.c | 10 +- net/tls/tls_sw.c | 31 ++- net/wireless/nl80211.c | 3 + net/wireless/rdev-ops.h | 4 + net/wireless/sme.c | 6 +- net/wireless/util.c | 2 +- sound/core/seq/seq_timer.c | 14 +- sound/firewire/dice/dice-extension.c | 5 +- sound/firewire/tascam/amdtp-tascam.c | 5 +- sound/soc/codecs/msm8916-wcd-analog.c | 20 +- sound/soc/codecs/msm8916-wcd-digital.c | 6 + sound/soc/intel/boards/bytcht_es8316.c | 3 +- sound/soc/stm/stm32_adfsdm.c | 12 +- sound/soc/stm/stm32_sai_sub.c | 194 +++++++++++++------ sound/usb/pcm.c | 2 +- tools/bpf/bpftool/btf_dumper.c | 2 +- tools/perf/builtin-report.c | 5 +- tools/perf/builtin-script.c | 5 - tools/perf/util/hist.h | 4 +- tools/perf/util/probe-finder.c | 32 +--- .../selftests/drivers/net/mlxsw/qos_mc_aware.sh | 8 +- 221 files changed, 1656 insertions(+), 1191 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/222 ARM: dts: meson8: fix the size of the PMU registers
From: Martin Blumenstingl <[email protected]>
commit 46c9585ed4af688ff1be6d4e76d7ed2f04de4fba upstream.
The PMU registers are at least 0x18 bytes wide. Meson8b already uses a size of 0x18. The structure of the PMU registers on Meson8 and Meson8b is similar but not identical.
Meson8 and Meson8b have the following registers in common (starting at AOBUS + 0xe0):
#define AO_RTI_PWR_A9_CNTL0 0xe0 (0x38 << 2)
#define AO_RTI_PWR_A9_CNTL1 0xe4 (0x39 << 2)
#define AO_RTI_GEN_PWR_SLEEP0 0xe8 (0x3a << 2)
#define AO_RTI_GEN_PWR_ISO0 0x4c (0x3b << 2)
Meson8b additionally has these three registers:
#define AO_RTI_GEN_PWR_ACK0 0xf0 (0x3c << 2)
#define AO_RTI_PWR_A9_MEM_PD0 0xf4 (0x3d << 2)
#define AO_RTI_PWR_A9_MEM_PD1 0xf8 (0x3e << 2)
Thus we can assume that the register size of the PMU IP blocks is identical on both SoCs (and Meson8 just contains some reserved registers in that area) because the CEC registers start right after the PMU (AO_RTI_*) registers at AOBUS + 0x100 (0x40 << 2).
The upcoming power domain driver will need to read and write the AO_RTI_GEN_PWR_SLEEP0 and AO_RTI_GEN_PWR_ISO0 registers, so the updated size is needed for that driver to work.
--- arch/arm/boot/dts/meson8.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/boot/dts/meson8.dtsi +1 -1
@@ -253,7 +253,7 @@ &aobus { pmu: pmu@e0 { compatible = "amlogic,meson8-pmu", "syscon"; - reg = <0xe0 0x8>; + reg = <0xe0 0x18>; }; pinctrl_aobus: pinctrl@84 {
Greg Kroah-Hartman
maintainerPATCH 2/222 clk: qcom: gcc-sdm845: Add missing flag to votable GDSCs
In reply to Greg Kroah-HartmanFrom: Georgi Djakov <[email protected]>
commit 5e82548e26ef62e257dc2ff37c11acb5eb72728e upstream.
On sdm845 devices, during boot we see the following warnings (unless we have added 'pd_ignore_unused' to the kernel command line):
hlos1_vote_mmnoc_mmu_tbu_sf_gdsc status stuck at 'on' hlos1_vote_mmnoc_mmu_tbu_hf1_gdsc status stuck at 'on' hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc status stuck at 'on' hlos1_vote_aggre_noc_mmu_tbu2_gdsc status stuck at 'on' hlos1_vote_aggre_noc_mmu_tbu1_gdsc status stuck at 'on' hlos1_vote_aggre_noc_mmu_pcie_tbu_gdsc status stuck at 'on' hlos1_vote_aggre_noc_mmu_audio_tbu_gdsc status stuck at 'on'
As the name of these GDSCs suggests, they are "votable" and in downstream DT, they all have the property "qcom,no-status-check-on-disable", which means that we should not poll the status bit when we disable them.
Luckily the VOTABLE flag already exists and it does exactly what we need, so let's make use of it to make the warnings disappear.
--- drivers/clk/qcom/gcc-sdm845.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/clk/qcom/gcc-sdm845.c +7 -0
@@ -3255,6 +3255,7 @@ static struct gdsc hlos1_vote_aggre_noc_ .name = "hlos1_vote_aggre_noc_mmu_audio_tbu_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, }; static struct gdsc hlos1_vote_aggre_noc_mmu_pcie_tbu_gdsc = {
@@ -3263,6 +3264,7 @@ static struct gdsc hlos1_vote_aggre_noc_ .name = "hlos1_vote_aggre_noc_mmu_pcie_tbu_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, }; static struct gdsc hlos1_vote_aggre_noc_mmu_tbu1_gdsc = {
@@ -3271,6 +3273,7 @@ static struct gdsc hlos1_vote_aggre_noc_ .name = "hlos1_vote_aggre_noc_mmu_tbu1_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, }; static struct gdsc hlos1_vote_aggre_noc_mmu_tbu2_gdsc = {
@@ -3279,6 +3282,7 @@ static struct gdsc hlos1_vote_aggre_noc_ .name = "hlos1_vote_aggre_noc_mmu_tbu2_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, }; static struct gdsc hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc = {
@@ -3287,6 +3291,7 @@ static struct gdsc hlos1_vote_mmnoc_mmu_ .name = "hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, }; static struct gdsc hlos1_vote_mmnoc_mmu_tbu_hf1_gdsc = {
@@ -3295,6 +3300,7 @@ static struct gdsc hlos1_vote_mmnoc_mmu_ .name = "hlos1_vote_mmnoc_mmu_tbu_hf1_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, }; static struct gdsc hlos1_vote_mmnoc_mmu_tbu_sf_gdsc = {
@@ -3303,6 +3309,7 @@ static struct gdsc hlos1_vote_mmnoc_mmu_ .name = "hlos1_vote_mmnoc_mmu_tbu_sf_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, }; static struct clk_regmap *gcc_sdm845_clocks[] = {
Greg Kroah-Hartman
maintainerPATCH 3/222 soc: amlogic: meson-ee-pwrc: propagate PD provider registration errors
In reply to Greg Kroah-HartmanFrom: Martin Blumenstingl <[email protected]>
commit 0766d65e6afaea8b80205a468207de9f18cd7ec8 upstream.
of_genpd_add_provider_onecell() can return an error. Propagate the error so the driver registration fails when of_genpd_add_provider_onecell() did not work.
--- drivers/soc/amlogic/meson-ee-pwrc.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/soc/amlogic/meson-ee-pwrc.c +1 -3
@@ -441,9 +441,7 @@ static int meson_ee_pwrc_probe(struct pl pwrc->xlate.domains[i] = &dom->base; } -of_genpd_add_provider_onecell (pdev->dev.of_node, &pwrc->xlate); - -return 0 ; +return of_genpd_add_provider_onecell (pdev->dev.of_node, &pwrc->xlate); }static void meson_ee_pwrc_shutdown (struct platform_device *pdev)
Greg Kroah-Hartman
maintainerPATCH 4/222 soc: amlogic: meson-ee-pwrc: propagate errors from pm_genpd_init()
In reply to Greg Kroah-HartmanFrom: Martin Blumenstingl <[email protected]>
commit c67aafd60d7e323fe74bf45fab60148f84cf9b95 upstream.
pm_genpd_init() can return an error. Propagate the error code to prevent the driver from indicating that it successfully probed while there were errors during pm_genpd_init().
--- drivers/soc/amlogic/meson-ee-pwrc.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-)
drivers/soc/amlogic/meson-ee-pwrc.c +14 -6
@@ -323,6 +323,8 @@ static int meson_ee_pwrc_init_domain(strstruct meson_ee_pwrc *pwrc, struct meson_ee_pwrc_domain *dom) { + int ret; + dom->pwrc = pwrc; dom->num_rstc = dom->desc.reset_names_count; dom->num_clks = dom->desc.clk_names_count;
@@ -368,15 +370,21 @@ static int meson_ee_pwrc_init_domain(str* prepare/enable counters won't be in sync. */ if (dom->num_clks && dom->desc.get_power && !dom->desc.get_power (dom)) { -int ret =clk_bulk_prepare_enable (dom->num_clks, dom->clks); + ret =clk_bulk_prepare_enable (dom->num_clks, dom->clks);if (ret)return ret; -pm_genpd_init (&dom->base, &pm_domain_always_on_gov, false); - }else -pm_genpd_init (&dom->base,NULL , - (dom->desc.get_power ? - dom->desc.get_power (dom) : true)); + ret =pm_genpd_init (&dom->base, &pm_domain_always_on_gov, + false); +if (ret) +return ret; + }else { + ret =pm_genpd_init (&dom->base,NULL , + (dom->desc.get_power ? + dom->desc.get_power (dom) : true)); +if (ret) +return ret; + }return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 5/222 dt-bindings: reset: meson8b: fix duplicate reset IDs
In reply to Greg Kroah-HartmanFrom: Martin Blumenstingl <[email protected]>
commit 4881873f4cc1460f63d85fa81363d56be328ccdc upstream.
According to the public S805 datasheet the RESET2 register uses the following bits for the PIC_DC, PSC and NAND reset lines:
- PIC_DC is at bit 3 (meaning: RESET_VD_RMEM + 3)
- PSC is at bit 4 (meaning: RESET_VD_RMEM + 4)
- NAND is at bit 5 (meaning: RESET_VD_RMEM + 4)
Update the reset IDs of these three reset lines so they don't conflict with PIC_DC and map to the actual hardware reset lines.
--- include/dt-bindings/reset/amlogic,meson8b-reset.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
include/dt-bindings/reset/amlogic,meson8b-reset.h +3 -3
@@ -46,9 +46,9 @@#define RESET_VD_RMEM 64#define RESET_AUDIN 65#define RESET_DBLK 66 -#define RESET_PIC_DC 66 -#define RESET_PSC 66 -#define RESET_NAND 66 +#define RESET_PIC_DC 67 +#define RESET_PSC 68 +#define RESET_NAND 69#define RESET_GE2D 70#define RESET_PARSER_REG 71#define RESET_PARSER_FETCH 72
Greg Kroah-Hartman
maintainerPATCH 6/222 ARM: dts: imx6q-dhcom: fix rtc compatible
In reply to Greg Kroah-HartmanFrom: Alexandre Belloni <[email protected]>
commit 7d7778b1396bc9e2a3875009af522beb4ea9355a upstream.
The only correct and documented compatible string for the rv3029 is microcrystal,rv3029. Fix it up.
--- arch/arm/boot/dts/imx6q-dhcom-som.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/boot/dts/imx6q-dhcom-som.dtsi +1 -1
@@ -206,7 +206,7 @@ }; rtc@56 { - compatible = "rv3029c2"; + compatible = "microcrystal,rv3029"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_rtc_hw300>; reg = <0x56>;
Greg Kroah-Hartman
maintainerPATCH 7/222 arm64: dts: ls1028a: fix endian setting for dcfg
In reply to Greg Kroah-HartmanFrom: Yinbo Zhu <[email protected]>
commit 33eae7fb2e593fdbaac15d843e2558379c6d1149 upstream.
DCFG block uses little endian. Fix it so that register access becomes correct.
--- arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi +1 -1
@@ -158,7 +158,7 @@ dcfg: syscon@1e00000 { compatible = "fsl,ls1028a-dcfg", "syscon"; reg = <0x0 0x1e00000 0x0 0x10000>; - big-endian; + little-endian; }; rst: syscon@1e60000 {
Greg Kroah-Hartman
maintainerPATCH 8/222 arm64: dts: imx8mm: Change SDMA1 ahb clock for imx8mm
In reply to Greg Kroah-HartmanFrom: Adam Ford <[email protected]>
commit 24a572bf67994223e722cadfe663e15ba221882a upstream.
Using SDMA1 with UART1 is causing a "Timeout waiting for CH0" error. This patch changes to ahb clock from SDMA1_ROOT to AHB which fixes the timeout error.
--- arch/arm64/boot/dts/freescale/imx8mm.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/freescale/imx8mm.dtsi +1 -1
@@ -741,7 +741,7 @@ reg = <0x30bd0000 0x10000>; interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clk IMX8MM_CLK_SDMA1_ROOT>, - <&clk IMX8MM_CLK_SDMA1_ROOT>; + <&clk IMX8MM_CLK_AHB>; clock-names = "ipg", "ahb"; #dma-cells = <3>; fsl,sdma-ram-script-name = "imx/sdma/sdma-imx7d.bin";
Greg Kroah-Hartman
maintainerPATCH 9/222 bus: ti-sysc: Fix iterating over clocks
In reply to Greg Kroah-HartmanFrom: Tony Lindgren <[email protected]>
commit 2c81f0f6d3f52ac222a5dc07a6e5c06e1543e88b upstream.
Commit d878970f6ce1 ("bus: ti-sysc: Add separate functions for handling clocks") separated handling of optional clocks from the main clocks, but introduced an issue where we do not necessarily allocate a slot for both fck and ick clocks, but still assume fixed slots for enumerating over the clocks.
Let's fix the issue by ensuring we always have slots for both fck and ick even if we don't use ick, and don't attempt to enumerate optional clocks if not allocated.
In the long run we might want to simplify things a bit by only allocating space only for the optional clocks as we have only few devices with optional clocks.
--- drivers/bus/ti-sysc.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
drivers/bus/ti-sysc.c +8 -2
@@ -343,6 +343,12 @@ static int sysc_get_clocks(struct sysc *return -EINVAL ; } +/* Always add a slot for main clocks fck and ick even if unused */ +if (!nr_fck) + ddata->nr_clocks++; +if (!nr_ick) + ddata->nr_clocks++; + ddata->clocks =devm_kcalloc (ddata->dev, ddata->nr_clocks,sizeof (*ddata->clocks),GFP_KERNEL );
@@ -421,7 +427,7 @@ static int sysc_enable_opt_clocks(structstruct clk *clock;int i, error; -if (!ddata->clocks) +if (!ddata->clocks || ddata->nr_clocks <SYSC_OPTFCK0 +1 )return 0 ;for (i =SYSC_OPTFCK0 ; i <SYSC_MAX_CLOCKS ; i++) {
@@ -455,7 +461,7 @@ static void sysc_disable_opt_clocks(strustruct clk *clock;int i; -if (!ddata->clocks) +if (!ddata->clocks || ddata->nr_clocks <SYSC_OPTFCK0 +1 )return ;for (i =SYSC_OPTFCK0 ; i <SYSC_MAX_CLOCKS ; i++) {
Greg Kroah-Hartman
maintainerPATCH 10/222 clk: Dont try to enable critical clocks if prepare failed
In reply to Greg Kroah-HartmanFrom: Guenter Roeck <[email protected]>
commit 12ead77432f2ce32dea797742316d15c5800cb32 upstream.
The following traceback is seen if a critical clock fails to prepare.
bcm2835-clk 3f101000.cprman: plld: couldn't lock PLL
------------[ cut here ]------------ Enabling unprepared plld_per WARNING: CPU: 1 PID: 1 at drivers/clk/clk.c:1014 clk_core_enable+0xcc/0x2c0 ... Call trace: clk_core_enable+0xcc/0x2c0 __clk_register+0x5c4/0x788 devm_clk_hw_register+0x4c/0xb0 bcm2835_register_pll_divider+0xc0/0x150 bcm2835_clk_probe+0x134/0x1e8 platform_drv_probe+0x50/0xa0 really_probe+0xd4/0x308 driver_probe_device+0x54/0xe8 device_driver_attach+0x6c/0x78 __driver_attach+0x54/0xd8
...
Check return values from clk_core_prepare() and clk_core_enable() and bail out if any of those functions returns an error.
--- drivers/clk/clk.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
drivers/clk/clk.c +8 -2
@@ -3408,11 +3408,17 @@ static int __clk_core_init(struct clk_coif (core->flags &CLK_IS_CRITICAL ) {unsigned long flags; -clk_core_prepare (core); + ret =clk_core_prepare (core); +if (ret) + goto out; flags =clk_enable_lock (); -clk_core_enable (core); + ret =clk_core_enable (core);clk_enable_unlock (flags); +if (ret) { +clk_core_unprepare (core); + goto out; + } }clk_core_reparent_orphans_nolock ();
Greg Kroah-Hartman
maintainerPATCH 11/222 Revert "gpio: thunderx: Switch to GPIOLIB_IRQCHIP"
In reply to Greg Kroah-HartmanFrom: Kevin Hao <[email protected]>
commit a564ac35d60564dd5b509e32afdc04e7aafee40e upstream.
This reverts commit a7fc89f9d5fcc10a5474cfe555f5a9e5df8b0f1f because there are some bugs in this commit, and we don't have a simple way to fix these bugs. So revert this commit to make the thunderx gpio work on the stable kernel at least. We will switch to GPIOLIB_IRQCHIP for thunderx gpio by following patches.
--- drivers/gpio/Kconfig | 1 drivers/gpio/gpio-thunderx.c | 163 ++++++++++++++++++++++++++++--------------- 2 files changed, 107 insertions(+), 57 deletions(-)
drivers/gpio/Kconfig +0 -1
@@ -546,7 +546,6 @@ config GPIO_THUNDERX tristate "Cavium ThunderX/OCTEON-TX GPIO" depends on ARCH_THUNDER || (64BIT && COMPILE_TEST) depends on PCI_MSI - select GPIOLIB_IRQCHIP select IRQ_DOMAIN_HIERARCHY select IRQ_FASTEOI_HIERARCHY_HANDLERS help
drivers/gpio/gpio-thunderx.c +107 -56
260 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 12/222 arm64: dts: imx8mq-librem5-devkit: use correct interrupt for the magnetometer
In reply to Greg Kroah-HartmanFrom: Angus Ainslie (Purism) <[email protected]>
commit 106f7b3bf943d267eb657f34616adcaadb2ab07f upstream.
The LSM9DS1 uses a high level interrupt.
--- arch/arm64/boot/dts/freescale/imx8mq-librem5-devkit.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/freescale/imx8mq-librem5-devkit.dts +1 -1
@@ -421,7 +421,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_imu>; interrupt-parent = <&gpio3>; - interrupts = <19 IRQ_TYPE_LEVEL_LOW>; + interrupts = <19 IRQ_TYPE_LEVEL_HIGH>; vdd-supply = <®_3v3_p>; vddio-supply = <®_3v3_p>; };
Greg Kroah-Hartman
maintainerPATCH 13/222 ASoC: msm8916-wcd-digital: Reset RX interpolation path after use
In reply to Greg Kroah-HartmanFrom: Stephan Gerhold <[email protected]>
commit 85578bbd642f65065039b1765ebe1a867d5435b0 upstream.
For some reason, attempting to route audio through QDSP6 on MSM8916 causes the RX interpolation path to get "stuck" after playing audio a few times. In this situation, the analog codec part is still working, but the RX path in the digital codec stops working, so you only hear the analog parts powering up. After a reboot everything works again.
So far I was not able to reproduce the problem when using lpass-cpu.
The downstream kernel driver avoids this by resetting the RX interpolation path after use. In mainline we do something similar for the TX decimator (LPASS_CDC_CLK_TX_RESET_B1_CTL), but the interpolator reset (LPASS_CDC_CLK_RX_RESET_CTL) got lost when the msm8916-wcd driver was split into analog and digital.
Fix this problem by adding the reset tomsm8916_wcd_digital_enable_interpolator().
--- sound/soc/codecs/msm8916-wcd-digital.c | 6 ++++++ 1 file changed, 6 insertions(+)
sound/soc/codecs/msm8916-wcd-digital.c +6 -0
@@ -586,6 +586,12 @@ static int msm8916_wcd_digital_enable_insnd_soc_component_write (component, rx_gain_reg[w->shift],snd_soc_component_read32 (component, rx_gain_reg[w->shift]));break ; +case SND_SOC_DAPM_POST_PMD : +snd_soc_component_update_bits (component,LPASS_CDC_CLK_RX_RESET_CTL , +1 << w->shift,1 << w->shift); +snd_soc_component_update_bits (component,LPASS_CDC_CLK_RX_RESET_CTL , +1 << w->shift,0x0 ); +break ; }return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 14/222 ASoC: stm32: sai: fix possible circular locking
In reply to Greg Kroah-HartmanFrom: Olivier Moysan <[email protected]>
commit a14bf98c045bf119b7e779f186528e38c6428830 upstream.
In current driver, locks can be taken as follows:
- Register access: take a lock on regmap config and then on clock.
- Master clock provider: take a lock on clock and then on regmap config. This can lead to the circular locking summarized below.
Remove peripheral clock management through regmap framework, and manage peripheral clock in driver instead. On register access, lock on clock is taken first, which allows to avoid possible locking issue.
[ 6696.561513] ======================================================
[ 6696.567670] WARNING: possible circular locking dependency detected
[ 6696.573842] 4.19.49 #866 Not tainted
[ 6696.577397] ------------------------------------------------------
[ 6696.583566] pulseaudio/6439 is trying to acquire lock:
[ 6696.588697] 87b0a25b (enable_lock){..-.}, at: clk_enable_lock+0x64/0x128
[ 6696.595377]
[ 6696.595377] but task is already holding lock:
[ 6696.601197] d858f825 (stm32_sai_sub:1342:(sai->regmap_config)->lock){....}
...
[ 6696.812513] Possible unsafe locking scenario:
[ 6696.812513]
[ 6696.818418] CPU0 CPU1
[ 6696.822935] ---- ----
[ 6696.827451] lock(stm32_sai_sub:1342:(sai->regmap_config)->lock);
[ 6696.833618] lock(enable_lock);
[ 6696.839350] lock(stm32_sai_sub:1342:
(sai->regmap_config)->lock);
[ 6696.848035] lock(enable_lock);--- sound/soc/stm/stm32_sai_sub.c | 196 ++++++++++++++++++++++++++++++------------ 1 file changed, 141 insertions(+), 55 deletions(-)
sound/soc/stm/stm32_sai_sub.c +141 -55
@@ -184,6 +184,56 @@ static bool stm32_sai_sub_writeable_reg( } } +static int stm32_sai_sub_reg_up (struct stm32_sai_sub_data *sai, +unsigned int reg,unsigned int mask, +unsigned int val) +{ +int ret; + + ret =clk_enable (sai->pdata->pclk); +if (ret <0 ) +return ret; + + ret =regmap_update_bits (sai->regmap, reg, mask, val); + +clk_disable (sai->pdata->pclk); + +return ret; +} + +static int stm32_sai_sub_reg_wr (struct stm32_sai_sub_data *sai, +unsigned int reg,unsigned int mask, +unsigned int val) +{ +int ret; + + ret =clk_enable (sai->pdata->pclk); +if (ret <0 ) +return ret; + + ret =regmap_write_bits (sai->regmap, reg, mask, val); + +clk_disable (sai->pdata->pclk); + +return ret; +} + +static int stm32_sai_sub_reg_rd (struct stm32_sai_sub_data *sai, +unsigned int reg,unsigned int *val) +{ +int ret; + + ret =clk_enable (sai->pdata->pclk); +if (ret <0 ) +return ret; + + ret =regmap_read (sai->regmap, reg, val); + +clk_disable (sai->pdata->pclk); + +return ret; +} +static const struct regmap_config stm32_sai_sub_regmap_config_f4 = { .reg_bits =32 , .reg_stride =4 ,
@@ -295,7 +345,7 @@ static int stm32_sai_set_clk_div(struct mask =SAI_XCR1_MCKDIV_MASK (SAI_XCR1_MCKDIV_WIDTH (version)); cr1 =SAI_XCR1_MCKDIV_SET (div); - ret =regmap_update_bits (sai->regmap,STM_SAI_CR1_REGX , mask, cr1); + ret =stm32_sai_sub_reg_up (sai,STM_SAI_CR1_REGX , mask, cr1);if (ret <0 )dev_err (&sai->pdev->dev,"Failed to update CR1 register\n" );
@@ -372,8 +422,8 @@ static int stm32_sai_mclk_enable(structdev_dbg (&sai->pdev->dev,"Enable master clock\n" ); -return regmap_update_bits (sai->regmap,STM_SAI_CR1_REGX , -SAI_XCR1_MCKEN ,SAI_XCR1_MCKEN ); +return stm32_sai_sub_reg_up (sai,STM_SAI_CR1_REGX , +SAI_XCR1_MCKEN ,SAI_XCR1_MCKEN ); }static void stm32_sai_mclk_disable (struct clk_hw *hw)
@@ -383,7 +433,7 @@ static void stm32_sai_mclk_disable(strucdev_dbg (&sai->pdev->dev,"Disable master clock\n" ); -regmap_update_bits (sai->regmap,STM_SAI_CR1_REGX ,SAI_XCR1_MCKEN ,0 ); +stm32_sai_sub_reg_up (sai,STM_SAI_CR1_REGX ,SAI_XCR1_MCKEN ,0 ); }static const struct clk_ops mclk_ops = {
@@ -446,15 +496,15 @@ static irqreturn_t stm32_sai_isr(int irqunsigned int sr, imr, flags;snd_pcm_state_t status =SNDRV_PCM_STATE_RUNNING ; -regmap_read (sai->regmap,STM_SAI_IMR_REGX , &imr); -regmap_read (sai->regmap,STM_SAI_SR_REGX , &sr); +stm32_sai_sub_reg_rd (sai,STM_SAI_IMR_REGX , &imr); +stm32_sai_sub_reg_rd (sai,STM_SAI_SR_REGX , &sr); flags = sr & imr;if (!flags)return IRQ_NONE ; -regmap_write_bits (sai->regmap,STM_SAI_CLRFR_REGX ,SAI_XCLRFR_MASK , -SAI_XCLRFR_MASK ); +stm32_sai_sub_reg_wr (sai,STM_SAI_CLRFR_REGX ,SAI_XCLRFR_MASK , +SAI_XCLRFR_MASK );if (!sai->substream) {dev_err (&pdev->dev,"Device stopped. Spurious IRQ 0x%x\n" , sr);
@@ -503,8 +553,8 @@ static int stm32_sai_set_sysclk(struct sint ret;if (dir ==SND_SOC_CLOCK_OUT && sai->sai_mclk) { - ret =regmap_update_bits (sai->regmap,STM_SAI_CR1_REGX , -SAI_XCR1_NODIV , + ret =stm32_sai_sub_reg_up (sai,STM_SAI_CR1_REGX , +SAI_XCR1_NODIV , freq ?0 :SAI_XCR1_NODIV );if (ret <0 )return ret;
@@ -583,7 +633,7 @@ static int stm32_sai_set_dai_tdm_slot(st slotr_mask |=SAI_XSLOTR_SLOTEN_MASK ; -regmap_update_bits (sai->regmap,STM_SAI_SLOTR_REGX , slotr_mask, slotr); +stm32_sai_sub_reg_up (sai,STM_SAI_SLOTR_REGX , slotr_mask, slotr); sai->slot_width = slot_width; sai->slots = slots;
@@ -665,7 +715,7 @@ static int stm32_sai_set_dai_fmt(struct cr1_mask |=SAI_XCR1_CKSTR ; frcr_mask |=SAI_XFRCR_FSPOL ; -regmap_update_bits (sai->regmap,STM_SAI_FRCR_REGX , frcr_mask, frcr); +stm32_sai_sub_reg_up (sai,STM_SAI_FRCR_REGX , frcr_mask, frcr);/* DAI clock master masks */ switch (fmt &SND_SOC_DAIFMT_MASTER_MASK ) {
@@ -693,7 +743,7 @@ static int stm32_sai_set_dai_fmt(struct cr1_mask |=SAI_XCR1_SLAVE ; conf_update: - ret =regmap_update_bits (sai->regmap,STM_SAI_CR1_REGX , cr1_mask, cr1); + ret =stm32_sai_sub_reg_up (sai,STM_SAI_CR1_REGX , cr1_mask, cr1);if (ret <0 ) {dev_err (cpu_dai->dev,"Failed to update CR1 register\n" );return ret;
@@ -730,12 +780,12 @@ static int stm32_sai_startup(struct snd_ }/* Enable ITs */ -regmap_write_bits (sai->regmap,STM_SAI_CLRFR_REGX , -SAI_XCLRFR_MASK ,SAI_XCLRFR_MASK ); +stm32_sai_sub_reg_wr (sai,STM_SAI_CLRFR_REGX , +SAI_XCLRFR_MASK ,SAI_XCLRFR_MASK ); imr =SAI_XIMR_OVRUDRIE ;if (STM_SAI_IS_CAPTURE (sai)) { -regmap_read (sai->regmap,STM_SAI_CR2_REGX , &cr2); +stm32_sai_sub_reg_rd (sai,STM_SAI_CR2_REGX , &cr2);if (cr2 &SAI_XCR2_MUTECNT_MASK ) imr |=SAI_XIMR_MUTEDETIE ; }
@@ -745,8 +795,8 @@ static int stm32_sai_startup(struct snd_else imr |=SAI_XIMR_AFSDETIE |SAI_XIMR_LFSDETIE ; -regmap_update_bits (sai->regmap,STM_SAI_IMR_REGX , -SAI_XIMR_MASK , imr); +stm32_sai_sub_reg_up (sai,STM_SAI_IMR_REGX , +SAI_XIMR_MASK , imr);return 0 ; }
@@ -763,10 +813,10 @@ static int stm32_sai_set_config(struct s* SAI fifo threshold is set to half fifo, to keep enough space * for DMA incoming bursts. */ -regmap_write_bits (sai->regmap,STM_SAI_CR2_REGX , -SAI_XCR2_FFLUSH |SAI_XCR2_FTH_MASK , -SAI_XCR2_FFLUSH | -SAI_XCR2_FTH_SET (STM_SAI_FIFO_TH_HALF )); +stm32_sai_sub_reg_wr (sai,STM_SAI_CR2_REGX , +SAI_XCR2_FFLUSH |SAI_XCR2_FTH_MASK , +SAI_XCR2_FFLUSH | +SAI_XCR2_FTH_SET (STM_SAI_FIFO_TH_HALF ));/* DS bits in CR1 not set for SPDIF (size forced to 24 bits).*/ if (STM_SAI_PROTOCOL_IS_SPDIF (sai)) {
@@ -795,7 +845,7 @@ static int stm32_sai_set_config(struct sif ((sai->slots ==2 ) && (params_channels (params) ==1 )) cr1 |=SAI_XCR1_MONO ; - ret =regmap_update_bits (sai->regmap,STM_SAI_CR1_REGX , cr1_mask, cr1); + ret =stm32_sai_sub_reg_up (sai,STM_SAI_CR1_REGX , cr1_mask, cr1);if (ret <0 ) {dev_err (cpu_dai->dev,"Failed to update CR1 register\n" );return ret;
@@ -809,7 +859,7 @@ static int stm32_sai_set_slots(struct snstruct stm32_sai_sub_data *sai =snd_soc_dai_get_drvdata (cpu_dai);int slotr, slot_sz; -regmap_read (sai->regmap,STM_SAI_SLOTR_REGX , &slotr); +stm32_sai_sub_reg_rd (sai,STM_SAI_SLOTR_REGX , &slotr);/* * If SLOTSZ is set to auto in SLOTR, align slot width on data size
@@ -831,16 +881,16 @@ static int stm32_sai_set_slots(struct sn sai->slots =2 ;/* The number of slots in the audio frame is equal to NBSLOT[3:0] + 1*/ -regmap_update_bits (sai->regmap,STM_SAI_SLOTR_REGX , -SAI_XSLOTR_NBSLOT_MASK , -SAI_XSLOTR_NBSLOT_SET ((sai->slots -1 ))); +stm32_sai_sub_reg_up (sai,STM_SAI_SLOTR_REGX , +SAI_XSLOTR_NBSLOT_MASK , +SAI_XSLOTR_NBSLOT_SET ((sai->slots -1 )));/* Set default slots mask if not already set from DT */ if (!(slotr &SAI_XSLOTR_SLOTEN_MASK )) { sai->slot_mask = (1 << sai->slots) -1 ; -regmap_update_bits (sai->regmap, -STM_SAI_SLOTR_REGX ,SAI_XSLOTR_SLOTEN_MASK , -SAI_XSLOTR_SLOTEN_SET (sai->slot_mask)); +stm32_sai_sub_reg_up (sai, +STM_SAI_SLOTR_REGX ,SAI_XSLOTR_SLOTEN_MASK , +SAI_XSLOTR_SLOTEN_SET (sai->slot_mask)); } dev_dbg(cpu_dai->dev, "Slots %d, slot width %d\n",
@@ -870,14 +920,14 @@ static void stm32_sai_set_frame(struct sdev_dbg (cpu_dai->dev,"Frame length %d, frame active %d\n" , sai->fs_length, fs_active); -regmap_update_bits (sai->regmap,STM_SAI_FRCR_REGX , frcr_mask, frcr); +stm32_sai_sub_reg_up (sai,STM_SAI_FRCR_REGX , frcr_mask, frcr);if ((sai->fmt &SND_SOC_DAIFMT_FORMAT_MASK ) ==SND_SOC_DAIFMT_LSB ) { offset = sai->slot_width - sai->data_size; -regmap_update_bits (sai->regmap,STM_SAI_SLOTR_REGX , -SAI_XSLOTR_FBOFF_MASK , -SAI_XSLOTR_FBOFF_SET (offset)); +stm32_sai_sub_reg_up (sai,STM_SAI_SLOTR_REGX , +SAI_XSLOTR_FBOFF_MASK , +SAI_XSLOTR_FBOFF_SET (offset)); } }
@@ -994,9 +1044,9 @@ static int stm32_sai_configure_clock(strreturn -EINVAL ; } -regmap_update_bits (sai->regmap, -STM_SAI_CR1_REGX , -SAI_XCR1_OSR , cr1); +stm32_sai_sub_reg_up (sai, +STM_SAI_CR1_REGX , +SAI_XCR1_OSR , cr1); div =stm32_sai_get_clk_div (sai, sai_clk_rate, sai->mclk_rate);
@@ -1058,12 +1108,12 @@ static int stm32_sai_trigger(struct snd_case SNDRV_PCM_TRIGGER_PAUSE_RELEASE :dev_dbg (cpu_dai->dev,"Enable DMA and SAI\n" ); -regmap_update_bits (sai->regmap,STM_SAI_CR1_REGX , -SAI_XCR1_DMAEN ,SAI_XCR1_DMAEN ); +stm32_sai_sub_reg_up (sai,STM_SAI_CR1_REGX , +SAI_XCR1_DMAEN ,SAI_XCR1_DMAEN );/* Enable SAI */ - ret =regmap_update_bits (sai->regmap,STM_SAI_CR1_REGX , -SAI_XCR1_SAIEN ,SAI_XCR1_SAIEN ); + ret =stm32_sai_sub_reg_up (sai,STM_SAI_CR1_REGX , +SAI_XCR1_SAIEN ,SAI_XCR1_SAIEN );if (ret <0 )dev_err (cpu_dai->dev,"Failed to update CR1 register\n" );break ;
@@ -1072,16 +1122,16 @@ static int stm32_sai_trigger(struct snd_case SNDRV_PCM_TRIGGER_STOP :dev_dbg (cpu_dai->dev,"Disable DMA and SAI\n" ); -regmap_update_bits (sai->regmap,STM_SAI_IMR_REGX , -SAI_XIMR_MASK ,0 ); +stm32_sai_sub_reg_up (sai,STM_SAI_IMR_REGX , +SAI_XIMR_MASK ,0 ); -regmap_update_bits (sai->regmap,STM_SAI_CR1_REGX , -SAI_XCR1_SAIEN , - (unsigned int )~SAI_XCR1_SAIEN ); - - ret =regmap_update_bits (sai->regmap,STM_SAI_CR1_REGX , -SAI_XCR1_DMAEN , - (unsigned int )~SAI_XCR1_DMAEN ); +stm32_sai_sub_reg_up (sai,STM_SAI_CR1_REGX , +SAI_XCR1_SAIEN , + (unsigned int )~SAI_XCR1_SAIEN ); + + ret =stm32_sai_sub_reg_up (sai,STM_SAI_CR1_REGX , +SAI_XCR1_DMAEN , + (unsigned int )~SAI_XCR1_DMAEN );if (ret <0 )dev_err (cpu_dai->dev,"Failed to update CR1 register\n" );
@@ -1101,7 +1151,7 @@ static void stm32_sai_shutdown(struct snstruct stm32_sai_sub_data *sai =snd_soc_dai_get_drvdata (cpu_dai);unsigned long flags; -regmap_update_bits (sai->regmap,STM_SAI_IMR_REGX ,SAI_XIMR_MASK ,0 ); +stm32_sai_sub_reg_up (sai,STM_SAI_IMR_REGX ,SAI_XIMR_MASK ,0 );clk_disable_unprepare (sai->sai_ck);
@@ -1169,7 +1219,7 @@ static int stm32_sai_dai_probe(struct sn cr1_mask |=SAI_XCR1_SYNCEN_MASK ; cr1 |=SAI_XCR1_SYNCEN_SET (sai->sync); -return regmap_update_bits (sai->regmap,STM_SAI_CR1_REGX , cr1_mask, cr1); +return stm32_sai_sub_reg_up (sai,STM_SAI_CR1_REGX , cr1_mask, cr1); }static const struct snd_soc_dai_ops stm32_sai_pcm_dai_ops = {
@@ -1322,8 +1372,13 @@ static int stm32_sai_sub_parse_of(structif (STM_SAI_HAS_PDM (sai) &&STM_SAI_IS_SUB_A (sai)) sai->regmap_config = &stm32_sai_sub_regmap_config_h7; - sai->regmap =devm_regmap_init_mmio_clk (&pdev->dev,"sai_ck" , - base, sai->regmap_config); +/* +* Do not manage peripheral clock through regmap framework as this +* can lead to circular locking issue with sai master clock provider. +* Manage peripheral clock directly in driver instead. +*/ + sai->regmap =devm_regmap_init_mmio (&pdev->dev, base, + sai->regmap_config);if (IS_ERR (sai->regmap)) {dev_err (&pdev->dev,"Failed to initialize MMIO\n" );return PTR_ERR (sai->regmap);
@@ -1420,6 +1475,10 @@ static int stm32_sai_sub_parse_of(structreturn PTR_ERR (sai->sai_ck); } + ret =clk_prepare (sai->pdata->pclk); +if (ret <0 ) +return ret; +if (STM_SAI_IS_F4 (sai->pdata))return 0 ;
@@ -1501,22 +1560,48 @@ static int stm32_sai_sub_probe(struct plreturn 0 ; } +static int stm32_sai_sub_remove (struct platform_device *pdev) +{ +struct stm32_sai_sub_data *sai =dev_get_drvdata (&pdev->dev); + +clk_unprepare (sai->pdata->pclk); + +return 0 ; +} +#ifdef CONFIG_PM_SLEEP static int stm32_sai_sub_suspend (struct device *dev) {struct stm32_sai_sub_data *sai =dev_get_drvdata (dev); +int ret; + + ret =clk_enable (sai->pdata->pclk); +if (ret <0 ) +return ret;regcache_cache_only (sai->regmap, true);regcache_mark_dirty (sai->regmap); + +clk_disable (sai->pdata->pclk); +return 0 ; }static int stm32_sai_sub_resume (struct device *dev) {struct stm32_sai_sub_data *sai =dev_get_drvdata (dev); +int ret; + + ret =clk_enable (sai->pdata->pclk); +if (ret <0 ) +return ret;regcache_cache_only (sai->regmap, false); -return regcache_sync (sai->regmap); + ret =regcache_sync (sai->regmap); + +clk_disable (sai->pdata->pclk); + +return ret; }#endif /* CONFIG_PM_SLEEP */
@@ -1531,6 +1616,7 @@ static struct platform_driver stm32_sai_ .pm = &stm32_sai_sub_pm_ops, }, .probe = stm32_sai_sub_probe, + .remove = stm32_sai_sub_remove, };module_platform_driver (stm32_sai_sub_driver);
Greg Kroah-Hartman
maintainerPATCH 15/222 ASoC: stm32: dfsdm: fix 16 bits record
In reply to Greg Kroah-HartmanFrom: Olivier Moysan <[email protected]>
commit 8e55ea19125b65cffe42747359af99d545e85f2f upstream.
In stm32_afsdm_pcm_cb function, the transfer size is provided in bytes. However, samples are copied as 16 bits words from iio buffer. Divide by two the transfer size, to copy the right number of samples.
--- sound/soc/stm/stm32_adfsdm.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
sound/soc/stm/stm32_adfsdm.c +6 -6
@@ -153,13 +153,13 @@ static const struct snd_soc_component_dr .name = "stm32_dfsdm_audio", }; -static void memcpy_32to16 (void *dest,const void *src,size_t n) +static void stm32_memcpy_32to16 (void *dest,const void *src,size_t n) {unsigned int i =0 ;u16 *d = (u16 *)dest, *s = (u16 *)src; s++; -for (i = n; i >0 ; i--) { +for (i = n >>1 ; i >0 ; i--) { *d++ = *s++; s++; }
@@ -186,8 +186,8 @@ static int stm32_afsdm_pcm_cb(const voidif ((priv->pos + src_size) > buff_size) {if (format ==SNDRV_PCM_FORMAT_S16_LE ) -memcpy_32to16 (&pcm_buff[priv->pos], src_buff, - buff_size - priv->pos); +stm32_memcpy_32to16 (&pcm_buff[priv->pos], src_buff, + buff_size - priv->pos);else memcpy (&pcm_buff[priv->pos], src_buff, buff_size - priv->pos);
@@ -196,8 +196,8 @@ static int stm32_afsdm_pcm_cb(const void }if (format ==SNDRV_PCM_FORMAT_S16_LE ) -memcpy_32to16 (&pcm_buff[priv->pos], - &src_buff[src_size - cur_size], cur_size); +stm32_memcpy_32to16 (&pcm_buff[priv->pos], + &src_buff[src_size - cur_size], cur_size);else memcpy (&pcm_buff[priv->pos], &src_buff[src_size - cur_size], cur_size);
Greg Kroah-Hartman
maintainerPATCH 16/222 ASoC: msm8916-wcd-analog: Fix selected events for MIC BIAS External1
In reply to Greg Kroah-HartmanFrom: Stephan Gerhold <[email protected]>
commit e0beec88397b163c7c4ea6fcfb67e8e07a2671dc upstream.
MIC BIAS External1 sets pm8916_wcd_analog_enable_micbias_ext1() as event handler, which ends up in pm8916_wcd_analog_enable_micbias_ext().
But pm8916_wcd_analog_enable_micbias_ext() only handles the POST_PMU event, which is not specified in the event flags for MIC BIAS External1. This means that the code in the event handler is never actually run.
Set SND_SOC_DAPM_POST_PMU as the only event for the handler to fix this.
--- sound/soc/codecs/msm8916-wcd-analog.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
sound/soc/codecs/msm8916-wcd-analog.c +2 -2
@@ -888,10 +888,10 @@ static const struct snd_soc_dapm_widgetSND_SOC_DAPM_SUPPLY ("MIC BIAS External1" ,CDC_A_MICB_1_EN ,7 ,0 , pm8916_wcd_analog_enable_micbias_ext1, -SND_SOC_DAPM_PRE_PMU |SND_SOC_DAPM_POST_PMD ), +SND_SOC_DAPM_POST_PMU ),SND_SOC_DAPM_SUPPLY ("MIC BIAS External2" ,CDC_A_MICB_2_EN ,7 ,0 , pm8916_wcd_analog_enable_micbias_ext2, -SND_SOC_DAPM_POST_PMU |SND_SOC_DAPM_POST_PMD ), +SND_SOC_DAPM_POST_PMU ), SND_SOC_DAPM_ADC_E("ADC1", NULL, CDC_A_TX_1_EN, 7, 0, pm8916_wcd_analog_enable_adc,
Greg Kroah-Hartman
maintainerPATCH 17/222 ASoC: msm8916-wcd-analog: Fix MIC BIAS Internal1
In reply to Greg Kroah-HartmanFrom: Stephan Gerhold <[email protected]>
commit 057efcf9faea4769cf1020677d93d040db9b23f3 upstream.
MIC BIAS Internal1 is broken at the moment because we always enable the internal rbias resistor to the TX2 line (connected to the headset microphone), rather than enabling the resistor connected to TX1.
Move the RBIAS code to pm8916_wcd_analog_enable_micbias_int1/2() to fix this.
--- sound/soc/codecs/msm8916-wcd-analog.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)
sound/soc/codecs/msm8916-wcd-analog.c +13 -3
@@ -391,9 +391,6 @@ static int pm8916_wcd_analog_enable_micbswitch (event) {case SND_SOC_DAPM_PRE_PMU : -snd_soc_component_update_bits (component,CDC_A_MICB_1_INT_RBIAS , -MICB_1_INT_TX2_INT_RBIAS_EN_MASK , -MICB_1_INT_TX2_INT_RBIAS_EN_ENABLE );snd_soc_component_update_bits (component, reg,MICB_1_EN_PULL_DOWN_EN_MASK ,0 ); snd_soc_component_update_bits(component, CDC_A_MICB_1_EN, MICB_1_EN_OPA_STG2_TAIL_CURR_MASK,
@@ -443,6 +440,14 @@ static int pm8916_wcd_analog_enable_micbstruct snd_soc_component *component =snd_soc_dapm_to_component (w->dapm);struct pm8916_wcd_analog_priv *wcd =snd_soc_component_get_drvdata (component); +switch (event) { +case SND_SOC_DAPM_PRE_PMU : +snd_soc_component_update_bits (component,CDC_A_MICB_1_INT_RBIAS , +MICB_1_INT_TX1_INT_RBIAS_EN_MASK , +MICB_1_INT_TX1_INT_RBIAS_EN_ENABLE ); +break ; + } +return pm8916_wcd_analog_enable_micbias_int (component, event, w->reg, wcd->micbias1_cap_mode); }
@@ -553,6 +558,11 @@ static int pm8916_wcd_analog_enable_micbstruct pm8916_wcd_analog_priv *wcd =snd_soc_component_get_drvdata (component);switch (event) { +case SND_SOC_DAPM_PRE_PMU : +snd_soc_component_update_bits (component,CDC_A_MICB_1_INT_RBIAS , +MICB_1_INT_TX2_INT_RBIAS_EN_MASK , +MICB_1_INT_TX2_INT_RBIAS_EN_ENABLE ); +break ;case SND_SOC_DAPM_POST_PMU :pm8916_mbhc_configure_bias (wcd, true);break ;
Greg Kroah-Hartman
maintainerPATCH 18/222 ARM: OMAP2+: Fix ti_sysc_find_one_clockdomain to check for to_clk_hw_omap
In reply to Greg Kroah-HartmanFrom: Tony Lindgren <[email protected]>
commit 90bdfa0b05e3cc809a7c1aa3b1f162b46ea1b330 upstream.
We must bail out early if the clock is not hw_omap. Otherwise we will try to access invalid address with hwclk->clkdm_name:
Unable to handle kernel paging request at virtual address ffffffff Internal error: Oops: 27 [#1] ARM
...
(strcmp) from [<c011b348>] (clkdm_lookup+0x40/0x60)
[<c011b348>] (clkdm_lookup) from [<c011cb84>] (ti_sysc_clkdm_init+0x5c/0x64) [<c011cb84>] (ti_sysc_clkdm_init) from [<c03680a8>] (sysc_probe+0x948/0x117c) [<c03680a8>] (sysc_probe) from [<c03d0af4>] (platform_drv_probe+0x48/0x98)
...
--- arch/arm/mach-omap2/pdata-quirks.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
arch/arm/mach-omap2/pdata-quirks.c +5 -1
@@ -368,10 +368,14 @@ static void __init dra7x_evm_mmc_quirk(vstatic struct clockdomain *ti_sysc_find_one_clockdomain (struct clk *clk) { +struct clk_hw *hw =__clk_get_hw (clk);struct clockdomain *clkdm =NULL ;struct clk_hw_omap *hwclk; - hwclk =to_clk_hw_omap (__clk_get_hw (clk)); + hwclk =to_clk_hw_omap (hw); +if (!omap2_clk_is_hw_omap (hw)) +return NULL ; +if (hwclk && hwclk->clkdm_name) clkdm =clkdm_lookup (hwclk->clkdm_name);
Greg Kroah-Hartman
maintainerPATCH 19/222 ARM: dts: imx7ulp: fix reg of cpu node
In reply to Greg Kroah-HartmanFrom: Peng Fan <[email protected]>
commit b8ab62ff7199fac8ce27fa4a149929034fabe7f8 upstream.
According to arm cpus binding doc,
"
On 32-bit ARM v7 or later systems this property is
required and matches the CPU MPIDR[23:0] register bits.
Bits [23:0] in the reg cell must be set to bits [23:0] in MPIDR.
All other bits in the reg cell must be set to 0.
"
In i.MX7ULP, the MPIDR[23:0] is 0xf00, not 0, so fix it. Otherwise there will be warning:
"DT missing boot CPU MPIDR[23:0], fall back to default cpu_logical_map"
--- arch/arm/boot/dts/imx7ulp.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm/boot/dts/imx7ulp.dtsi +2 -2
@@ -37,10 +37,10 @@ #address-cells = <1>; #size-cells = <0>; - cpu0: cpu@0 { + cpu0: cpu@f00 { compatible = "arm,cortex-a7"; device_type = "cpu"; - reg = <0>; + reg = <0xf00>; }; };
Greg Kroah-Hartman
maintainerPATCH 20/222 ARM: dts: imx6q-dhcom: Fix SGTL5000 VDDIO regulator connection
In reply to Greg Kroah-HartmanFrom: Marek Vasut <[email protected]>
commit fe6a6689d1815b63528796886853890d8ee7f021 upstream.
The SGTL5000 VDDIO is connected to the PMIC SW2 output, not to a fixed 3V3 rail. Describe this correctly in the DT.
--- arch/arm/boot/dts/imx6q-dhcom-pdk2.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/boot/dts/imx6q-dhcom-pdk2.dts +1 -1
@@ -55,7 +55,7 @@ #sound-dai-cells = <0>; clocks = <&clk_ext_audio_codec>; VDDA-supply = <®_3p3v>; - VDDIO-supply = <®_3p3v>; + VDDIO-supply = <&sw2_reg>; }; };
Greg Kroah-Hartman
maintainerPATCH 21/222 ASoC: Intel: bytcht_es8316: Fix Irbis NB41 netbook quirk
In reply to Greg Kroah-HartmanFrom: Hans de Goede <[email protected]>
commit 869bced7a055665e3ddb1ba671a441ce6f997bf1 upstream.
When a quirk for the Irbis NB41 netbook was added, to override the defaults for this device, I forgot to add/keep the BYT_CHT_ES8316_SSP0 part of the defaults, completely breaking audio on this netbook.
This commit adds the BYT_CHT_ES8316_SSP0 flag to the Irbis NB41 netbook quirk, making audio work again.
--- sound/soc/intel/boards/bytcht_es8316.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
sound/soc/intel/boards/bytcht_es8316.c +2 -1
@@ -442,7 +442,8 @@ static const struct dmi_system_id byt_chDMI_MATCH (DMI_SYS_VENDOR ,"IRBIS" ), DMI_MATCH(DMI_PRODUCT_NAME, "NB41"), }, - .driver_data = (void *)(BYT_CHT_ES8316_INTMIC_IN2_MAP + .driver_data = (void *)(BYT_CHT_ES8316_SSP0 + |BYT_CHT_ES8316_INTMIC_IN2_MAP | BYT_CHT_ES8316_JD_INVERTED), }, { /* Teclast X98 Plus II */
Greg Kroah-Hartman
maintainerPATCH 22/222 ALSA: dice: fix fallback from protocol extension into limited functionality
In reply to Greg Kroah-HartmanFrom: Takashi Sakamoto <[email protected]>
commit 3e2dc6bdb56893bc28257e482e1dbe5d39f313df upstream.
At failure of attempt to detect protocol extension, ALSA dice driver should be fallback to limited functionality. However it's not.
This commit fixes it.
--- sound/firewire/dice/dice-extension.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
sound/firewire/dice/dice-extension.c +4 -1
@@ -159,8 +159,11 @@ int snd_dice_detect_extension_formats(stint j;for (j = i +1 ; j <9 ; ++j) { -if (pointers[i *2 ] == pointers[j *2 ]) +if (pointers[i *2 ] == pointers[j *2 ]) { +// Fallback to limited functionality. + err = -ENXIO ; goto end; + } } }
Greg Kroah-Hartman
maintainerPATCH 23/222 ALSA: seq: Fix racy access for queue timer in proc read
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
commit 60adcfde92fa40fcb2dbf7cc52f9b096e0cd109a upstream.
snd_seq_info_timer_read() reads the information of the timer assigned for each queue, but it's done in a racy way which may lead to UAF as spotted by syzkaller.
This patch applies the missing q->timer_mutex lock while accessing the timer object as well as a slight code change to adapt the standard coding style.
--- sound/core/seq/seq_timer.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)
sound/core/seq/seq_timer.c +9 -5
@@ -465,15 +465,19 @@ void snd_seq_info_timer_read(struct snd_ q =queueptr (idx);if (q ==NULL )continue ; -if ((tmr = q->timer) ==NULL || - (ti = tmr->timeri) ==NULL ) { -queuefree (q); -continue ; - } +mutex_lock (&q->timer_mutex); + tmr = q->timer; +if (!tmr) + goto unlock; + ti = tmr->timeri; +if (!ti) + goto unlock;snd_iprintf (buffer,"Timer for queue %i : %s\n" , q->queue, ti->timer->name); resolution =snd_timer_resolution (ti) * tmr->ticks;snd_iprintf (buffer," Period time : %lu.%09lu\n" , resolution /1000000000 , resolution %1000000000 );snd_iprintf (buffer," Skew : %u / %u\n" , tmr->skew, tmr->skew_base); +unlock: +mutex_unlock (&q->timer_mutex);queuefree (q); } }
Greg Kroah-Hartman
maintainerPATCH 24/222 ALSA: firewire-tascam: fix corruption due to spin lock without restoration in SoftIRQ context
In reply to Greg Kroah-HartmanFrom: Takashi Sakamoto <[email protected]>
commit 747d1f076de5a60770011f6e512de43298ec64cb upstream.
ALSA firewire-tascam driver can bring corruption due to spin lock without restoration of IRQ flag in SoftIRQ context. This commit fixes the bug.
--- sound/firewire/tascam/amdtp-tascam.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
sound/firewire/tascam/amdtp-tascam.c +3 -2
@@ -157,14 +157,15 @@ static void read_status_messages(structif ((before ^ after) & mask) {struct snd_firewire_tascam_change *entry = &tscm->queue[tscm->push_pos]; +unsigned long flag; -spin_lock_irq (&tscm->lock); +spin_lock_irqsave (&tscm->lock, flag); entry->index = index; entry->before = before; entry->after = after;if (++tscm->push_pos >=SND_TSCM_QUEUE_COUNT ) tscm->push_pos =0 ; -spin_unlock_irq (&tscm->lock); +spin_unlock_irqrestore (&tscm->lock, flag);wake_up (&tscm->hwdep_wait); }
Greg Kroah-Hartman
maintainerPATCH 25/222 ALSA: usb-audio: fix sync-ep altsetting sanity check
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 5d1b71226dc4d44b4b65766fa9d74492f9d4587b upstream.
The altsetting sanity check in set_sync_ep_implicit_fb_quirk() was checking for there to be at least one altsetting but then went on to access the second one, which may not exist.
This could lead to random slab data being used to initialise the sync endpoint in snd_usb_add_endpoint().
--- sound/usb/pcm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/usb/pcm.c +1 -1
@@ -370,7 +370,7 @@ static int set_sync_ep_implicit_fb_quirk add_sync_ep_from_ifnum: iface =usb_ifnum_to_if (dev, ifnum); -if (!iface || iface->num_altsetting ==0 ) +if (!iface || iface->num_altsetting <2 )return -EINVAL ; alts = &iface->altsetting[1 ];
Greg Kroah-Hartman
maintainerPATCH 26/222 arm64: dts: allwinner: a64: olinuxino: Fix SDIO supply regulator
In reply to Greg Kroah-HartmanFrom: Stefan Mavrodiev <[email protected]>
commit 3d615c2fc2d111b51d2e20516b920138d4ae29a2 upstream.
A64-OLinuXino uses DCDC1 (VCC-IO) for MMC1 supply. In commit 916b68cfe4b5 ("arm64: dts: a64-olinuxino: Enable RTL8723BS WiFi") ALDO2 is set, which is VCC-PL. Since DCDC1 is always present, the boards are working without a problem.
This patch sets the correct regulator.
--- arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts +1 -1
@@ -140,7 +140,7 @@ &mmc1 { pinctrl-names = "default"; pinctrl-0 = <&mmc1_pins>; - vmmc-supply = <®_aldo2>; + vmmc-supply = <®_dcdc1>; vqmmc-supply = <®_dldo4>; mmc-pwrseq = <&wifi_pwrseq>; bus-width = <4>;
Greg Kroah-Hartman
maintainerPATCH 27/222 arm64: dts: allwinner: a64: olinuxino: Fix eMMC supply regulator
In reply to Greg Kroah-HartmanFrom: Stefan Mavrodiev <[email protected]>
commit 8467ebbf708e5c4574b4eb5f663558fc724945ac upstream.
A64-OLinuXino-eMMC uses 1.8V for eMMC supply. This is done via a triple jumper, which sets VCC-PL to either 1.8V or 3.3V. This setting is different for boards with and without eMMC.
This is not a big issue for DDR52 mode, however the eMMC will not work in HS200/HS400, since these modes explicitly requires 1.8V.
--- arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino-emmc.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino-emmc.dts +1 -1
@@ -15,7 +15,7 @@ pinctrl-names = "default"; pinctrl-0 = <&mmc2_pins>; vmmc-supply = <®_dcdc1>; - vqmmc-supply = <®_dcdc1>; + vqmmc-supply = <®_eldo1>; bus-width = <8>; non-removable; cap-mmc-hw-reset;
Greg Kroah-Hartman
maintainerPATCH 28/222 arm64: dts: agilex/stratix10: fix pmu interrupt numbers
In reply to Greg Kroah-HartmanFrom: Dinh Nguyen <[email protected]>
commit 210de0e996aee8e360ccc9e173fe7f0a7ed2f695 upstream.
Fix up the correct interrupt numbers for the PMU unit on Agilex and Stratix10.
--- arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi | 8 ++++---- arch/arm64/boot/dts/intel/socfpga_agilex.dtsi | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-)
arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi +4 -4
@@ -61,10 +61,10 @@ pmu { compatible = "arm,armv8-pmuv3"; - interrupts = <0 120 8>, - <0 121 8>, - <0 122 8>, - <0 123 8>; + interrupts = <0 170 4>, + <0 171 4>, + <0 172 4>, + <0 173 4>; interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>,
arch/arm64/boot/dts/intel/socfpga_agilex.dtsi +4 -4
@@ -47,10 +47,10 @@ pmu { compatible = "arm,armv8-pmuv3"; - interrupts = <0 120 8>, - <0 121 8>, - <0 122 8>, - <0 123 8>; + interrupts = <0 170 4>, + <0 171 4>, + <0 172 4>, + <0 173 4>; interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>,
Greg Kroah-Hartman
maintainerPATCH 29/222 Fix built-in early-load Intel microcode alignment
In reply to Greg Kroah-HartmanFrom: Jari Ruusu <[email protected]>
commit f5ae2ea6347a308cfe91f53b53682ce635497d0d upstream.
Intel Software Developer's Manual, volume 3, chapter 9.11.6 says:
"Note that the microcode update must be aligned on a 16-byte boundary
and the size of the microcode update must be 1-KByte granular"
When early-load Intel microcode is loaded from initramfs, userspace tool 'iucode_tool' has already 16-byte aligned those microcode bits in that initramfs image. Image that was created something like this:
iucode_tool --write-earlyfw=FOO.cpio microcode-files...
However, when early-load Intel microcode is loaded from built-in firmware BLOB using CONFIG_EXTRA_FIRMWARE= kernel config option, that 16-byte alignment is not guaranteed.
Fix this by forcing all built-in firmware BLOBs to 16-byte alignment.
[ If we end up having other firmware with much bigger alignment
requirements, we might need to introduce some method for the firmware to specify it, this is the minimal "just increase the alignment a bit
to account for this one special case" patch - Linus ]
--- drivers/base/firmware_loader/builtin/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/base/firmware_loader/builtin/Makefile +1 -1
@@ -17,7 +17,7 @@ PROGBITS = $(if $(CONFIG_ARM),%,@)progb filechk_fwbin = \ echo "/* Generated by $(src)/Makefile */" ;\ echo " .section .rodata" ;\ - echo " .p2align $(ASM_ALIGN)" ;\ + echo " .p2align 4" ;\ echo "_fw_$(FWSTR)_bin:" ;\ echo " .incbin \"$(fwdir)/$(FWNAME)\"" ;\ echo "_fw_end:" ;\
Greg Kroah-Hartman
maintainerPATCH 30/222 clk: sunxi-ng: r40: Allow setting parent rate for external clock outputs
In reply to Greg Kroah-HartmanFrom: Chen-Yu Tsai <[email protected]>
commit c7b305267eb77fe47498676e9337324c9653494c upstream.
One of the uses of the external clock outputs is to provide a stable 32768 Hz clock signal to WiFi and Bluetooth chips. On the R40, the RTC has an internal RC oscillator that is muxed with the external crystal.
Allow setting the parent rate for the external clock outputs so that requests for 32768 Hz get passed to the RTC's clock driver to mux in the external crystal if it isn't already muxed correctly.
--- drivers/clk/sunxi-ng/ccu-sun8i-r40.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/clk/sunxi-ng/ccu-sun8i-r40.c +4 -2
@@ -761,7 +761,8 @@ static struct ccu_mp outa_clk = { .reg = 0x1f0, .features = CCU_FEATURE_FIXED_PREDIV, .hw.init = CLK_HW_INIT_PARENTS("outa", out_parents, - &ccu_mp_ops, 0), + &ccu_mp_ops, + CLK_SET_RATE_PARENT), } };
@@ -779,7 +780,8 @@ static struct ccu_mp outb_clk = { .reg = 0x1f4, .features = CCU_FEATURE_FIXED_PREDIV, .hw.init = CLK_HW_INIT_PARENTS("outb", out_parents, - &ccu_mp_ops, 0), + &ccu_mp_ops, + CLK_SET_RATE_PARENT), } };
Greg Kroah-Hartman
maintainerPATCH 31/222 block: fix an integer overflow in logical block size
In reply to Greg Kroah-HartmanFrom: Mikulas Patocka <[email protected]>
commit ad6bf88a6c19a39fb3b0045d78ea880325dfcf15 upstream.
Logical block size has type unsigned short. That means that it can be at most 32768. However, there are architectures that can run with 64k pages (for example arm64) and on these architectures, it may be possible to create block devices with 64k block size.
For exmaple (run this on an architecture with 64k pages):
Mount will fail with this error because it tries to read the superblock using 2-sector access:
device-mapper: writecache: I/O is not aligned, sector 2, size 1024, block size 65536 EXT4-fs (dm-0): unable to read superblock
This patch changes the logical block size from unsigned short to unsigned int to avoid the overflow.
--- block/blk-settings.c | 2 +- drivers/md/dm-snap-persistent.c | 2 +- drivers/md/raid0.c | 2 +- include/linux/blkdev.h | 8 ++++---- 4 files changed, 7 insertions(+), 7 deletions(-)
block/blk-settings.c +1 -1
@@ -328,7 +328,7 @@ EXPORT_SYMBOL(blk_queue_max_segment_size* storage device can address. The default of 512 covers most * hardware. **/ -void blk_queue_logical_block_size (struct request_queue *q,unsigned short size) +void blk_queue_logical_block_size (struct request_queue *q,unsigned int size) { q->limits.logical_block_size = size;
drivers/md/dm-snap-persistent.c +1 -1
@@ -17,7 +17,7 @@#include <linux/dm-bufio.h> #define DM_MSG_PREFIX "persistent snapshot" -#define DM_CHUNK_SIZE_DEFAULT_SECTORS 32/* 16KB */ +#define DM_CHUNK_SIZE_DEFAULT_SECTORS 32U/* 16KB */ #define DM_PREFETCH_CHUNKS 12
drivers/md/raid0.c +1 -1
@@ -87,7 +87,7 @@ static int create_strip_zones(struct mddchar b[BDEVNAME_SIZE ];char b2[BDEVNAME_SIZE ];struct r0conf *conf =kzalloc (sizeof (*conf),GFP_KERNEL ); -unsigned short blksize =512 ; +unsigned blksize =512 ; *private_conf =ERR_PTR (-ENOMEM );if (!conf)
include/linux/blkdev.h +4 -4
@@ -328,6 +328,7 @@ struct queue_limits {unsigned int max_sectors;unsigned int max_segment_size;unsigned int physical_block_size; +unsigned int logical_block_size;unsigned int alignment_offset;unsigned int io_min;unsigned int io_opt;
@@ -338,7 +339,6 @@ struct queue_limits {unsigned int discard_granularity;unsigned int discard_alignment; -unsigned short logical_block_size;unsigned short max_segments;unsigned short max_integrity_segments;unsigned short max_discard_segments;
@@ -1080,7 +1080,7 @@ extern void blk_queue_max_write_same_sec unsigned int max_write_same_sectors);extern void blk_queue_max_write_zeroes_sectors (struct request_queue *q,unsigned int max_write_same_sectors); -extern void blk_queue_logical_block_size (struct request_queue *,unsigned short ); +extern void blk_queue_logical_block_size (struct request_queue *,unsigned int );extern void blk_queue_physical_block_size (struct request_queue *,unsigned int );extern void blk_queue_alignment_offset (struct request_queue *q,unsigned int alignment);
@@ -1294,7 +1294,7 @@ static inline unsigned int queue_max_segreturn q->limits.max_segment_size; } -static inline unsigned short queue_logical_block_size (const struct request_queue *q) +static inline unsigned queue_logical_block_size (const struct request_queue *q) {int retval =512 ;
@@ -1304,7 +1304,7 @@ static inline unsigned short queue_logicreturn retval; } -static inline unsigned short bdev_logical_block_size (struct block_device *bdev) +static inline unsigned int bdev_logical_block_size (struct block_device *bdev) {return queue_logical_block_size (bdev_get_queue (bdev)); }
Greg Kroah-Hartman
maintainerPATCH 32/222 fuse: fix fuse_send_readpages() in the syncronous read case
In reply to Greg Kroah-HartmanFrom: Miklos Szeredi <[email protected]>
commit 7df1e988c723a066754090b22d047c3225342152 upstream.
Buffered read in fuse normally goes via:
-> generic_file_buffered_read()
-> fuse_readpages()
-> fuse_send_readpages()
->fuse_simple_request() [called since v5.4]In the case of a read request, fuse_simple_request() will return a non-negative bytecount on success or a negative error value. A positive bytecount was taken to be an error and the PG_error flag set on the page. This resulted in generic_file_buffered_read() falling back to ->readpage(), which would repeat the read request and succeed. Because of the repeated read succeeding the bug was not detected with regression tests or other use cases.
The FTP module in GVFS however fails the second read due to the non-seekable nature of FTP downloads.
Fix by checking and ignoring positive return value from fuse_simple_request().
--- fs/fuse/file.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
fs/fuse/file.c +3 -1
@@ -882,6 +882,7 @@ static void fuse_send_readpages(struct fstruct fuse_args_pages *ap = &ia->ap;loff_t pos =page_offset (ap->pages[0 ]);size_t count = ap->num_pages <<PAGE_SHIFT ; +ssize_t res;int err; ap->args.out_pages = true;
@@ -896,7 +897,8 @@ static void fuse_send_readpages(struct fif (!err)return ; }else { - err =fuse_simple_request (fc, &ap->args); + res =fuse_simple_request (fc, &ap->args); + err = res <0 ? res :0 ; }fuse_readpages_end (fc, &ap->args, err); }
Greg Kroah-Hartman
maintainerPATCH 33/222 io_uring: only allow submit from owning task
In reply to Greg Kroah-HartmanFrom: Jens Axboe <[email protected]>
commit 44d282796f81eb1debc1d7cb53245b4cb3214cb5 upstream.
If the credentials or the mm doesn't match, don't allow the task to submit anything on behalf of this ring. The task that owns the ring can pass the file descriptor to another task, but we don't want to allow that task to submit an SQE that then assumes the ring mm and creds if it needs to go async.
--- fs/io_uring.c | 6 ++++++ 1 file changed, 6 insertions(+)
fs/io_uring.c +6 -0
@@ -3716,6 +3716,12 @@ SYSCALL_DEFINE6(io_uring_enter, unsignedwake_up (&ctx->sqo_wait); submitted = to_submit; }else if (to_submit) { +if (current->mm != ctx->sqo_mm || +current_cred () != ctx->creds) { + ret = -EPERM ; + goto out; + } + to_submit =min (to_submit, ctx->sq_entries);mutex_lock (&ctx->uring_lock);
Re: [PATCH 5.4 033/222] io_uring: only allow submit from owning task
Am 22.01.20 um 10:26 schrieb Greg Kroah-Hartman:
Quoted 23 lines
From: Jens Axboe <[email protected]>
commit
44d282796f81eb1debc1d7cb53245b4cb3214cb5upstream.If the credentials or the mm doesn't match, don't allow the task to submit anything on behalf of this ring. The task that owns the ring can pass the file descriptor to another task, but we don't want to allow that task to submit an SQE that then assumes the ring mm and creds if it needs to go async.
Suggested-by Stefan Metzmacher <[email protected]>Signed-off-by Jens Axboe <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>--- fs/io_uring.c | 6 ++++++ 1 file changed, 6 insertions(+)
fs/io_uring.c SYSCALL_DEFINE6(io_uring_enter, unsigned · line 3724
Quoted 9 lines
fs/io_uring.c +6
-0@@ -3716,6 +3716,12 @@ SYSCALL_DEFINE6(io_uring_enter, unsignedwake_up (&ctx->sqo_wait); submitted = to_submit; }else if (to_submit) { +if (current->mm != ctx->sqo_mm || +current_cred () != ctx->creds) { + ret = -EPERM ; + goto out; + } +
I thought about this a bit more.
I'm not sure if this is actually to restrictive,
because it means applications like Samba won't
be able to use io-uring at all.
As even if current_cred() and ctx->creds describe the same set of uid,gids the != won't ever match again and makes the whole ring unuseable.
I'm not sure about what the best short term solution could be...
1. May just doing the check for path based operations? and fail individual requests with EPERM.
2. Or force REQ_F_FORCE_ASYNC for path based operations, so that they're always executed from within the workqueue with were ctx->creds is active.
3. Or (as proposed earlier) do the override_creds/revert_creds dance (and similar for mm) if needed.
To summaries the problem again:
For path based operations like:
- IORING_OP_CONNECT (maybe also - IORING_OP_ACCEPT???)
- IORING_OP_SEND*, IORING_OP_RECV* on DGRAM sockets
- IORING_OP_OPENAT, IORING_OP_STATX, IORING_OP_OPENAT2 it's important under which current_cred they are called.
Are IORING_OP_MADVISE, IORING_OP_FADVISE and IORING_OP_FALLOCATE are only bound to the credentials of the passed fd they operate on?
The current assumption is that the io_uring_setup() syscall captures the current_cred() to ctx->cred and all operations on the ring are executed under the context of ctx->cred.
Therefore all helper threads do the override_creds/revert_creds dance.
But the possible non-blocking line execution of operations in the io_uring_enter() syscall doesn't do the override_creds/revert_creds dance and execute the operations under current_cred().
This means it's random depending on filled cached under what credentials an operation is executed.
In order to prevent security problems the current patch is enough, but as outlined above it will make io-uring complete unuseable for applications using any syscall that changes current_cred().
Change 1. would be a little bit better, but still not really useful.
I'd actually prefer solution 3. as it's still possible to make use of non-blocking operations, while the security is the same as solution 2.
metze
Re: [PATCH 5.4 033/222] io_uring: only allow submit from owning task
Am 24.01.20 um 11:38 schrieb Stefan Metzmacher:
Quoted 36 lines
Am 22.01.20 um 10:26 schrieb Greg Kroah-Hartman:
Quoted 23 lines
From: Jens Axboe <[email protected]>
commit
44d282796f81eb1debc1d7cb53245b4cb3214cb5upstream.If the credentials or the mm doesn't match, don't allow the task to submit anything on behalf of this ring. The task that owns the ring can pass the file descriptor to another task, but we don't want to allow that task to submit an SQE that then assumes the ring mm and creds if it needs to go async.
Suggested-by Stefan Metzmacher <[email protected]>Signed-off-by Jens Axboe <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>--- fs/io_uring.c | 6 ++++++ 1 file changed, 6 insertions(+)fs/io_uring.c SYSCALL_DEFINE6(io_uring_enter, unsigned · line 3724
Quoted 9 lines
fs/io_uring.c +6
-0@@ -3716,6 +3716,12 @@ SYSCALL_DEFINE6(io_uring_enter, unsignedwake_up (&ctx->sqo_wait); submitted = to_submit; }else if (to_submit) { +if (current->mm != ctx->sqo_mm || +current_cred () != ctx->creds) { + ret = -EPERM ; + goto out; + } +I thought about this a bit more.
Quoted 3 lines
I'm not sure if this is actually to restrictive,
because it means applications like Samba won't
be able to use io-uring at all.
Even for simple operations like IORING_OP_READ*, IORING_OP_WRITE*, IORING_OP_FSYNC and IORING_OP_SYNC_FILE_RANGE, which only operate on the given fd.
metze
Jens Axboe
maintainerRe: [PATCH 5.4 033/222] io_uring: only allow submit from owning task
In reply to Stefan MetzmacherQuoted 64 lines · Stefan Metzmacher
Am 22.01.20 um 10:26 schrieb Greg Kroah-Hartman:
Quoted 23 lines
From: Jens Axboe <[email protected]>
commit
44d282796f81eb1debc1d7cb53245b4cb3214cb5upstream.If the credentials or the mm doesn't match, don't allow the task to submit anything on behalf of this ring. The task that owns the ring can pass the file descriptor to another task, but we don't want to allow that task to submit an SQE that then assumes the ring mm and creds if it needs to go async.
Suggested-by Stefan Metzmacher <[email protected]>Signed-off-by Jens Axboe <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>--- fs/io_uring.c | 6 ++++++ 1 file changed, 6 insertions(+)fs/io_uring.c SYSCALL_DEFINE6(io_uring_enter, unsigned · line 3724
Quoted 9 lines
fs/io_uring.c +6
-0@@ -3716,6 +3716,12 @@ SYSCALL_DEFINE6(io_uring_enter, unsignedwake_up (&ctx->sqo_wait); submitted = to_submit; }else if (to_submit) { +if (current->mm != ctx->sqo_mm || +current_cred () != ctx->creds) { + ret = -EPERM ; + goto out; + } +I thought about this a bit more.
I'm not sure if this is actually to restrictive,
because it means applications like Samba won't
be able to use io-uring at all.As even if
current_cred()andctx->credsdescribe the same set of uid,gids the != won't ever match again and makes the whole ring unuseable.I'm not sure about what the best short term solution could be...
1. May just doing the check for path based operations? and fail individual requests with EPERM.
2. Or force
REQ_F_FORCE_ASYNCfor path based operations, so that they're always executed from within the workqueue with werectx->credsis active.3. Or (as proposed earlier) do the override_creds/revert_creds dance (and similar for mm) if needed.
To summaries the problem again:
For path based operations like:
-IORING_OP_CONNECT(maybe also -IORING_OP_ACCEPT???)
- IORING_OP_SEND*, IORING_OP_RECV* on DGRAM sockets
-IORING_OP_OPENAT,IORING_OP_STATX,IORING_OP_OPENAT2it's important under whichcurrent_credthey are called.
Quoted 7 lines
Are
IORING_OP_MADVISE,IORING_OP_FADVISEandIORING_OP_FALLOCATEare only bound to the credentials of the passed fd they operate on?The current assumption is that the
io_uring_setup()syscall captures thecurrent_cred()toctx->credand all operations on the ring are executed under the context ofctx->cred.
Therefore all helper threads do the override_creds/revert_creds dance.
But it doesn't - we're expecting them to match, and with this change, we assert that it's the case or return -EPERM.
Quoted 11 lines
But the possible non-blocking line execution of operations in the
io_uring_enter()syscall doesn't do the override_creds/revert_creds dance and execute the operations undercurrent_cred().This means it's random depending on filled cached under what credentials an operation is executed.
In order to prevent security problems the current patch is enough, but as outlined above it will make io-uring complete unuseable for applications using any syscall that changes
current_cred().
Quoted 5 lines
Change 1. would be a little bit better, but still not really useful.
I'd actually prefer solution 3. as it's still possible to make use of non-blocking operations, while the security is the same as solution 2.
For your situation, we need to extend it anyway, and provide a way to swap between personalities. So yeah it won't work as-is for your use case, but we can work on making that the case.
Signature · 1 line
Jens Axboe
Re: [PATCH 5.4 033/222] io_uring: only allow submit from owning task
Am 24.01.20 um 17:58 schrieb Jens Axboe:
Quoted 89 lines · Stefan Metzmacher
Quoted 64 lines
Am 22.01.20 um 10:26 schrieb Greg Kroah-Hartman:
Quoted 23 lines
From: Jens Axboe <[email protected]>
commit
44d282796f81eb1debc1d7cb53245b4cb3214cb5upstream.If the credentials or the mm doesn't match, don't allow the task to submit anything on behalf of this ring. The task that owns the ring can pass the file descriptor to another task, but we don't want to allow that task to submit an SQE that then assumes the ring mm and creds if it needs to go async.
Suggested-by Stefan Metzmacher <[email protected]>Signed-off-by Jens Axboe <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>--- fs/io_uring.c | 6 ++++++ 1 file changed, 6 insertions(+)fs/io_uring.c SYSCALL_DEFINE6(io_uring_enter, unsigned · line 3724
Quoted 9 lines
fs/io_uring.c +6
-0@@ -3716,6 +3716,12 @@ SYSCALL_DEFINE6(io_uring_enter, unsignedwake_up (&ctx->sqo_wait); submitted = to_submit; }else if (to_submit) { +if (current->mm != ctx->sqo_mm || +current_cred () != ctx->creds) { + ret = -EPERM ; + goto out; + } +I thought about this a bit more.
I'm not sure if this is actually to restrictive,
because it means applications like Samba won't
be able to use io-uring at all.As even if
current_cred()andctx->credsdescribe the same set of uid,gids the != won't ever match again and makes the whole ring unuseable.I'm not sure about what the best short term solution could be...
1. May just doing the check for path based operations? and fail individual requests with EPERM.
2. Or force
REQ_F_FORCE_ASYNCfor path based operations, so that they're always executed from within the workqueue with werectx->credsis active.3. Or (as proposed earlier) do the override_creds/revert_creds dance (and similar for mm) if needed.
To summaries the problem again:
For path based operations like:
-IORING_OP_CONNECT(maybe also -IORING_OP_ACCEPT???)
- IORING_OP_SEND*, IORING_OP_RECV* on DGRAM sockets
-IORING_OP_OPENAT,IORING_OP_STATX,IORING_OP_OPENAT2it's important under whichcurrent_credthey are called.Quoted 7 lines
Are
IORING_OP_MADVISE,IORING_OP_FADVISEandIORING_OP_FALLOCATEare only bound to the credentials of the passed fd they operate on?The current assumption is that the
io_uring_setup()syscall captures thecurrent_cred()toctx->credand all operations on the ring are executed under the context ofctx->cred.
Therefore all helper threads do the override_creds/revert_creds dance.But it doesn't - we're expecting them to match, and with this change, we assert that it's the case or return
-EPERM.Quoted 13 lines
But the possible non-blocking line execution of operations in the
io_uring_enter()syscall doesn't do the override_creds/revert_creds dance and execute the operations undercurrent_cred().This means it's random depending on filled cached under what credentials an operation is executed.
In order to prevent security problems the current patch is enough, but as outlined above it will make io-uring complete unuseable for applications using any syscall that changes
current_cred().Change 1. would be a little bit better, but still not really useful.
Quoted 7 lines
Quoted 3 lines
I'd actually prefer solution 3. as it's still possible to make use of non-blocking operations, while the security is the same as solution 2.
For your situation, we need to extend it anyway, and provide a way to swap between personalities. So yeah it won't work as-is for your use case, but we can work on making that the case.
That's only for the OPENAT2 case, which we might want to use in future, but there's a lot of work required to have async opens in Samba.
But I have a experimental module that, just use READV, WRITEV and FSYNC with io-uring in order to avoid our userspace helper threads.
And that won't work anymore with the change as Samba change current_cred() very often switch between (at least) 2 identities root and the user. That will change the pointer of current_cred() each time.
I mean I could work around the check by using IORING_SETUP_SQPOLL, but I'd like to avoid that.
metze
Jens Axboe
maintainerRe: [PATCH 5.4 033/222] io_uring: only allow submit from owning task
Quoted 104 lines · Stefan Metzmacher
Am 24.01.20 um 17:58 schrieb Jens Axboe:
Quoted 89 lines · Stefan Metzmacher
Quoted 64 lines
Am 22.01.20 um 10:26 schrieb Greg Kroah-Hartman:
Quoted 23 lines
From: Jens Axboe <[email protected]>
commit
44d282796f81eb1debc1d7cb53245b4cb3214cb5upstream.If the credentials or the mm doesn't match, don't allow the task to submit anything on behalf of this ring. The task that owns the ring can pass the file descriptor to another task, but we don't want to allow that task to submit an SQE that then assumes the ring mm and creds if it needs to go async.
Suggested-by Stefan Metzmacher <[email protected]>Signed-off-by Jens Axboe <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>--- fs/io_uring.c | 6 ++++++ 1 file changed, 6 insertions(+)fs/io_uring.c SYSCALL_DEFINE6(io_uring_enter, unsigned · line 3724
Quoted 9 lines
fs/io_uring.c +6
-0@@ -3716,6 +3716,12 @@ SYSCALL_DEFINE6(io_uring_enter, unsignedwake_up (&ctx->sqo_wait); submitted = to_submit; }else if (to_submit) { +if (current->mm != ctx->sqo_mm || +current_cred () != ctx->creds) { + ret = -EPERM ; + goto out; + } +I thought about this a bit more.
I'm not sure if this is actually to restrictive,
because it means applications like Samba won't
be able to use io-uring at all.As even if
current_cred()andctx->credsdescribe the same set of uid,gids the != won't ever match again and makes the whole ring unuseable.I'm not sure about what the best short term solution could be...
1. May just doing the check for path based operations? and fail individual requests with EPERM.
2. Or force
REQ_F_FORCE_ASYNCfor path based operations, so that they're always executed from within the workqueue with werectx->credsis active.3. Or (as proposed earlier) do the override_creds/revert_creds dance (and similar for mm) if needed.
To summaries the problem again:
For path based operations like:
-IORING_OP_CONNECT(maybe also -IORING_OP_ACCEPT???)
- IORING_OP_SEND*, IORING_OP_RECV* on DGRAM sockets
-IORING_OP_OPENAT,IORING_OP_STATX,IORING_OP_OPENAT2it's important under whichcurrent_credthey are called.Quoted 7 lines
Are
IORING_OP_MADVISE,IORING_OP_FADVISEandIORING_OP_FALLOCATEare only bound to the credentials of the passed fd they operate on?The current assumption is that the
io_uring_setup()syscall captures thecurrent_cred()toctx->credand all operations on the ring are executed under the context ofctx->cred.
Therefore all helper threads do the override_creds/revert_creds dance.But it doesn't - we're expecting them to match, and with this change, we assert that it's the case or return
-EPERM.Quoted 13 lines
But the possible non-blocking line execution of operations in the
io_uring_enter()syscall doesn't do the override_creds/revert_creds dance and execute the operations undercurrent_cred().This means it's random depending on filled cached under what credentials an operation is executed.
In order to prevent security problems the current patch is enough, but as outlined above it will make io-uring complete unuseable for applications using any syscall that changes
current_cred().Change 1. would be a little bit better, but still not really useful.
Quoted 7 lines
Quoted 3 lines
I'd actually prefer solution 3. as it's still possible to make use of non-blocking operations, while the security is the same as solution 2.
For your situation, we need to extend it anyway, and provide a way to swap between personalities. So yeah it won't work as-is for your use case, but we can work on making that the case.
That's only for the OPENAT2 case, which we might want to use in future, but there's a lot of work required to have async opens in Samba.
But I have a experimental module that, just use READV, WRITEV and FSYNC with io-uring in order to avoid our userspace helper threads.
Quoted 6 lines
And that won't work anymore with the change as Samba change
current_cred()very often switch between (at least) 2 identities root and the user. That will change the pointer ofcurrent_cred()each time.I mean I could work around the check by using
IORING_SETUP_SQPOLL, but I'd like to avoid that.
It's easy enough to support the current creds from io_uring_enter(), where we need a bit of plumbing is if we have to go async for that particular operation. We currently have that static as well, which is why the current patch is needed.
What I'm trying to say is that'll we'll need code changes to support this in any case, even just reverting that change isn't going to make the problem go away for you.
Hence we just need to decide on what the best way to do this would be!
Signature · 1 line
Jens Axboe
Re: [PATCH 5.4 033/222] io_uring: only allow submit from owning task
In reply to Stefan MetzmacherHi,
Quoted 36 lines · Stefan Metzmacher
Am 22.01.20 um 10:26 schrieb Greg Kroah-Hartman:
Quoted 23 lines
From: Jens Axboe <[email protected]>
commit
44d282796f81eb1debc1d7cb53245b4cb3214cb5upstream.If the credentials or the mm doesn't match, don't allow the task to submit anything on behalf of this ring. The task that owns the ring can pass the file descriptor to another task, but we don't want to allow that task to submit an SQE that then assumes the ring mm and creds if it needs to go async.
Suggested-by Stefan Metzmacher <[email protected]>Signed-off-by Jens Axboe <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>--- fs/io_uring.c | 6 ++++++ 1 file changed, 6 insertions(+)fs/io_uring.c SYSCALL_DEFINE6(io_uring_enter, unsigned · line 3724
Quoted 9 lines
fs/io_uring.c +6
-0@@ -3716,6 +3716,12 @@ SYSCALL_DEFINE6(io_uring_enter, unsignedwake_up (&ctx->sqo_wait); submitted = to_submit; }else if (to_submit) { +if (current->mm != ctx->sqo_mm || +current_cred () != ctx->creds) { + ret = -EPERM ; + goto out; + } +I thought about this a bit more.
Quoted 3 lines
I'm not sure if this is actually to restrictive, because it means applications like Samba won't
be able to use io-uring at all.
Yea, I think it is too restrictive. In fact, it broke my WIP branch to make postgres use io_uring.
Postgres uses a forked process model, with all sub-processes forked off one parent process ("postmaster"), sharing MAP_ANONYMOUS|MAP_SHARED memory (buffer pool, locks, and lots of other IPC). My WIP branch so far has postmaster create a number of io_urings that then the different processes can use (with locking if necessary).
In plenty of the cases it's fairly important for performance to not require an additional context switch initiate IO, therefore we cannot delegate submitting to an io_uring to separate process. But it's not feasible to have one (or even two) urings for each process either: For one, that's just about guaranteed to bring us over the default RLIMIT_MEMLOCK limit, and requiring root only config changes is not an option for many (nor user friendly).
Not sharing queues makes it basically impossible to rely on io_uring ordering properties when operation interlock is needed. E.g. to guarantee that the journal is flushed before some data buffer can be written back, being able to make use of links and drains is great - but there's one journal for all processes. To be able to guarantee anything, all the interlocked writes need to go through one io_uring. I've not yet implemented this, so I don't have numbers, but I expect pretty significant savings.
Not being able to share urings also makes it harder to resolve deadlocks:
As we call into both library and user defined code, we cannot guarantee that a specific backend process will promptly (or at all, when waiting for some locks) process cqes. There's also sections where we don't want to constantly check for ready events, for performance reasons. But operations initiated by a process might be blocking other connections:
E.g. process #1 might have initiated transferring a number of blocks into postgres' buffer pool via io_uring , and now is busy processing the first block that completed. But now process #2 might need one of the buffers that had IO queued, but didn't complete in time for #1 to see the results. The way I have it set up right now, #2 simply can process pending cqes in the relevant queue. Which, in this example, would mark the pg buffer pool entry as valid, allowing #2 to continue.
Now, completions can still be read by all processes, so I could continue to do the above: But that'd require all potentially needed io_urings to be set up in postmaster, before the first fork, and all processes to keep all those FDs open (commonly several hundred). Not an attractive option either, imo.
Obviously we could solve this by having a sqe result processing thread running within each process - but that'd be a very significant new overhead. And it'd require making some non-threadsafe code threadsafe, which I do not relish tackling as a side-effect of io_uring adoption.
It also turns out to be nice from a performance / context-switch rate angle to be able to process cqes for submissions by other processes. Saves an expensive context switch, and often enough it really doesn't matter which process processes the completion (especially for readahead). And in other cases it's cheap to just schedule the subsequent work from the cqe processor, e.g. initiating readahead of a few more blocks into the pg buffer pool. Similarly, there are a few cases where it's useful for several processes to submit IO into a uring primarily drained by one specific process, to offload the subsequent action, if that's expensive
Now, I think there's a valid argument to be made that postgres should just use threads, and not be hampered by any of this. But a) that's not going to happen all that soon, it's a large change, b) it's far from free from problems either, especially scalability on larger machines, and robustness.
Quoted 3 lines
As even if
current_cred()andctx->credsdescribe the same set of uid,gids the != won't ever match again and makes the whole ring unuseable.
Indeed. It also seems weird that a sqpoll now basically has different semantics, allowing the io_uring to be used by multiple processes - a task with a different mm can still wake the sqpoll thread up, even.
Since the different processes attached still can still write to the io_uring mmaped memory, they can still queue sqes, they just can't initiate the processing. But the next time the creator of the uring submits, they will still be - and thus it seems that the kernel needs to handle this safely. So I really don't get what this actually achieves? Am I missing something here?
Greetings,
Andres Freund
Jens Axboe
maintainerRe: [PATCH 5.4 033/222] io_uring: only allow submit from owning task
Quoted 128 lines · Andres Freund
Hi,
Quoted 36 lines · Stefan Metzmacher
Am 22.01.20 um 10:26 schrieb Greg Kroah-Hartman:
Quoted 23 lines
From: Jens Axboe <[email protected]>
commit
44d282796f81eb1debc1d7cb53245b4cb3214cb5upstream.If the credentials or the mm doesn't match, don't allow the task to submit anything on behalf of this ring. The task that owns the ring can pass the file descriptor to another task, but we don't want to allow that task to submit an SQE that then assumes the ring mm and creds if it needs to go async.
Suggested-by Stefan Metzmacher <[email protected]>Signed-off-by Jens Axboe <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>--- fs/io_uring.c | 6 ++++++ 1 file changed, 6 insertions(+)fs/io_uring.c SYSCALL_DEFINE6(io_uring_enter, unsigned · line 3724
Quoted 9 lines
fs/io_uring.c +6
-0@@ -3716,6 +3716,12 @@ SYSCALL_DEFINE6(io_uring_enter, unsignedwake_up (&ctx->sqo_wait); submitted = to_submit; }else if (to_submit) { +if (current->mm != ctx->sqo_mm || +current_cred () != ctx->creds) { + ret = -EPERM ; + goto out; + } +I thought about this a bit more.
Quoted 3 lines
I'm not sure if this is actually to restrictive, because it means applications like Samba won't
be able to use io-uring at all.Yea, I think it is too restrictive. In fact, it broke my WIP branch to make postgres use
io_uring.Postgres uses a forked process model, with all sub-processes forked off one parent process ("postmaster"), sharing MAP_ANONYMOUS|MAP_SHARED memory (buffer pool, locks, and lots of other IPC). My WIP branch so far has postmaster create a number of
io_uringsthat then the different processes can use (with locking if necessary).In plenty of the cases it's fairly important for performance to not require an additional context switch initiate IO, therefore we cannot delegate submitting to an
io_uringto separate process. But it's not feasible to have one (or even two) urings for each process either: For one, that's just about guaranteed to bring us over the defaultRLIMIT_MEMLOCKlimit, and requiring root only config changes is not an option for many (nor user friendly).Not sharing queues makes it basically impossible to rely on
io_uringordering properties when operation interlock is needed. E.g. to guarantee that the journal is flushed before some data buffer can be written back, being able to make use of links and drains is great - but there's one journal for all processes. To be able to guarantee anything, all the interlocked writes need to go through oneio_uring. I've not yet implemented this, so I don't have numbers, but I expect pretty significant savings.Not being able to share urings also makes it harder to resolve deadlocks:
As we call into both library and user defined code, we cannot guarantee that a specific backend process will promptly (or at all, when waiting for some locks) process cqes. There's also sections where we don't want to constantly check for ready events, for performance reasons. But operations initiated by a process might be blocking other connections:
E.g. process #1 might have initiated transferring a number of blocks into postgres' buffer pool via
io_uring, and now is busy processing the first block that completed. But now process #2 might need one of the buffers that had IO queued, but didn't complete in time for #1 to see the results. The way I have it set up right now, #2 simply can process pending cqes in the relevant queue. Which, in this example, would mark the pg buffer pool entry as valid, allowing #2 to continue.Now, completions can still be read by all processes, so I could continue to do the above: But that'd require all potentially needed
io_uringsto be set up in postmaster, before the first fork, and all processes to keep all those FDs open (commonly several hundred). Not an attractive option either, imo.Obviously we could solve this by having a sqe result processing thread running within each process - but that'd be a very significant new overhead. And it'd require making some non-threadsafe code threadsafe, which I do not relish tackling as a side-effect of
io_uringadoption.It also turns out to be nice from a performance / context-switch rate angle to be able to process cqes for submissions by other processes. Saves an expensive context switch, and often enough it really doesn't matter which process processes the completion (especially for readahead). And in other cases it's cheap to just schedule the subsequent work from the cqe processor, e.g. initiating readahead of a few more blocks into the pg buffer pool. Similarly, there are a few cases where it's useful for several processes to submit IO into a uring primarily drained by one specific process, to offload the subsequent action, if that's expensive
Now, I think there's a valid argument to be made that postgres should just use threads, and not be hampered by any of this. But a) that's not going to happen all that soon, it's a large change, b) it's far from free from problems either, especially scalability on larger machines, and robustness.
Quoted 3 lines
As even if
current_cred()andctx->credsdescribe the same set of uid,gids the != won't ever match again and makes the whole ring unuseable.Indeed. It also seems weird that a sqpoll now basically has different semantics, allowing the
io_uringto be used by multiple processes - a task with a different mm can still wake the sqpoll thread up, even.
Quoted 6 lines
Since the different processes attached still can still write to the
io_uringmmaped memory, they can still queue sqes, they just can't initiate the processing. But the next time the creator of the uring submits, they will still be - and thus it seems that the kernel needs to handle this safely. So I really don't get what this actually achieves? Am I missing something here?
Thanks for your detailed reported, I'm going to revert this change for 5.5.
Signature · 1 line
Jens Axboe
Greg Kroah-Hartman
maintainerPATCH 34/222 cpuidle: teo: Fix intervals[] array indexing bug
In reply to Greg Kroah-HartmanFrom: Ikjoon Jang <[email protected]>
commit 57388a2ccb6c2f554fee39772886c69b796dde53 upstream.
Fix a simple bug in rotating array index.
--- drivers/cpuidle/governors/teo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/cpuidle/governors/teo.c +1 -1
@@ -194,7 +194,7 @@ static void teo_update(struct cpuidle_dr* pattern detection. */ cpu_data->intervals[cpu_data->interval_idx++] = measured_us; -if (cpu_data->interval_idx >INTERVALS ) +if (cpu_data->interval_idx >=INTERVALS ) cpu_data->interval_idx =0 ; }
Greg Kroah-Hartman
maintainerPATCH 35/222 ARM: dts: am571x-idk: Fix gpios property to have the correct gpio number
In reply to Greg Kroah-HartmanFrom: Kishon Vijay Abraham I <[email protected]>
commit 0c4eb2a6b3c6b0facd0a3bccda5db22e7b3b6f96 upstream.
commit d23f3839fe97d8dce03d ("ARM: dts: DRA7: Add pcie1 dt node for EP mode") while adding the dt node for EP mode for DRA7 platform, added rc node for am571x-idk and populated gpios property with "gpio3 23". However the GPIO_PCIE_SWRST line is actually connected to "gpio5 18". Fix it here. (The patch adding "gpio3 23" was tested with another am57x board in EP mode which doesn't rely on reset from host).
--- arch/arm/boot/dts/am571x-idk.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/boot/dts/am571x-idk.dts +1 -1
@@ -167,7 +167,7 @@ &pcie1_rc { status = "okay"; - gpios = <&gpio3 23 GPIO_ACTIVE_HIGH>; + gpios = <&gpio5 18 GPIO_ACTIVE_HIGH>; }; &pcie1_ep {
Greg Kroah-Hartman
maintainerPATCH 36/222 ARM: davinci: select CONFIG_RESET_CONTROLLER
In reply to Greg Kroah-HartmanFrom: Arnd Bergmann <[email protected]>
commit 7afec66e2bf5683d8bfc812cc295313d1b8473bc upstream.
Selecting RESET_CONTROLLER is actually required, otherwise we can get a link failure in the clock driver:
drivers/clk/davinci/psc.o: In function `__davinci_psc_register_clocks':
psc.c:(.text+0x9a0): undefined reference to devm_reset_controller_register' drivers/clk/davinci/psc-da850.o: In function da850_psc0_init':
psc-da850.c:(.text+0x24): undefined reference to `reset_controller_add_lookup'
--- arch/arm/mach-davinci/Kconfig | 1 + 1 file changed, 1 insertion(+)
arch/arm/mach-davinci/Kconfig +1 -0
@@ -9,6 +9,7 @@ menuconfig ARCH_DAVINCI select PM_GENERIC_DOMAINS if PM select PM_GENERIC_DOMAINS_OF if PM && OF select REGMAP_MMIO + select RESET_CONTROLLER select HAVE_IDE select PINCTRL_SINGLE
Greg Kroah-Hartman
maintainerPATCH 37/222 perf: Correctly handle failed perf_get_aux_event()
In reply to Greg Kroah-HartmanFrom: Mark Rutland <[email protected]>
commit da9ec3d3dd0f1240a48920be063448a2242dbd90 upstream.
Vince reports a worrying issue:
| so I was tracking down some odd behavior in the perf_fuzzer which turns | out to be because perf_even_open() sometimes returns 0 (indicating a file | descriptor of 0) even though as far as I can tell stdin is still open.
... and further the cause:
| error is triggered if aux_sample_size has non-zero value. | | seems to be this line in kernel/events/core.c: | | if (perf_need_aux_event(event) && !perf_get_aux_event(event, group_leader)) | goto err_locked; | | (note, err is never set)
This seems to be a thinko in commit:
ab43762ef010967e ("perf: Allow normal events to output AUX data")
... and we should probably return -EINVAL here, as this should only happen when the new event is mis-configured or does not have a compatible aux_event group leader.
--- kernel/events/core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
kernel/events/core.c +3 -1
@@ -11182,8 +11182,10 @@ SYSCALL_DEFINE5(perf_event_open, } } -if (event->attr.aux_output && !perf_get_aux_event (event, group_leader)) +if (event->attr.aux_output && !perf_get_aux_event (event, group_leader)) { + err = -EINVAL ; goto err_locked; + }/* * Must be under the same ctx::mutex as perf_install_in_context(),
Greg Kroah-Hartman
maintainerPATCH 38/222 iio: adc: ad7124: Fix DT channel configuration
In reply to Greg Kroah-HartmanFrom: Alexandru Tachici <[email protected]>
commit d7857e4ee1ba69732b16c73b2f2dde83ecd78ee4 upstream.
This patch fixes device tree channel configuration.
ad7124 driver reads channels configuration from the device tree. It expects to find channel specifications as child nodes. Before this patch ad7124 driver assumed that the child nodes are parsed by for_each_available_child_of_node in the order 0,1,2,3...
This is wrong and the real order of the children can be seen by running:
dtc -I fs /sys/firmware/devicetree/base on the machine.
For example, running this on an rpi 3B+ yields the real children order: 4,2,0,7,5,3,1,6
Before this patch the driver assigned the channel configuration like this:
- 0 <- 4
- 1 <- 2
- 2 <- 0
........
For example, the symptoms can be observed by connecting the 4th channel to a 1V tension and then reading the in_voltage0-voltage19_raw sysfs (multiplied of course by the scale) one would see that channel 0 measures 1V and channel 4 measures only noise.
Now the driver uses the reg property of each child in order to correctly identify to which channel the parsed configuration belongs to.
Fixes b3af341bbd966: ("iio: adc: Add ad7124 support")
--- drivers/iio/adc/ad7124.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-)
drivers/iio/adc/ad7124.c +5 -7
@@ -494,13 +494,11 @@ static int ad7124_of_parse_channel_confi st->channel_config[channel].buf_negative =of_property_read_bool (child,"adi,buffered-negative" ); - *chan = ad7124_channel_template; - chan->address = channel; - chan->scan_index = channel; - chan->channel = ain[0 ]; - chan->channel2 = ain[1 ]; - - chan++; + chan[channel] = ad7124_channel_template; + chan[channel].address = channel; + chan[channel].scan_index = channel; + chan[channel].channel = ain[0 ]; + chan[channel].channel2 = ain[1 ]; }return 0 ;
Greg Kroah-Hartman
maintainerPATCH 39/222 iio: imu: st_lsm6dsx: Fix selection of ST_LSM6DS3_ID
In reply to Greg Kroah-HartmanFrom: Stephan Gerhold <[email protected]>
commit fb4fbc8904e786537e29329d791147389e1465a2 upstream.
At the moment, attempting to probe a device with ST_LSM6DS3_ID (e.g. using the st,lsm6ds3 compatible) fails with:
st_lsm6dsx_i2c 1-006b: unsupported whoami [69]
... even though 0x69 is the whoami listed for ST_LSM6DS3_ID.
This happens because st_lsm6dsx_check_whoami() also attempts to match unspecified (zero-initialized) entries in the "id" array. ST_LSM6DS3_ID = 0 will therefore match any entry in st_lsm6dsx_sensor_settings (here: the first), because none of them actually have all 12 entries listed in the "id" array.
Avoid this by additionally checking if "name" is set, which is only set for valid entries in the "id" array.
Note: Although the problem was introduced earlier it did not surface until commit 52f4b1f19679 ("iio: imu: st_lsm6dsx: add support for accel/gyro unit of lsm9ds1") because ST_LSM6DS3_ID was the first entry in st_lsm6dsx_sensor_settings.
--- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +2 -1
@@ -911,7 +911,8 @@ static int st_lsm6dsx_check_whoami(strucfor (i =0 ; i <ARRAY_SIZE (st_lsm6dsx_sensor_settings); i++) {for (j =0 ; j <ST_LSM6DSX_MAX_ID ; j++) { -if (id == st_lsm6dsx_sensor_settings[i].id[j].hw_id) +if (st_lsm6dsx_sensor_settings[i].id[j].name && + id == st_lsm6dsx_sensor_settings[i].id[j].hw_id)break ; }if (j <ST_LSM6DSX_MAX_ID )
Greg Kroah-Hartman
maintainerPATCH 40/222 iio: light: vcnl4000: Fix scale for vcnl4040
In reply to Greg Kroah-HartmanFrom: Guido Günther <[email protected]>
commit bc80573ea25bb033a58da81b3ce27205b97c088e upstream.
According to the data sheet the ambient sensor's scale is 0.12 lux/step (not 0.024 lux/step as used by vcnl4200) when the integration time is 80ms. The integration time is currently hardcoded in the driver to that value.
See p. 8 in https://www.vishay.com/docs/84307/designingvcnl4040.pdf
--- drivers/iio/light/vcnl4000.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/iio/light/vcnl4000.c +2 -1
@@ -163,7 +163,6 @@ static int vcnl4200_init(struct vcnl4000if (ret <0 )return ret; - data->al_scale =24000 ; data->vcnl4200_al.reg =VCNL4200_AL_DATA ; data->vcnl4200_ps.reg =VCNL4200_PS_DATA ;switch (id) {
@@ -172,11 +171,13 @@ static int vcnl4200_init(struct vcnl4000/* show 54ms in total. */ data->vcnl4200_al.sampling_rate =ktime_set (0 ,54000 *1000 ); data->vcnl4200_ps.sampling_rate =ktime_set (0 ,4200 *1000 ); + data->al_scale =24000 ;break ;case VCNL4040_PROD_ID :/* Integration time is 80ms, add 10ms. */ data->vcnl4200_al.sampling_rate =ktime_set (0 ,100000 *1000 ); data->vcnl4200_ps.sampling_rate =ktime_set (0 ,100000 *1000 ); + data->al_scale =120000 ;break ; } data->vcnl4200_al.last_measurement =ktime_set (0 ,0 );
Greg Kroah-Hartman
maintainerPATCH 41/222 iio: chemical: pms7003: fix unmet triggered buffer dependency
In reply to Greg Kroah-HartmanFrom: Tomasz Duszynski <[email protected]>
commit 217afe63ccf445fc220e5ef480683607b05c0aa5 upstream.
IIO triggered buffer depends on IIO buffer which is missing from Kconfig file. This should go unnoticed most of the time because there's a chance something else has already enabled buffers. In some rare cases though one might experience kbuild warnings about unmet direct dependencies and build failures due to missing symbols.
Fix this by selecting IIO_BUFFER explicitly.
--- drivers/iio/chemical/Kconfig | 1 + 1 file changed, 1 insertion(+)
drivers/iio/chemical/Kconfig +1 -0
@@ -65,6 +65,7 @@ config IAQCORE config PMS7003 tristate "Plantower PMS7003 particulate matter sensor" depends on SERIAL_DEV_BUS + select IIO_BUFFER select IIO_TRIGGERED_BUFFER help Say Y here to build support for the Plantower PMS7003 particulate
Greg Kroah-Hartman
maintainerPATCH 42/222 iio: buffer: align the size of scan bytes to size of the largest element
In reply to Greg Kroah-HartmanFrom: Lars Möllendorf <[email protected]>
commit 883f616530692d81cb70f8a32d85c0d2afc05f69 upstream.
Previous versions of iio_compute_scan_bytes only aligned each element to its own length (i.e. its own natural alignment). Because multiple consecutive sets of scan elements are buffered this does not work in case the computed scan bytes do not align with the natural alignment of the first scan element in the set.
This commit fixes this by aligning the scan bytes to the natural alignment of the largest scan element in the set.
--- drivers/iio/industrialio-buffer.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/iio/industrialio-buffer.c +5 -1
@@ -566,7 +566,7 @@ static int iio_compute_scan_bytes(struct const unsigned long *mask, bool timestamp) { unsigned bytes = 0; -int length, i; +int length, i, largest =0 ;/* How much space will the demuxed element take? */ for_each_set_bit(i, mask,
@@ -574,13 +574,17 @@ static int iio_compute_scan_bytes(struct length =iio_storage_bytes_for_si (indio_dev, i); bytes =ALIGN (bytes, length); bytes += length; + largest =max (largest, length); }if (timestamp) { length =iio_storage_bytes_for_timestamp (indio_dev); bytes =ALIGN (bytes, length); bytes += length; + largest =max (largest, length); } + + bytes =ALIGN (bytes, largest);return bytes; }
Greg Kroah-Hartman
maintainerPATCH 43/222 USB: serial: simple: Add Motorola Solutions TETRA MTP3xxx and MTP85xx
In reply to Greg Kroah-HartmanFrom: Jerónimo Borque <[email protected]>
commit 260e41ac4dd3e5acb90be624c03ba7f019615b75 upstream.
Add device-ids for the Motorola Solutions TETRA radios MTP3xxx series and MTP85xx series
$ lsusb -vd 0cad:
Bus 001 Device 009: ID 0cad:9015 Motorola CGISS TETRA PEI interface Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0 bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 idVendor 0x0cad Motorola CGISS idProduct 0x9015 bcdDevice 24.16 iManufacturer 1 iProduct 2 iSerial 0 bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 0x0037
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 3
bmAttributes 0x80
(Bus Powered)
MaxPower 500mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 0
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 0
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Bus 001 Device 010: ID 0cad:9013 Motorola CGISS TETRA PEI interface Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0 bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 idVendor 0x0cad Motorola CGISS idProduct 0x9013 bcdDevice 24.16 iManufacturer 1 iProduct 2 iSerial 0 bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 0x0037
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 3
bmAttributes 0x80
(Bus Powered)
MaxPower 500mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 0
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 0
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
--- drivers/usb/serial/usb-serial-simple.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/usb/serial/usb-serial-simple.c +2 -0
@@ -86,6 +86,8 @@ DEVICE(moto_modem, MOTO_IDS);#define MOTOROLA_TETRA_IDS () \ { USB_DEVICE(0x0cad, 0x9011) },/* Motorola Solutions TETRA PEI */ \ { USB_DEVICE(0x0cad, 0x9012) }, /* MTP6550 */ \ + { USB_DEVICE(0x0cad, 0x9013) }, /* MTP3xxx */ \ + { USB_DEVICE(0x0cad, 0x9015) }, /* MTP85xx */ \ { USB_DEVICE(0x0cad, 0x9016) } /* TPG2200 */DEVICE (motorola_tetra,MOTOROLA_TETRA_IDS );
Greg Kroah-Hartman
maintainerPATCH 44/222 USB: serial: option: Add support for Quectel RM500Q
In reply to Greg Kroah-HartmanFrom: Kristian Evensen <[email protected]>
commit accf227de4d211b52c830a58b2df00d5739f2389 upstream.
RM500Q is a 5G module from Quectel, supporting both standalone and non-standalone modes. Unlike other recent Quectel modems, it is possible to identify the diagnostic interface (bInterfaceProtocol is unique). Thus, there is no need to check for the number of endpoints or reserve interfaces. The interface number is still dynamic though, so matching on interface number is not possible and two entries have to be added to the table.
Output from usb-devices with all interfaces enabled (order is diag, nmea, at_port, modem, rmnet and adb):
Bus 004 Device 007: ID 2c7c:0800 Quectel Wireless Solutions Co., Ltd. Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 3.20
bDeviceClass 0 (Defined at Interface level) bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 9 idVendor 0x2c7c Quectel Wireless Solutions Co., Ltd. idProduct 0x0800 bcdDevice 4.14 iManufacturer 1 Quectel iProduct 2 LTE-A Module iSerial 3 40046d60 bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 328
bNumInterfaces 6
bConfigurationValue 1
iConfiguration 4 DIAG_SER_RMNET
bmAttributes 0xa0
(Bus Powered)
Remote Wakeup
MaxPower 224mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 255 Vendor Specific Subclass
bInterfaceProtocol 48
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0400 1x 1024 bytes
bInterval 0
bMaxBurst 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0400 1x 1024 bytes
bInterval 0
bMaxBurst 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 3
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 0
bInterfaceProtocol 0
iInterface 0
** UNRECOGNIZED: 05 24 00 10 01
** UNRECOGNIZED: 05 24 01 00 00
** UNRECOGNIZED: 04 24 02 02
** UNRECOGNIZED: 05 24 06 00 00
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x83 EP 3 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x000a 1x 10 bytes
bInterval 9
bMaxBurst 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0400 1x 1024 bytes
bInterval 0
bMaxBurst 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0400 1x 1024 bytes
bInterval 0
bMaxBurst 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 2
bAlternateSetting 0
bNumEndpoints 3
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 0
bInterfaceProtocol 0
iInterface 0
** UNRECOGNIZED: 05 24 00 10 01
** UNRECOGNIZED: 05 24 01 00 00
** UNRECOGNIZED: 04 24 02 02
** UNRECOGNIZED: 05 24 06 00 00
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x85 EP 5 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x000a 1x 10 bytes
bInterval 9
bMaxBurst 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x84 EP 4 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0400 1x 1024 bytes
bInterval 0
bMaxBurst 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x03 EP 3 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0400 1x 1024 bytes
bInterval 0
bMaxBurst 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 3
bAlternateSetting 0
bNumEndpoints 3
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 0
bInterfaceProtocol 0
iInterface 0
** UNRECOGNIZED: 05 24 00 10 01
** UNRECOGNIZED: 05 24 01 00 00
** UNRECOGNIZED: 04 24 02 02
** UNRECOGNIZED: 05 24 06 00 00
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x87 EP 7 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x000a 1x 10 bytes
bInterval 9
bMaxBurst 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x86 EP 6 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0400 1x 1024 bytes
bInterval 0
bMaxBurst 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x04 EP 4 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0400 1x 1024 bytes
bInterval 0
bMaxBurst 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 4
bAlternateSetting 0
bNumEndpoints 3
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 255 Vendor Specific Subclass
bInterfaceProtocol 255 Vendor Specific Protocol
iInterface 5 CDEV Serial
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x88 EP 8 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 9
bMaxBurst 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x8e EP 14 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0400 1x 1024 bytes
bInterval 0
bMaxBurst 6
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x0f EP 15 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0400 1x 1024 bytes
bInterval 0
bMaxBurst 2
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 5
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 66
bInterfaceProtocol 1
iInterface 6 ADB Interface
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x05 EP 5 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0400 1x 1024 bytes
bInterval 0
bMaxBurst 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x89 EP 9 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0400 1x 1024 bytes
bInterval 0
bMaxBurst 0
Binary Object Store Descriptor:
bLength 5
bDescriptorType 15
wTotalLength 42
bNumDeviceCaps 3
USB 2.0 Extension Device Capability:
bLength 7
bDescriptorType 16
bDevCapabilityType 2
bmAttributes 0x00000006
Link Power Management (LPM) Supported
SuperSpeed USB Device Capability:
bLength 10
bDescriptorType 16
bDevCapabilityType 3
bmAttributes 0x00
wSpeedsSupported 0x000f
Device can operate at Low Speed (1Mbps)
Device can operate at Full Speed (12Mbps)
Device can operate at High Speed (480Mbps)
Device can operate at SuperSpeed (5Gbps)
bFunctionalitySupport 1
Lowest fully-functional device speed is Full Speed (12Mbps)
bU1DevExitLat 1 micro seconds
bU2DevExitLat 500 micro seconds
** UNRECOGNIZED: 14 10 0a 00 01 00 00 00 00 11 00 00 30 40 0a 00 b0 40 0a 00
Device Status: 0x0000
(Bus Powered)
--- drivers/usb/serial/option.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/usb/serial/option.c +4 -0
@@ -248,6 +248,7 @@ static void option_instat_callback(struc#define QUECTEL_PRODUCT_BG96 0x0296#define QUECTEL_PRODUCT_EP06 0x0306#define QUECTEL_PRODUCT_EM12 0x0512 +#define QUECTEL_PRODUCT_RM500Q 0x0800#define CMOTECH_VENDOR_ID 0x16d8#define CMOTECH_PRODUCT_6001 0x6001
@@ -1104,6 +1105,9 @@ static const struct usb_device_id option { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0xff, 0xff), .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0xff, 0x30) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0, 0) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) }, { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) }, { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6003),
Greg Kroah-Hartman
maintainerPATCH 45/222 USB: serial: opticon: fix control-message timeouts
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 5e28055f340275a8616eee88ef19186631b4d136 upstream.
The driver was issuing synchronous uninterruptible control requests without using a timeout. This could lead to the driver hanging on open() or tiocmset() due to a malfunctioning (or malicious) device until the device is physically disconnected.
The USB upper limit of five seconds per request should be more than enough.
--- drivers/usb/serial/opticon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/serial/opticon.c +1 -1
@@ -113,7 +113,7 @@ static int send_control_msg(struct usb_s retval =usb_control_msg (serial->dev,usb_sndctrlpipe (serial->dev,0 ), requesttype,USB_DIR_OUT |USB_TYPE_VENDOR |USB_RECIP_INTERFACE , -0 ,0 , buffer,1 ,0 ); +0 ,0 , buffer,1 ,USB_CTRL_SET_TIMEOUT );kfree (buffer);if (retval <0 )
Greg Kroah-Hartman
maintainerPATCH 46/222 USB: serial: option: add support for Quectel RM500Q in QDL mode
In reply to Greg Kroah-HartmanFrom: Reinhard Speyerer <[email protected]>
commit f3eaabbfd093c93d791eb930cc68d9b15246a65e upstream.
Add support for Quectel RM500Q in QDL mode.
T: Bus=02 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 24 Spd=480 MxCh= 0 D: Ver= 2.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=2c7c ProdID=0800 Rev= 0.00 S: Manufacturer=Qualcomm CDMA Technologies MSM S: Product=QUSB_BULK_SN:xxxxxxxx S: SerialNumber=xxxxxxxx C:* #Ifs= 1 Cfg#= 1 Atr=a0 MxPwr= 2mA I:* If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=10 Driver=option E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
It is assumed that the ZLP flag required for other Qualcomm-based 5G devices also applies to Quectel RM500Q.
--- drivers/usb/serial/option.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/usb/serial/option.c +2 -0
@@ -1107,6 +1107,8 @@ static const struct usb_device_id option { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0, 0) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0xff, 0x30) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0xff, 0x10), + .driver_info = ZLP }, { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) }, { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) },
Greg Kroah-Hartman
maintainerPATCH 47/222 USB: serial: suppress driver bind attributes
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit fdb838efa31e1ed9a13ae6ad0b64e30fdbd00570 upstream.
USB-serial drivers must not be unbound from their ports before the corresponding USB driver is unbound from the parent interface so suppress the bind and unbind attributes.
Unbinding a serial driver while it's port is open is a sure way to trigger a crash as any driver state is released on unbind while port hangup is handled on the parent USB interface level. Drivers for multiport devices where ports share a resource such as an interrupt endpoint also generally cannot handle individual ports going away.
--- drivers/usb/serial/usb-serial.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/usb/serial/usb-serial.c +3 -0
@@ -1317,6 +1317,9 @@ static int usb_serial_register(struct usreturn -EINVAL ; } +/* Prevent individual ports from being unbound. */ + driver->driver.suppress_bind_attrs = true; +usb_serial_operations_init (driver);/* Add this device to our list of devices */
Greg Kroah-Hartman
maintainerPATCH 48/222 USB: serial: ch341: handle unbound port at reset_resume
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 4d5ef53f75c22d28f490bcc5c771fcc610a9afa4 upstream.
Check for NULL port data in reset_resume() to avoid dereferencing a NULL pointer in case the port device isn't bound to a driver (e.g. after a failed control request at port probe).
--- drivers/usb/serial/ch341.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/usb/serial/ch341.c +5 -1
@@ -589,9 +589,13 @@ static int ch341_tiocmget(struct tty_strstatic int ch341_reset_resume (struct usb_serial *serial) {struct usb_serial_port *port = serial->port[0 ]; -struct ch341_private *priv =usb_get_serial_port_data (port); +struct ch341_private *priv;int ret; + priv =usb_get_serial_port_data (port); +if (!priv) +return 0 ; +/* reconfigure ch341 serial port after bus-reset */ ch341_configure (serial->dev, priv);
Greg Kroah-Hartman
maintainerPATCH 49/222 USB: serial: io_edgeport: handle unbound ports on URB completion
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit e37d1aeda737a20b1846a91a3da3f8b0f00cf690 upstream.
Check for NULL port data in the shared interrupt and bulk completion callbacks to avoid dereferencing a NULL pointer in case a device sends data for a port device which isn't bound to a driver (e.g. due to a malicious device having unexpected endpoints or after an allocation failure on port probe).
--- drivers/usb/serial/io_edgeport.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/usb/serial/io_edgeport.c +2 -2
@@ -716,7 +716,7 @@ static void edge_interrupt_callback(struif (txCredits) { port = edge_serial->serial->port[portNumber]; edge_port =usb_get_serial_port_data (port); -if (edge_port->open) { +if (edge_port && edge_port->open) {spin_lock_irqsave (&edge_port->ep_lock, flags); edge_port->txCredits += txCredits;
@@ -1825,7 +1825,7 @@ static void process_rcvd_data(struct edg port = edge_serial->serial->port[ edge_serial->rxPort]; edge_port =usb_get_serial_port_data (port); -if (edge_port->open) { +if (edge_port && edge_port->open) {dev_dbg (dev,"%s - Sending %d bytes to TTY for port %d\n" , __func__, rxLen, edge_serial->rxPort);
Greg Kroah-Hartman
maintainerPATCH 50/222 USB: serial: io_edgeport: add missing active-port sanity check
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 1568c58d11a7c851bd09341aeefd6a1c308ac40d upstream.
The driver receives the active port number from the device, but never made sure that the port number was valid. This could lead to a NULL-pointer dereference or memory corruption in case a device sends data for an invalid port.
--- drivers/usb/serial/io_edgeport.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
drivers/usb/serial/io_edgeport.c +7 -5
@@ -1725,7 +1725,8 @@ static void edge_break(struct tty_structstatic void process_rcvd_data (struct edgeport_serial *edge_serial,unsigned char *buffer,__u16 bufferLength) { -struct device *dev = &edge_serial->serial->dev->dev; +struct usb_serial *serial = edge_serial->serial; +struct device *dev = &serial->dev->dev;struct usb_serial_port *port;struct edgeport_port *edge_port;__u16 lastBufferLength;
@@ -1821,9 +1822,8 @@ static void process_rcvd_data(struct edg/* spit this data back into the tty driver if this port is open */ -if (rxLen) { - port = edge_serial->serial->port[ - edge_serial->rxPort]; +if (rxLen && edge_serial->rxPort < serial->num_ports) { + port = serial->port[edge_serial->rxPort]; edge_port =usb_get_serial_port_data (port);if (edge_port && edge_port->open) { dev_dbg(dev, "%s - Sending %d bytes to TTY for port %d\n",
@@ -1833,8 +1833,8 @@ static void process_rcvd_data(struct edg rxLen); edge_port->port->icount.rx += rxLen; } - buffer += rxLen; } + buffer += rxLen;break ;case EXPECT_HDR3 :/* Expect 3rd byte of status header */
@@ -1869,6 +1869,8 @@ static void process_rcvd_status(struct e__u8 code = edge_serial->rxStatusCode;/* switch the port pointer to the one being currently talked about */ +if (edge_serial->rxPort >= edge_serial->serial->num_ports) +return ; port = edge_serial->serial->port[edge_serial->rxPort]; edge_port =usb_get_serial_port_data (port);if (edge_port ==NULL ) {
Greg Kroah-Hartman
maintainerPATCH 51/222 USB: serial: keyspan: handle unbound ports
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 3018dd3fa114b13261e9599ddb5656ef97a1fa17 upstream.
Check for NULL port data in the control URB completion handlers to avoid dereferencing a NULL pointer in the unlikely case where a port device isn't bound to a driver (e.g. after an allocation failure on port probe()).
--- drivers/usb/serial/keyspan.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/usb/serial/keyspan.c +4 -0
@@ -1058,6 +1058,8 @@ static void usa49_glocont_callback(strucfor (i =0 ; i < serial->num_ports; ++i) { port = serial->port[i]; p_priv =usb_get_serial_port_data (port); +if (!p_priv) +continue ;if (p_priv->resend_cont) {dev_dbg (&port->dev,"%s - sending setup\n" , __func__);
@@ -1459,6 +1461,8 @@ static void usa67_glocont_callback(strucfor (i =0 ; i < serial->num_ports; ++i) { port = serial->port[i]; p_priv =usb_get_serial_port_data (port); +if (!p_priv) +continue ;if (p_priv->resend_cont) {dev_dbg (&port->dev,"%s - sending setup\n" , __func__);
Greg Kroah-Hartman
maintainerPATCH 52/222 USB: serial: quatech2: handle unbound ports
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit 9715a43eea77e42678a1002623f2d9a78f5b81a1 upstream.
Check for NULL port data in the modem- and line-status handlers to avoid dereferencing a NULL pointer in the unlikely case where a port device isn't bound to a driver (e.g. after an allocation failure on port probe).
Note that the other (stubbed) event handlers qt2_process_xmit_empty() and qt2_process_flush() would need similar sanity checks in case they are ever implemented.
--- drivers/usb/serial/quatech2.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/usb/serial/quatech2.c +6 -0
@@ -841,7 +841,10 @@ static void qt2_update_msr(struct usb_seu8 newMSR = (u8) *ch;unsigned long flags; +/* May be called from qt2_process_read_urb() for an unbound port. */ port_priv =usb_get_serial_port_data (port); +if (!port_priv) +return ;spin_lock_irqsave (&port_priv->lock, flags); port_priv->shadowMSR = newMSR;
@@ -869,7 +872,10 @@ static void qt2_update_lsr(struct usb_seunsigned long flags;u8 newLSR = (u8) *ch; +/* May be called from qt2_process_read_urb() for an unbound port. */ port_priv =usb_get_serial_port_data (port); +if (!port_priv) +return ;if (newLSR &UART_LSR_BI ) newLSR &= (u8) (UART_LSR_OE |UART_LSR_BI );
Greg Kroah-Hartman
maintainerPATCH 53/222 staging: comedi: ni_routes: fix null dereference in ni_find_route_source()
In reply to Greg Kroah-HartmanFrom: Ian Abbott <[email protected]>
commit 01e20b664f808a4f3048ca3f930911fd257209bd upstream.
In ni_find_route_source(), tables->route_values gets dereferenced. However it is possible that tables->route_values is NULL, leading to a null pointer dereference. tables->route_values will be NULL if the call to ni_assign_device_routes() during board initialization returned an error due to missing device family routing information or missing board-specific routing information. For example, there is currently no board-specific routing information provided for the PCIe-6251 board and several other boards, so those are affected by this bug.
The bug is triggered when ni_find_route_source() is called via ni_check_trigger_arg() or ni_check_trigger_arg_roffs() when checking the arguments for setting up asynchronous commands. Fix it by returning -EINVAL if tables->route_values is NULL.
Even with this fix, setting up asynchronous commands to use external trigger sources for boards with missing routing information will still fail gracefully. Since ni_find_route_source() only depends on the device family routing information, it would be better if that was made available even if the board-specific routing information is missing. That will be addressed by another patch.
--- drivers/staging/comedi/drivers/ni_routes.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/staging/comedi/drivers/ni_routes.c +3 -0
@@ -489,6 +489,9 @@ int ni_find_route_source(const u8 src_se {int src; +if (!tables->route_values) +return -EINVAL ; + dest =B (dest);/* subtract NI names offset */ /* ensure we are not going to under/over run the route value table */ if (dest <0 || dest >=NI_NUM_NAMES )
Greg Kroah-Hartman
maintainerPATCH 54/222 staging: comedi: ni_routes: allow partial routing information
In reply to Greg Kroah-HartmanFrom: Ian Abbott <[email protected]>
commit 9fea3a40f6b07de977a2783270c8c3bc82544d45 upstream.
This patch fixes a regression on setting up asynchronous commands to use external trigger sources when board-specific routing information is missing.
ni_find_device_routes() (called via ni_assign_device_routes()) finds the table of register values for the device family and the set of valid routes for the specific board. If both are found, tables->route_values is set to point to the table of register values for the device family and tables->valid_routes is set to point to the list of valid routes for the specific board. If either is not found, both tables->route_values and tables->valid_routes are left set at their initial null values (initialized by ni_assign_device_routes()) and the function returns -ENODATA.
Returning an error results in some routing functionality being disabled. Unfortunately, leaving table->route_values set to NULL also breaks the setting up of asynchronous commands that are configured to use external trigger sources. Calls to ni_check_trigger_arg() or ni_check_trigger_arg_roffs() while checking the asynchronous command set-up would result in a null pointer dereference if table->route_values is NULL. The null pointer dereference is fixed in another patch, but it now results in failure to set up the asynchronous command. That is a regression from the behavior prior to commit 347e244884c3 ("staging: comedi: tio: implement global tio/ctr routing") and commit 56d0b826d39f ("staging: comedi: ni_mio_common:
implement new routing for TRIG_EXT").
Change ni_find_device_routes() to set tables->route_values and/or tables->valid_routes to valid information even if the other one can only be set to NULL due to missing information. The function will still return an error in that case. This should result in tables->valid_routes being valid for all currently supported device families even if the board-specific routing information is missing. That should be enough to fix the regression on setting up asynchronous commands to use external triggers for boards with missing routing information.
--- drivers/staging/comedi/drivers/ni_routes.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
drivers/staging/comedi/drivers/ni_routes.c +3 -6
@@ -74,9 +74,6 @@ static int ni_find_device_routes(const c } } -if (!rv) -return -ENODATA ; -/* Second, find the set of routes valid for this device. */ for (i =0 ; ni_device_routes_list[i]; ++i) { if (memcmp(ni_device_routes_list[i]->device, board_name,
@@ -86,12 +83,12 @@ static int ni_find_device_routes(const c } } -if (!dr) -return -ENODATA ; - tables->route_values = rv; tables->valid_routes = dr; +if (!rv || !dr) +return -ENODATA ; +return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 55/222 scsi: fnic: fix invalid stack access
In reply to Greg Kroah-HartmanFrom: Arnd Bergmann <[email protected]>
commit 42ec15ceaea74b5f7a621fc6686cbf69ca66c4cf upstream.
gcc -O3 warns that some local variables are not properly initialized:
drivers/scsi/fnic/vnic_dev.c: In function 'fnic_dev_hang_notify':drivers/scsi/fnic/vnic_dev.c:511:16: error: 'a0' is used uninitialized in this function [-Werror=uninitialized]
vdev->args[0] = *a0;
~~~~~~~~~~~~~~^~~~~drivers/scsi/fnic/vnic_dev.c:691:6: note: 'a0' was declared here
u64 a0, a1;
^~drivers/scsi/fnic/vnic_dev.c:512:16: error: 'a1' is used uninitialized in this function [-Werror=uninitialized]
vdev->args[1] = *a1;
~~~~~~~~~~~~~~^~~~~drivers/scsi/fnic/vnic_dev.c:691:10: note: 'a1' was declared here
u64 a0, a1;
^~drivers/scsi/fnic/vnic_dev.c: In function 'fnic_dev_mac_addr':drivers/scsi/fnic/vnic_dev.c:512:16: error: 'a1' is used uninitialized in this function [-Werror=uninitialized]
vdev->args[1] = *a1;
~~~~~~~~~~~~~~^~~~~drivers/scsi/fnic/vnic_dev.c:698:10: note: 'a1' was declared here
u64 a0, a1;
^~Apparently the code relies on the local variables occupying adjacent memory locations in the same order, but this is of course not guaranteed.
Use an array of two u64 variables where needed to make it work correctly.
I suspect there is also an endianness bug here, but have not digged in deep enough to be sure.
--- drivers/scsi/fnic/vnic_dev.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
drivers/scsi/fnic/vnic_dev.c +10 -10
@@ -688,26 +688,26 @@ int vnic_dev_soft_reset_done(struct vnicint vnic_dev_hang_notify (struct vnic_dev *vdev) { -u64 a0, a1; +u64 a0 =0 , a1 =0 ;int wait =1000 ;return vnic_dev_cmd (vdev,CMD_HANG_NOTIFY , &a0, &a1, wait); }int vnic_dev_mac_addr (struct vnic_dev *vdev,u8 *mac_addr) { -u64 a0, a1; +u64 a[2 ] = {};int wait =1000 ;int err, i;for (i =0 ; i <ETH_ALEN ; i++) mac_addr[i] =0 ; - err =vnic_dev_cmd (vdev,CMD_MAC_ADDR , &a0, &a1, wait); + err =vnic_dev_cmd (vdev,CMD_MAC_ADDR , &a[0 ], &a[1 ], wait);if (err)return err;for (i =0 ; i <ETH_ALEN ; i++) - mac_addr[i] = ((u8 *)&a0)[i]; + mac_addr[i] = ((u8 *)&a)[i];return 0 ; }
@@ -732,30 +732,30 @@ void vnic_dev_packet_filter(struct vnic_void vnic_dev_add_addr (struct vnic_dev *vdev,u8 *addr) { -u64 a0 =0 , a1 =0 ; +u64 a[2 ] = {};int wait =1000 ;int err;int i;for (i =0 ; i <ETH_ALEN ; i++) - ((u8 *)&a0)[i] = addr[i]; + ((u8 *)&a)[i] = addr[i]; - err =vnic_dev_cmd (vdev,CMD_ADDR_ADD , &a0, &a1, wait); + err =vnic_dev_cmd (vdev,CMD_ADDR_ADD , &a[0 ], &a[1 ], wait);if (err)pr_err ("Can't add addr [%pM], %d\n" , addr, err); }void vnic_dev_del_addr (struct vnic_dev *vdev,u8 *addr) { -u64 a0 =0 , a1 =0 ; +u64 a[2 ] = {};int wait =1000 ;int err;int i;for (i =0 ; i <ETH_ALEN ; i++) - ((u8 *)&a0)[i] = addr[i]; + ((u8 *)&a)[i] = addr[i]; - err =vnic_dev_cmd (vdev,CMD_ADDR_DEL , &a0, &a1, wait); + err =vnic_dev_cmd (vdev,CMD_ADDR_DEL , &a[0 ], &a[1 ], wait);if (err)pr_err ("Can't del addr [%pM], %d\n" , addr, err); }
Greg Kroah-Hartman
maintainerPATCH 56/222 scsi: mptfusion: Fix double fetch bug in ioctl
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
commit 28d76df18f0ad5bcf5fa48510b225f0ed262a99b upstream.
Tom Hatskevich reported that we look up "iocp" then, in the called functions we do a second copy_from_user() and look it up again. The problem that could cause is:
drivers/message/fusion/mptctl.c
674 /* All of these commands require an interrupt or
675 * are unknown/illegal.
676 */
677 if ((ret = mptctl_syscall_down(iocp, nonblock)) != 0)
^^^^
We take this lock.
678 return ret;
679
680 if (cmd == MPTFWDOWNLOAD)
681 ret = mptctl_fw_download(arg);
^^^Then the user memory changes and we look up "iocp" again but a different one so now we are holding the incorrect lock and have a race condition.
682 else if (cmd == MPTCOMMAND) 683 ret = mptctl_mpt_command(arg);
The security impact of this bug is not as bad as it could have been because these operations are all privileged and root already has enormous destructive power. But it's still worth fixing.
This patch passes the "iocp" pointer to the functions to avoid the second lookup. That deletes 100 lines of code from the driver so it's a nice clean up as well.
--- drivers/message/fusion/mptctl.c | 213 +++++++++------------------------------- 1 file changed, 50 insertions(+), 163 deletions(-)
drivers/message/fusion/mptctl.c +50 -163
@@ -100,19 +100,19 @@ struct buflist {* Function prototypes. Called from OS entry point mptctl_ioctl. * arg contents specific to function. */ -static int mptctl_fw_download (unsigned long arg); -static int mptctl_getiocinfo (unsigned long arg,unsigned int cmd); -static int mptctl_gettargetinfo (unsigned long arg); -static int mptctl_readtest (unsigned long arg); -static int mptctl_mpt_command (unsigned long arg); -static int mptctl_eventquery (unsigned long arg); -static int mptctl_eventenable (unsigned long arg); -static int mptctl_eventreport (unsigned long arg); -static int mptctl_replace_fw (unsigned long arg); - -static int mptctl_do_reset (unsigned long arg); -static int mptctl_hp_hostinfo (unsigned long arg,unsigned int cmd); -static int mptctl_hp_targetinfo (unsigned long arg); +static int mptctl_fw_download (MPT_ADAPTER *iocp,unsigned long arg); +static int mptctl_getiocinfo (MPT_ADAPTER *iocp,unsigned long arg,unsigned int cmd); +static int mptctl_gettargetinfo (MPT_ADAPTER *iocp,unsigned long arg); +static int mptctl_readtest (MPT_ADAPTER *iocp,unsigned long arg); +static int mptctl_mpt_command (MPT_ADAPTER *iocp,unsigned long arg); +static int mptctl_eventquery (MPT_ADAPTER *iocp,unsigned long arg); +static int mptctl_eventenable (MPT_ADAPTER *iocp,unsigned long arg); +static int mptctl_eventreport (MPT_ADAPTER *iocp,unsigned long arg); +static int mptctl_replace_fw (MPT_ADAPTER *iocp,unsigned long arg); + +static int mptctl_do_reset (MPT_ADAPTER *iocp,unsigned long arg); +static int mptctl_hp_hostinfo (MPT_ADAPTER *iocp,unsigned long arg,unsigned int cmd); +static int mptctl_hp_targetinfo (MPT_ADAPTER *iocp,unsigned long arg);static int mptctl_probe (struct pci_dev *,const struct pci_device_id *);static void mptctl_remove (struct pci_dev *);
@@ -123,8 +123,8 @@ static long compat_mpctl_ioctl(struct fi/* * Private function calls. */ -static int mptctl_do_mpt_command (struct mpt_ioctl_command karg,void __user *mfPtr); -static int mptctl_do_fw_download (int ioc,char __user *ufwbuf,size_t fwlen); +static int mptctl_do_mpt_command (MPT_ADAPTER *iocp,struct mpt_ioctl_command karg,void __user *mfPtr); +static int mptctl_do_fw_download (MPT_ADAPTER *iocp,char __user *ufwbuf,size_t fwlen);static MptSge_t *kbuf_alloc_2_sgl (int bytes,u32 dir,int sge_offset,int *frags,struct buflist **blp,dma_addr_t *sglbuf_dma,MPT_ADAPTER *ioc); static void kfree_sgl(MptSge_t *sgl, dma_addr_t sgl_dma,
@@ -656,19 +656,19 @@ __mptctl_ioctl(struct file *file, unsign* by TM and FW reloads. */ if ((cmd & ~IOCSIZE_MASK ) == (MPTIOCINFO & ~IOCSIZE_MASK )) { -return mptctl_getiocinfo (arg,_IOC_SIZE (cmd)); +return mptctl_getiocinfo (iocp, arg,_IOC_SIZE (cmd)); }else if (cmd ==MPTTARGETINFO ) { -return mptctl_gettargetinfo (arg); +return mptctl_gettargetinfo (iocp, arg); }else if (cmd ==MPTTEST ) { -return mptctl_readtest (arg); +return mptctl_readtest (iocp, arg); }else if (cmd ==MPTEVENTQUERY ) { -return mptctl_eventquery (arg); +return mptctl_eventquery (iocp, arg); }else if (cmd ==MPTEVENTENABLE ) { -return mptctl_eventenable (arg); +return mptctl_eventenable (iocp, arg); }else if (cmd ==MPTEVENTREPORT ) { -return mptctl_eventreport (arg); +return mptctl_eventreport (iocp, arg); }else if (cmd ==MPTFWREPLACE ) { -return mptctl_replace_fw (arg); +return mptctl_replace_fw (iocp, arg); }/* All of these commands require an interrupt or
@@ -678,15 +678,15 @@ __mptctl_ioctl(struct file *file, unsignreturn ret;if (cmd ==MPTFWDOWNLOAD ) - ret =mptctl_fw_download (arg); + ret =mptctl_fw_download (iocp, arg);else if (cmd ==MPTCOMMAND ) - ret =mptctl_mpt_command (arg); + ret =mptctl_mpt_command (iocp, arg);else if (cmd ==MPTHARDRESET ) - ret =mptctl_do_reset (arg); + ret =mptctl_do_reset (iocp, arg);else if ((cmd & ~IOCSIZE_MASK ) == (HP_GETHOSTINFO & ~IOCSIZE_MASK )) - ret =mptctl_hp_hostinfo (arg,_IOC_SIZE (cmd)); + ret =mptctl_hp_hostinfo (iocp, arg,_IOC_SIZE (cmd));else if (cmd ==HP_GETTARGETINFO ) - ret =mptctl_hp_targetinfo (arg); + ret =mptctl_hp_targetinfo (iocp, arg);else ret = -EINVAL ;
@@ -705,11 +705,10 @@ mptctl_ioctl(struct file *file, unsignedreturn ret; } -static int mptctl_do_reset (unsigned long arg) +static int mptctl_do_reset (MPT_ADAPTER *iocp,unsigned long arg) {struct mpt_ioctl_diag_reset __user *urinfo = (void __user *) arg;struct mpt_ioctl_diag_reset krinfo; -MPT_ADAPTER *iocp;if (copy_from_user (&krinfo, urinfo,sizeof (struct mpt_ioctl_diag_reset ))) { printk(KERN_ERR MYNAM "%s@%d::mptctl_do_reset - "
@@ -718,12 +717,6 @@ static int mptctl_do_reset(unsigned longreturn -EFAULT ; } -if (mpt_verify_adapter (krinfo.hdr.iocnum, &iocp) <0 ) { - printk(KERN_DEBUG MYNAM "%s@%d::mptctl_do_reset - ioc%d not found!\n", - __FILE__, __LINE__, krinfo.hdr.iocnum); -return -ENODEV ;/* (-6) No such device or address */ - } -dctlprintk (iocp,printk (MYIOC_s_DEBUG_FMT"mptctl_do_reset called.\n" , iocp->name));
@@ -754,7 +747,7 @@ static int mptctl_do_reset(unsigned long* -ENOMSG if FW upload returned bad status */ static int -mptctl_fw_download (unsigned long arg) +mptctl_fw_download (MPT_ADAPTER *iocp,unsigned long arg) {struct mpt_fw_xfer __user *ufwdl = (void __user *) arg;struct mpt_fw_xfer kfwdl;
@@ -766,7 +759,7 @@ mptctl_fw_download(unsigned long arg)return -EFAULT ; } -return mptctl_do_fw_download (kfwdl.iocnum, kfwdl.bufp, kfwdl.fwlen); +return mptctl_do_fw_download (iocp, kfwdl.bufp, kfwdl.fwlen); }/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -784,11 +777,10 @@ mptctl_fw_download(unsigned long arg)* -ENOMSG if FW upload returned bad status */ static int -mptctl_do_fw_download (int ioc,char __user *ufwbuf,size_t fwlen) +mptctl_do_fw_download (MPT_ADAPTER *iocp,char __user *ufwbuf,size_t fwlen) {FWDownload_t *dlmsg;MPT_FRAME_HDR *mf; -MPT_ADAPTER *iocp;FWDownloadTCSGE_t *ptsge;MptSge_t *sgl, *sgIn;char *sgOut;
@@ -808,17 +800,10 @@ mptctl_do_fw_download(int ioc, char __uspFWDownloadReply_t ReplyMsg =NULL ;unsigned long timeleft; -if (mpt_verify_adapter (ioc, &iocp) <0 ) { - printk(KERN_DEBUG MYNAM "ioctl_fwdl - ioc%d not found!\n", - ioc); -return -ENODEV ;/* (-6) No such device or address */ - }else { - -/* Valid device. Get a message frame and construct the FW download message. -*/ -if ((mf =mpt_get_msg_frame (mptctl_id, iocp)) ==NULL ) -return -EAGAIN ; - } +/* Valid device. Get a message frame and construct the FW download message. +*/ +if ((mf =mpt_get_msg_frame (mptctl_id, iocp)) ==NULL ) +return -EAGAIN ;dctlprintk (iocp,printk (MYIOC_s_DEBUG_FMT"mptctl_do_fwdl called. mptctl_id = %xh.\n" , iocp->name, mptctl_id));
@@ -826,8 +811,6 @@ mptctl_do_fw_download(int ioc, char __us iocp->name, ufwbuf));dctlprintk (iocp,printk (MYIOC_s_DEBUG_FMT"DbG: kfwdl.fwlen = %d\n" , iocp->name, (int )fwlen)); -dctlprintk (iocp,printk (MYIOC_s_DEBUG_FMT"DbG: kfwdl.ioc = %04xh\n" , - iocp->name, ioc)); dlmsg = (FWDownload_t *) mf; ptsge = (FWDownloadTCSGE_t *) &dlmsg->SGL;
@@ -1238,13 +1221,11 @@ kfree_sgl(MptSge_t *sgl, dma_addr_t sgl_* -ENODEV if no such device/adapter */ static int -mptctl_getiocinfo (unsigned long arg,unsigned int data_size) +mptctl_getiocinfo (MPT_ADAPTER *ioc,unsigned long arg,unsigned int data_size) {struct mpt_ioctl_iocinfo __user *uarg = (void __user *) arg;struct mpt_ioctl_iocinfo *karg; -MPT_ADAPTER *ioc;struct pci_dev *pdev; -int iocnum;unsigned int port;int cim_rev;struct scsi_device *sdev;
@@ -1272,14 +1253,6 @@ mptctl_getiocinfo (unsigned long arg, unreturn PTR_ERR (karg); } -if (((iocnum =mpt_verify_adapter (karg->hdr.iocnum, &ioc)) <0 ) || - (ioc ==NULL )) { - printk(KERN_DEBUG MYNAM "%s::mptctl_getiocinfo() @%d - ioc%d not found!\n", - __FILE__, __LINE__, iocnum); -kfree (karg); -return -ENODEV ; - } -/* Verify the data transfer size is correct. */ if (karg->hdr.maxDataSize != data_size) { printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_getiocinfo - "
@@ -1385,15 +1358,13 @@ mptctl_getiocinfo (unsigned long arg, un* -ENODEV if no such device/adapter */ static int -mptctl_gettargetinfo (unsigned long arg) +mptctl_gettargetinfo (MPT_ADAPTER *ioc,unsigned long arg) {struct mpt_ioctl_targetinfo __user *uarg = (void __user *) arg;struct mpt_ioctl_targetinfo karg; -MPT_ADAPTER *ioc;VirtDevice *vdevice;char *pmem;int *pdata; -int iocnum;int numDevices =0 ;int lun;int maxWordsLeft;
@@ -1408,13 +1379,6 @@ mptctl_gettargetinfo (unsigned long arg)return -EFAULT ; } -if (((iocnum =mpt_verify_adapter (karg.hdr.iocnum, &ioc)) <0 ) || - (ioc ==NULL )) { - printk(KERN_DEBUG MYNAM "%s::mptctl_gettargetinfo() @%d - ioc%d not found!\n", - __FILE__, __LINE__, iocnum); -return -ENODEV ; - } -dctlprintk (ioc,printk (MYIOC_s_DEBUG_FMT"mptctl_gettargetinfo called.\n" , ioc->name));/* Get the port number and set the maximum number of bytes
@@ -1510,12 +1474,10 @@ mptctl_gettargetinfo (unsigned long arg)* -ENODEV if no such device/adapter */ static int -mptctl_readtest (unsigned long arg) +mptctl_readtest (MPT_ADAPTER *ioc,unsigned long arg) {struct mpt_ioctl_test __user *uarg = (void __user *) arg;struct mpt_ioctl_test karg; -MPT_ADAPTER *ioc; -int iocnum;if (copy_from_user (&karg, uarg,sizeof (struct mpt_ioctl_test ))) { printk(KERN_ERR MYNAM "%s@%d::mptctl_readtest - "
@@ -1524,13 +1486,6 @@ mptctl_readtest (unsigned long arg)return -EFAULT ; } -if (((iocnum =mpt_verify_adapter (karg.hdr.iocnum, &ioc)) <0 ) || - (ioc ==NULL )) { - printk(KERN_DEBUG MYNAM "%s::mptctl_readtest() @%d - ioc%d not found!\n", - __FILE__, __LINE__, iocnum); -return -ENODEV ; - } -dctlprintk (ioc,printk (MYIOC_s_DEBUG_FMT"mptctl_readtest called.\n" , ioc->name));/* Fill in the data and return the structure to the calling
@@ -1571,12 +1526,10 @@ mptctl_readtest (unsigned long arg)* -ENODEV if no such device/adapter */ static int -mptctl_eventquery (unsigned long arg) +mptctl_eventquery (MPT_ADAPTER *ioc,unsigned long arg) {struct mpt_ioctl_eventquery __user *uarg = (void __user *) arg;struct mpt_ioctl_eventquery karg; -MPT_ADAPTER *ioc; -int iocnum;if (copy_from_user (&karg, uarg,sizeof (struct mpt_ioctl_eventquery ))) { printk(KERN_ERR MYNAM "%s@%d::mptctl_eventquery - "
@@ -1585,13 +1538,6 @@ mptctl_eventquery (unsigned long arg)return -EFAULT ; } -if (((iocnum =mpt_verify_adapter (karg.hdr.iocnum, &ioc)) <0 ) || - (ioc ==NULL )) { - printk(KERN_DEBUG MYNAM "%s::mptctl_eventquery() @%d - ioc%d not found!\n", - __FILE__, __LINE__, iocnum); -return -ENODEV ; - } -dctlprintk (ioc,printk (MYIOC_s_DEBUG_FMT"mptctl_eventquery called.\n" , ioc->name)); karg.eventEntries =MPTCTL_EVENT_LOG_SIZE ;
@@ -1610,12 +1556,10 @@ mptctl_eventquery (unsigned long arg)/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ static int -mptctl_eventenable (unsigned long arg) +mptctl_eventenable (MPT_ADAPTER *ioc,unsigned long arg) {struct mpt_ioctl_eventenable __user *uarg = (void __user *) arg;struct mpt_ioctl_eventenable karg; -MPT_ADAPTER *ioc; -int iocnum;if (copy_from_user (&karg, uarg,sizeof (struct mpt_ioctl_eventenable ))) { printk(KERN_ERR MYNAM "%s@%d::mptctl_eventenable - "
@@ -1624,13 +1568,6 @@ mptctl_eventenable (unsigned long arg)return -EFAULT ; } -if (((iocnum =mpt_verify_adapter (karg.hdr.iocnum, &ioc)) <0 ) || - (ioc ==NULL )) { - printk(KERN_DEBUG MYNAM "%s::mptctl_eventenable() @%d - ioc%d not found!\n", - __FILE__, __LINE__, iocnum); -return -ENODEV ; - } -dctlprintk (ioc,printk (MYIOC_s_DEBUG_FMT"mptctl_eventenable called.\n" , ioc->name));if (ioc->events ==NULL ) {
@@ -1658,12 +1595,10 @@ mptctl_eventenable (unsigned long arg)/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ static int -mptctl_eventreport (unsigned long arg) +mptctl_eventreport (MPT_ADAPTER *ioc,unsigned long arg) {struct mpt_ioctl_eventreport __user *uarg = (void __user *) arg;struct mpt_ioctl_eventreport karg; -MPT_ADAPTER *ioc; -int iocnum;int numBytes, maxEvents, max;if (copy_from_user (&karg, uarg,sizeof (struct mpt_ioctl_eventreport ))) {
@@ -1673,12 +1608,6 @@ mptctl_eventreport (unsigned long arg)return -EFAULT ; } -if (((iocnum =mpt_verify_adapter (karg.hdr.iocnum, &ioc)) <0 ) || - (ioc ==NULL )) { - printk(KERN_DEBUG MYNAM "%s::mptctl_eventreport() @%d - ioc%d not found!\n", - __FILE__, __LINE__, iocnum); -return -ENODEV ; - }dctlprintk (ioc,printk (MYIOC_s_DEBUG_FMT"mptctl_eventreport called.\n" , ioc->name));
@@ -1712,12 +1641,10 @@ mptctl_eventreport (unsigned long arg)/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ static int -mptctl_replace_fw (unsigned long arg) +mptctl_replace_fw (MPT_ADAPTER *ioc,unsigned long arg) {struct mpt_ioctl_replace_fw __user *uarg = (void __user *) arg;struct mpt_ioctl_replace_fw karg; -MPT_ADAPTER *ioc; -int iocnum;int newFwSize;if (copy_from_user (&karg, uarg,sizeof (struct mpt_ioctl_replace_fw ))) {
@@ -1727,13 +1654,6 @@ mptctl_replace_fw (unsigned long arg)return -EFAULT ; } -if (((iocnum =mpt_verify_adapter (karg.hdr.iocnum, &ioc)) <0 ) || - (ioc ==NULL )) { - printk(KERN_DEBUG MYNAM "%s::mptctl_replace_fw() @%d - ioc%d not found!\n", - __FILE__, __LINE__, iocnum); -return -ENODEV ; - } -dctlprintk (ioc,printk (MYIOC_s_DEBUG_FMT"mptctl_replace_fw called.\n" , ioc->name));/* If caching FW, Free the old FW image
@@ -1780,12 +1700,10 @@ mptctl_replace_fw (unsigned long arg)* -ENOMEM if memory allocation error */ static int -mptctl_mpt_command (unsigned long arg) +mptctl_mpt_command (MPT_ADAPTER *ioc,unsigned long arg) {struct mpt_ioctl_command __user *uarg = (void __user *) arg;struct mpt_ioctl_command karg; -MPT_ADAPTER *ioc; -int iocnum;int rc;
@@ -1796,14 +1714,7 @@ mptctl_mpt_command (unsigned long arg)return -EFAULT ; } -if (((iocnum =mpt_verify_adapter (karg.hdr.iocnum, &ioc)) <0 ) || - (ioc ==NULL )) { - printk(KERN_DEBUG MYNAM "%s::mptctl_mpt_command() @%d - ioc%d not found!\n", - __FILE__, __LINE__, iocnum); -return -ENODEV ; - } - - rc =mptctl_do_mpt_command (karg, &uarg->MF); + rc =mptctl_do_mpt_command (ioc, karg, &uarg->MF);return rc; }
@@ -1821,9 +1732,8 @@ mptctl_mpt_command (unsigned long arg)* -EPERM if SCSI I/O and target is untagged */ static int -mptctl_do_mpt_command (struct mpt_ioctl_command karg,void __user *mfPtr) +mptctl_do_mpt_command (MPT_ADAPTER *ioc,struct mpt_ioctl_command karg,void __user *mfPtr) { -MPT_ADAPTER *ioc;MPT_FRAME_HDR *mf =NULL ;MPIHeader_t *hdr;char *psge;
@@ -1832,7 +1742,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_dma_addr_t dma_addr_in;dma_addr_t dma_addr_out;int sgSize =0 ;/* Num SG elements */ -int iocnum, flagsLength; +int flagsLength;int sz, rc =0 ;int msgContext;u16 req_idx;
@@ -1847,13 +1757,6 @@ mptctl_do_mpt_command (struct mpt_ioctl_ bufIn.kptr = bufOut.kptr =NULL ; bufIn.len = bufOut.len =0 ; -if (((iocnum =mpt_verify_adapter (karg.hdr.iocnum, &ioc)) <0 ) || - (ioc ==NULL )) { - printk(KERN_DEBUG MYNAM "%s::mptctl_do_mpt_command() @%d - ioc%d not found!\n", - __FILE__, __LINE__, iocnum); -return -ENODEV ; - } -spin_lock_irqsave (&ioc->taskmgmt_lock, flags);if (ioc->ioc_reset_in_progress) {spin_unlock_irqrestore (&ioc->taskmgmt_lock, flags);
@@ -2418,17 +2321,15 @@ done_free_mem:* -ENOMEM if memory allocation error */ static int -mptctl_hp_hostinfo (unsigned long arg,unsigned int data_size) +mptctl_hp_hostinfo (MPT_ADAPTER *ioc,unsigned long arg,unsigned int data_size) {hp_host_info_t __user *uarg = (void __user *) arg; -MPT_ADAPTER *ioc;struct pci_dev *pdev;char *pbuf=NULL ;dma_addr_t buf_dma;hp_host_info_t karg;CONFIGPARMS cfg;ConfigPageHeader_t hdr; -int iocnum;int rc, cim_rev;ToolboxIstwiReadWriteRequest_t *IstwiRWRequest;MPT_FRAME_HDR *mf =NULL ;
@@ -2452,12 +2353,6 @@ mptctl_hp_hostinfo(unsigned long arg, unreturn -EFAULT ; } -if (((iocnum =mpt_verify_adapter (karg.hdr.iocnum, &ioc)) <0 ) || - (ioc ==NULL )) { - printk(KERN_DEBUG MYNAM "%s::mptctl_hp_hostinfo() @%d - ioc%d not found!\n", - __FILE__, __LINE__, iocnum); -return -ENODEV ; - }dctlprintk (ioc,printk (MYIOC_s_DEBUG_FMT": mptctl_hp_hostinfo called.\n" , ioc->name));
@@ -2659,15 +2554,13 @@ retry_wait:* -ENOMEM if memory allocation error */ static int -mptctl_hp_targetinfo (unsigned long arg) +mptctl_hp_targetinfo (MPT_ADAPTER *ioc,unsigned long arg) {hp_target_info_t __user *uarg = (void __user *) arg;SCSIDevicePage0_t *pg0_alloc;SCSIDevicePage3_t *pg3_alloc; -MPT_ADAPTER *ioc;MPT_SCSI_HOST *hd =NULL ;hp_target_info_t karg; -int iocnum;int data_sz;dma_addr_t page_dma;CONFIGPARMS cfg;
@@ -2681,12 +2574,6 @@ mptctl_hp_targetinfo(unsigned long arg)return -EFAULT ; } -if (((iocnum =mpt_verify_adapter (karg.hdr.iocnum, &ioc)) <0 ) || - (ioc ==NULL )) { - printk(KERN_DEBUG MYNAM "%s::mptctl_hp_targetinfo() @%d - ioc%d not found!\n", - __FILE__, __LINE__, iocnum); -return -ENODEV ; - }if (karg.hdr.id >=MPT_MAX_FC_DEVICES )return -EINVAL ; dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_hp_targetinfo called.\n",
@@ -2854,7 +2741,7 @@ compat_mptfwxfer_ioctl(struct file *filp kfw.fwlen = kfw32.fwlen; kfw.bufp =compat_ptr (kfw32.bufp); - ret =mptctl_do_fw_download (kfw.iocnum, kfw.bufp, kfw.fwlen); + ret =mptctl_do_fw_download (iocp, kfw.bufp, kfw.fwlen);mutex_unlock (&iocp->ioctl_cmds.mutex);
@@ -2908,7 +2795,7 @@ compat_mpt_command(struct file *filp, un/* Pass new structure to do_mpt_command */ - ret =mptctl_do_mpt_command (karg, &uarg->MF); + ret =mptctl_do_mpt_command (iocp, karg, &uarg->MF);mutex_unlock (&iocp->ioctl_cmds.mutex);
Greg Kroah-Hartman
maintainerPATCH 57/222 ptrace: reintroduce usage of subjective credentials in ptrace_has_cap()
In reply to Greg Kroah-HartmanFrom: Christian Brauner <[email protected]>
commit 6b3ad6649a4c75504edeba242d3fd36b3096a57f upstream.
Commit 69f594a38967 ("ptrace: do not audit capability check when outputing /proc/pid/stat") introduced the ability to opt out of audit messages for accesses to various proc files since they are not violations of policy. While doing so it somehow switched the check from ns_capable() to has_ns_capability{_noaudit}(). That means it switched from checking the subjective credentials of the task to using the objective credentials. This is wrong since. ptrace_has_cap() is currently only used in ptrace_may_access() And is used to check whether the calling task (subject) has the CAP_SYS_PTRACE capability in the provided user namespace to operate on the target task (object). According to the cred.h comments this would mean the subjective credentials of the calling task need to be used.
This switches ptrace_has_cap() to use security_capable(). Because we only call ptrace_has_cap() in ptrace_may_access() and in there we already have a stable reference to the calling task's creds under rcu_read_lock() there's no need to go through another series of dereferences and rcu locking done
in ns_capable{_noaudit}().
As one example where this might be particularly problematic, Jann pointed out that in combination with the upcoming IORING_OP_OPENAT feature, this bug might allow unprivileged users to bypass the capability checks while asynchronously opening files like /proc/*/mem, because the capability checks for this would be performed against kernel credentials.
To illustrate on the former point about this being exploitable: When io_uring creates a new context it records the subjective credentials of the caller. Later on, when it starts to do work it creates a kernel thread and registers a callback. The callback runs with kernel creds for ktask->real_cred and ktask->cred. To prevent this from becoming a full-blown 0-day io_uring will call override_cred() and override ktask->cred with the subjective credentials of the creator of the io_uring instance. With ptrace_has_cap() currently looking at ktask->real_cred this override will be ineffective and the caller will be able to open arbitray proc files as mentioned above.
Luckily, this is currently not exploitable but will turn into a 0-day once IORING_OP_OPENAT{2} land in v5.6. Fix it now!
--- kernel/ptrace.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
kernel/ptrace.c +10 -5
@@ -264,12 +264,17 @@ static int ptrace_check_attach(struct tareturn ret; } -static int ptrace_has_cap (struct user_namespace *ns,unsigned int mode) +static bool ptrace_has_cap (const struct cred *cred,struct user_namespace *ns, +unsigned int mode) { +int ret; +if (mode &PTRACE_MODE_NOAUDIT ) -return has_ns_capability_noaudit (current, ns,CAP_SYS_PTRACE ); + ret =security_capable (cred, ns,CAP_SYS_PTRACE ,CAP_OPT_NOAUDIT );else -return has_ns_capability (current, ns,CAP_SYS_PTRACE ); + ret =security_capable (cred, ns,CAP_SYS_PTRACE ,CAP_OPT_NONE ); + +return ret ==0 ; }/* Returns 0 on success, -errno on denial. */
@@ -321,7 +326,7 @@ static int __ptrace_may_access(struct ta gid_eq(caller_gid, tcred->sgid) && gid_eq(caller_gid, tcred->gid)) goto ok; -if (ptrace_has_cap (tcred->user_ns, mode)) +if (ptrace_has_cap (cred, tcred->user_ns, mode)) goto ok;rcu_read_unlock ();return -EPERM ;
@@ -340,7 +345,7 @@ ok: mm = task->mm;if (mm && ((get_dumpable (mm) !=SUID_DUMP_USER ) && - !ptrace_has_cap (mm->user_ns, mode))) + !ptrace_has_cap (cred, mm->user_ns, mode)))return -EPERM ;return security_ptrace_access_check (task, mode);
Greg Kroah-Hartman
maintainerPATCH 58/222 mtd: rawnand: gpmi: Fix suspend/resume problem
In reply to Greg Kroah-HartmanFrom: Esben Haabendal <[email protected]>
commit 5bc6bb603b4d0c8802af75e4932232683ab2d761 upstream.
On system resume, the gpmi clock must be enabled before accessing gpmi block. Without this, resume causes something like
[ 661.348790] gpmi_reset_block(5cbb0f7e): module reset timeout [ 661.348889] gpmi-nand 1806000.gpmi-nand: Error setting GPMI : -110 [ 661.348928] PM: dpm_run_callback(): platform_pm_resume+0x0/0x44 returns -110 [ 661.348961] PM: Device 1806000.gpmi-nand failed to resume: error -110
--- drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c +6 -1
@@ -148,6 +148,10 @@ static int gpmi_init(struct gpmi_nand_dastruct resources *r = &this->resources;int ret; + ret =pm_runtime_get_sync (this->dev); +if (ret <0 ) +return ret; + ret =gpmi_reset_block (r->gpmi_regs, false);if (ret) goto err_out;
@@ -179,8 +183,9 @@ static int gpmi_init(struct gpmi_nand_da*/ writel (BM_GPMI_CTRL1_DECOUPLE_CS , r->gpmi_regs +HW_GPMI_CTRL1_SET ); -return 0 ; err_out: +pm_runtime_mark_last_busy (this->dev); +pm_runtime_put_autosuspend (this->dev);return ret; }
Greg Kroah-Hartman
maintainerPATCH 59/222 mtd: rawnand: gpmi: Restore nfc timing setup after suspend/resume
In reply to Greg Kroah-HartmanFrom: Esben Haabendal <[email protected]>
commit d70486668cdf51b14a50425ab45fc18677a167b2 upstream.
As we reset the GPMI block at resume, the timing parameters setup by a previous exec_op is lost. Rewriting GPMI timing registers on first exec_op after resume fixes the problem.
--- drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c +4 -0
@@ -2727,6 +2727,10 @@ static int gpmi_pm_resume(struct devicereturn ret; } +/* Set flag to get timing setup restored for next exec_op */ +if (this->hw.clk_rate) + this->hw.must_apply_timings = true; +/* re-init the BCH registers */ ret =bch_set_geometry (this);if (ret) {
Greg Kroah-Hartman
maintainerPATCH 60/222 usb: core: hub: Improved device recognition on remote wakeup
In reply to Greg Kroah-HartmanFrom: Keiya Nobuta <[email protected]>
commit 9c06ac4c83df6d6fbdbf7488fbad822b4002ba19 upstream.
If hub_activate() is called before D+ has stabilized after remote wakeup, the following situation might occur:
__ ___________________
/ \ /D+ __/ \__/
Hub _______________________________
| ^ ^ ^
| | | |
Host _____v__|___|___________|______
| | | |
| | | \-- Interrupt Transfer (*3)
| | \-- ClearPortFeature (*2) | \-- GetPortStatus (*1)
\-- Host detects remote wakeup
- D+ goes high, Host starts running by remote wakeup
- D+ is not stable, goes low
- Host requests GetPortStatus at (*1) and gets the following hub status:
- Current Connect Status bit is 0
- Connect Status Change bit is 1
- D+ stabilizes, goes high
- Host requests ClearPortFeature and thus Connect Status Change bit is cleared at (*2)
- After waiting 100 ms, Host starts the Interrupt Transfer at (*3)
- Since the Connect Status Change bit is 0, Hub returns NAK.
In this case, port_event() is not called in hub_event() and Host cannot recognize device. To solve this issue, flag change_bits even if only Connect Status Change bit is 1 when got in the first GetPortStatus.
This issue occurs rarely because it only if D+ changes during a very short time between GetPortStatus and ClearPortFeature. However, it is fatal if it occurs in embedded system.
--- drivers/usb/core/hub.c | 1 + 1 file changed, 1 insertion(+)
drivers/usb/core/hub.c +1 -0
@@ -1191,6 +1191,7 @@ static void hub_activate(struct usb_hub* PORT_OVER_CURRENT is not. So check for any of them. */ if (udev || (portstatus &USB_PORT_STAT_CONNECTION ) || + (portchange &USB_PORT_STAT_C_CONNECTION ) || (portstatus &USB_PORT_STAT_OVERCURRENT ) || (portchange &USB_PORT_STAT_C_OVERCURRENT ))set_bit (port1, hub->change_bits);
Greg Kroah-Hartman
maintainerPATCH 61/222 cpu/SMT: Fix x86 link error without CONFIG_SYSFS
In reply to Greg Kroah-HartmanFrom: Arnd Bergmann <[email protected]>
commit dc8d37ed304eeeea47e65fb9edc1c6c8b0093386 upstream.
When CONFIG_SYSFS is disabled, but CONFIG_HOTPLUG_SMT is enabled, the kernel fails to link:
arch/x86/power/cpu.o: In function `hibernate_resume_nonboot_cpu_disable':
(.text+0x38d): undefined reference to cpuhp_smt_enable' arch/x86/power/hibernate.o: In function arch_resume_nosmt':
hibernate.c:(.text+0x291): undefined reference to cpuhp_smt_enable' hibernate.c:(.text+0x29c): undefined reference to cpuhp_smt_disable'
Move the exported functions out of the #ifdef section into its own with the correct conditions.
The patch that caused this is marked for stable backports, so this one may need to be backported as well.
--- kernel/cpu.c | 143 +++++++++++++++++++++++++++++------------------------------ 1 file changed, 72 insertions(+), 71 deletions(-)
kernel/cpu.c +72 -71
@@ -1909,6 +1909,78 @@ void __cpuhp_remove_state(enum cpuhp_sta }EXPORT_SYMBOL (__cpuhp_remove_state); +#ifdef CONFIG_HOTPLUG_SMT +static void cpuhp_offline_cpu_device (unsigned int cpu) +{ +struct device *dev =get_cpu_device (cpu); + + dev->offline = true; +/* Tell user space about the state change */ +kobject_uevent (&dev->kobj,KOBJ_OFFLINE ); +} + +static void cpuhp_online_cpu_device (unsigned int cpu) +{ +struct device *dev =get_cpu_device (cpu); + + dev->offline = false; +/* Tell user space about the state change */ +kobject_uevent (&dev->kobj,KOBJ_ONLINE ); +} + +int cpuhp_smt_disable (enum cpuhp_smt_control ctrlval) +{ +int cpu, ret =0 ; + +cpu_maps_update_begin (); +for_each_online_cpu (cpu) { +if (topology_is_primary_thread (cpu)) +continue ; + ret =cpu_down_maps_locked (cpu,CPUHP_OFFLINE ); +if (ret) +break ; +/* +* As this needs to hold the cpu maps lock it's impossible +* to call device_offline() because that ends up calling +* cpu_down() which takes cpu maps lock. cpu maps lock +* needs to be held as this might race against in kernel +* abusers of the hotplug machinery (thermal management). +* +* So nothing would update device:offline state. That would +* leave the sysfs entry stale and prevent onlining after +* smt control has been changed to 'off' again. This is +* called under the sysfs hotplug lock, so it is properly +* serialized against the regular offline usage. +*/ +cpuhp_offline_cpu_device (cpu); + } +if (!ret) + cpu_smt_control = ctrlval; +cpu_maps_update_done (); +return ret; +} + +int cpuhp_smt_enable (void ) +{ +int cpu, ret =0 ; + +cpu_maps_update_begin (); + cpu_smt_control =CPU_SMT_ENABLED ; +for_each_present_cpu (cpu) { +/* Skip online CPUs and CPUs on offline nodes */ +if (cpu_online (cpu) || !node_online (cpu_to_node (cpu))) +continue ; + ret =_cpu_up (cpu,0 ,CPUHP_ONLINE ); +if (ret) +break ; +/* See comment in cpuhp_smt_disable() */ +cpuhp_online_cpu_device (cpu); + } +cpu_maps_update_done (); +return ret; +} +#endif +#if defined(CONFIG_SYSFS ) && defined(CONFIG_HOTPLUG_CPU )static ssize_t show_cpuhp_state (struct device *dev,struct device_attribute *attr,char *buf)
@@ -2063,77 +2135,6 @@ static const struct attribute_group cpuh#ifdef CONFIG_HOTPLUG_SMT -static void cpuhp_offline_cpu_device (unsigned int cpu) -{ -struct device *dev =get_cpu_device (cpu); - - dev->offline = true; -/* Tell user space about the state change */ -kobject_uevent (&dev->kobj,KOBJ_OFFLINE ); -} - -static void cpuhp_online_cpu_device (unsigned int cpu) -{ -struct device *dev =get_cpu_device (cpu); - - dev->offline = false; -/* Tell user space about the state change */ -kobject_uevent (&dev->kobj,KOBJ_ONLINE ); -} - -int cpuhp_smt_disable (enum cpuhp_smt_control ctrlval) -{ -int cpu, ret =0 ; - -cpu_maps_update_begin (); -for_each_online_cpu (cpu) { -if (topology_is_primary_thread (cpu)) -continue ; - ret =cpu_down_maps_locked (cpu,CPUHP_OFFLINE ); -if (ret) -break ; -/* -* As this needs to hold the cpu maps lock it's impossible -* to call device_offline() because that ends up calling -* cpu_down() which takes cpu maps lock. cpu maps lock -* needs to be held as this might race against in kernel -* abusers of the hotplug machinery (thermal management). -* -* So nothing would update device:offline state. That would -* leave the sysfs entry stale and prevent onlining after -* smt control has been changed to 'off' again. This is -* called under the sysfs hotplug lock, so it is properly -* serialized against the regular offline usage. -*/ -cpuhp_offline_cpu_device (cpu); - } -if (!ret) - cpu_smt_control = ctrlval; -cpu_maps_update_done (); -return ret; -} - -int cpuhp_smt_enable (void ) -{ -int cpu, ret =0 ; - -cpu_maps_update_begin (); - cpu_smt_control =CPU_SMT_ENABLED ; -for_each_present_cpu (cpu) { -/* Skip online CPUs and CPUs on offline nodes */ -if (cpu_online (cpu) || !node_online (cpu_to_node (cpu))) -continue ; - ret =_cpu_up (cpu,0 ,CPUHP_ONLINE ); -if (ret) -break ; -/* See comment in cpuhp_smt_disable() */ -cpuhp_online_cpu_device (cpu); - } -cpu_maps_update_done (); -return ret; -} - -static ssize_t __store_smt_control (struct device *dev,struct device_attribute *attr,const char *buf,size_t count)
Greg Kroah-Hartman
maintainerPATCH 62/222 x86/resctrl: Fix an imbalance in domain_remove_cpu()
In reply to Greg Kroah-HartmanFrom: Qian Cai <[email protected]>
commit e278af89f1ba0a9ef20947db6afc2c9afa37e85b upstream.
A system that supports resource monitoring may have multiple resources while not all of these resources are capable of monitoring. Monitoring related state is initialized only for resources that are capable of monitoring and correspondingly this state should subsequently only be removed from these resources that are capable of monitoring.
domain_add_cpu() calls domain_setup_mon_state() only when r->mon_capable is true where it will initialize d->mbm_over. However, domain_remove_cpu() calls cancel_delayed_work(&d->mbm_over) without checking r->mon_capable resulting in an attempt to cancel d->mbm_over on all resources, even those that never initialized d->mbm_over because they are not capable of monitoring. Hence, it triggers a debugobjects warning when offlining CPUs because those timer debugobjects are never initialized:
ODEBUG: assert_init not available (active state 0) object type:
timer_list hint: 0x0
WARNING: CPU: 143 PID: 789 at lib/debugobjects.c:484 debug_print_object Hardware name: HP Synergy 680 Gen9/Synergy 680 Gen9 Compute Module, BIOS I40 05/23/2018 RIP: 0010:debug_print_object Call Trace: debug_object_assert_init del_timer try_to_grab_pending cancel_delayed_work resctrl_offline_cpu cpuhp_invoke_callback cpuhp_thread_fun smpboot_thread_fn kthread ret_from_fork
--- arch/x86/kernel/cpu/resctrl/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kernel/cpu/resctrl/core.c +1 -1
@@ -618,7 +618,7 @@ static void domain_remove_cpu(int cpu, sif (static_branch_unlikely (&rdt_mon_enable_key))rmdir_mondata_subdir_allrdtgrp (r, d->id);list_del (&d->list); -if (is_mbm_enabled ()) +if (r->mon_capable &&is_mbm_enabled ())cancel_delayed_work (&d->mbm_over);if (is_llc_occupancy_enabled () &&has_busy_rmid (r, d)) {/*
Greg Kroah-Hartman
maintainerPATCH 63/222 x86/CPU/AMD: Ensure clearing of SME/SEV features is maintained
In reply to Greg Kroah-HartmanFrom: Tom Lendacky <[email protected]>
commit a006483b2f97af685f0e60f3a547c9ad4c9b9e94 upstream.
If the SME and SEV features are present via CPUID, but memory encryption support is not enabled (MSR 0xC001_0010[23]), the feature flags are cleared using clear_cpu_cap(). However, if get_cpu_cap() is later called, these feature flags will be reset back to present, which is not desired.
Change from using clear_cpu_cap() to setup_clear_cpu_cap() so that the clearing of the flags is maintained.
--- arch/x86/kernel/cpu/amd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/x86/kernel/cpu/amd.c +2 -2
@@ -615,9 +615,9 @@ static void early_detect_mem_encrypt(strreturn ; clear_all: -clear_cpu_cap (c,X86_FEATURE_SME ); +setup_clear_cpu_cap (X86_FEATURE_SME ); clear_sev: -clear_cpu_cap (c,X86_FEATURE_SEV ); +setup_clear_cpu_cap (X86_FEATURE_SEV ); } }
Greg Kroah-Hartman
maintainerPATCH 64/222 locking/rwsem: Fix kernel crash when spinning on RWSEM_OWNER_UNKNOWN
In reply to Greg Kroah-HartmanFrom: Waiman Long <[email protected]>
commit 39e7234f00bc93613c086ae42d852d5f4147120a upstream.
The commit 91d2a812dfb9 ("locking/rwsem: Make handoff writer optimistically spin on owner") will allow a recently woken up waiting writer to spin on the owner. Unfortunately, if the owner happens to be RWSEM_OWNER_UNKNOWN, the code will incorrectly spin on it leading to a kernel crash. This is fixed by passing the proper non-spinnable bits to rwsem_spin_on_owner() so that RWSEM_OWNER_UNKNOWN will be treated as a non-spinnable target.
--- kernel/locking/rwsem.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/locking/rwsem.c +2 -2
@@ -1226,8 +1226,8 @@ wait:* In this case, we attempt to acquire the lock again * without sleeping. */ -if ((wstate ==WRITER_HANDOFF ) && - (rwsem_spin_on_owner (sem,0 ) ==OWNER_NULL )) +if (wstate ==WRITER_HANDOFF && +rwsem_spin_on_owner (sem,RWSEM_NONSPINNABLE ) ==OWNER_NULL ) goto trylock_again;/* Block until there are no active lockers. */
Greg Kroah-Hartman
maintainerPATCH 65/222 perf/x86/intel/uncore: Fix missing marker for snr_uncore_imc_freerunning_events
In reply to Greg Kroah-HartmanFrom: Kan Liang <[email protected]>
commit fa694ae532836bd2f4cd659e9b4032abaf9fa9e5 upstream.
An Oops during the boot is found on some SNR machines. It turns out this is because the snr_uncore_imc_freerunning_events[] array was missing an end-marker.
--- arch/x86/events/intel/uncore_snbep.c | 1 + 1 file changed, 1 insertion(+)
arch/x86/events/intel/uncore_snbep.c +1 -0
@@ -4536,6 +4536,7 @@ static struct uncore_event_desc snr_uncoINTEL_UNCORE_EVENT_DESC (write,"event=0xff,umask=0x21" ),INTEL_UNCORE_EVENT_DESC (write.scale,"3.814697266e-6" ), INTEL_UNCORE_EVENT_DESC(write.unit, "MiB"), + { /* end: all zeroes */ }, }; static struct intel_uncore_ops snr_uncore_imc_freerunning_ops = {
Greg Kroah-Hartman
maintainerPATCH 66/222 x86/efistub: Disable paging at mixed mode entry
In reply to Greg Kroah-HartmanFrom: Ard Biesheuvel <[email protected]>
commit 4911ee401b7ceff8f38e0ac597cbf503d71e690c upstream.
The EFI mixed mode entry code goes through the ordinary startup_32() routine before jumping into the kernel's EFI boot code in 64-bit mode. The 32-bit startup code must be entered with paging disabled, but this is not documented as a requirement for the EFI handover protocol, and so we should disable paging explicitly when entering the kernel from 32-bit EFI firmware.
--- arch/x86/boot/compressed/head_64.S | 5 +++++ 1 file changed, 5 insertions(+)
arch/x86/boot/compressed/head_64.S +5 -0
@@ -244,6 +244,11 @@ ENTRY(efi32_stub_entry) leal efi32_config(%ebp), %eax movl %eax, efi_config(%ebp) + /* Disable paging */ + movl %cr0, %eax + btrl $X86_CR0_PG_BIT, %eax + movl %eax, %cr0 + jmp startup_32 ENDPROC(efi32_stub_entry) #endif
Greg Kroah-Hartman
maintainerPATCH 67/222 s390/zcrypt: Fix CCA cipher key gen with clear key value function
In reply to Greg Kroah-HartmanFrom: Harald Freudenberger <[email protected]>
commit 94dd3bada53ee77b80d0aeee5571eeb83654d156 upstream.
Regression tests showed that the CCA cipher key function which generates an CCA cipher key with given clear key value does not work correctly. At parsing the reply CPRB two limits are wrong calculated resulting in rejecting the reply as invalid with s390dbf message "_ip_cprb_helper reply with invalid or unknown key block".
--- drivers/s390/crypto/zcrypt_ccamisc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/s390/crypto/zcrypt_ccamisc.c +2 -2
@@ -1037,8 +1037,8 @@ static int _ip_cprb_helper(u16 cardnr, u prepparm = (struct iprepparm *) prepcblk->rpl_parmb;/* do some plausibility checks on the key block */ -if (prepparm->kb.len <120 +5 *sizeof (uint16_t ) || - prepparm->kb.len >136 +5 *sizeof (uint16_t )) { +if (prepparm->kb.len <120 +3 *sizeof (uint16_t ) || + prepparm->kb.len >136 +3 *sizeof (uint16_t )) {DEBUG_ERR ("%s reply with invalid or unknown key block\n" , __func__); rc = -EIO ;
Greg Kroah-Hartman
maintainerPATCH 68/222 scsi: storvsc: Correctly set number of hardware queues for IDE disk
In reply to Greg Kroah-HartmanFrom: Long Li <[email protected]>
commit 7b571c19d4c0b78d27dd3bf1f3c42e4032390af6 upstream.
Commit 0ed881027690 ("scsi: storvsc: setup 1:1 mapping between hardware queue and CPU queue") introduced a regression for disks attached to IDE. For these disks the host VSP only offers one VMBUS channel. Setting multiple queues can overload the VMBUS channel and result in performance drop for high queue depth workload on system with large number of CPUs.
Fix it by leaving the number of hardware queues to 1 (default value) for IDE disks.
--- drivers/scsi/storvsc_drv.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/scsi/storvsc_drv.c +3 -1
@@ -1835,9 +1835,11 @@ static int storvsc_probe(struct hv_devic*/ host->sg_tablesize = (stor_device->max_transfer_bytes >>PAGE_SHIFT );/* +* For non-IDE disks, the host supports multiple channels. * Set the number of HW queues we are supporting. */ - host->nr_hw_queues =num_present_cpus (); +if (!dev_is_ide) + host->nr_hw_queues =num_present_cpus ();/* * Set the error handler work queue.
Greg Kroah-Hartman
maintainerPATCH 69/222 mtd: spi-nor: Fix selection of 4-byte addressing opcodes on Spansion
In reply to Greg Kroah-HartmanFrom: Vignesh Raghavendra <[email protected]>
commit 440b6d50254bdbd84c2a665c7f53ec69dd741a4f upstream.
mtd->size is still unassigned when running spansion_post_sfdp_fixups() hook, therefore use nor->params.size to determine the size of flash device.
This makes sure that 4-byte addressing opcodes are used on Spansion flashes that are larger than 16MiB and don't have SFDP 4BAIT table populated.
--- drivers/mtd/spi-nor/spi-nor.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/mtd/spi-nor/spi-nor.c +1 -3
@@ -4544,9 +4544,7 @@ static void spi_nor_info_init_params(strstatic void spansion_post_sfdp_fixups (struct spi_nor *nor) { -struct mtd_info *mtd = &nor->mtd; - -if (mtd->size <=SZ_16M ) +if (nor->params.size <=SZ_16M )return ; nor->flags |=SNOR_F_4B_OPCODES ;
Greg Kroah-Hartman
maintainerPATCH 70/222 drm/i915: Add missing include file <linux/math64.h>
In reply to Greg Kroah-HartmanFrom: YueHaibing <[email protected]>
commit ea38aa2ea5b0969776f0a47f174ce928a22be803 upstream.
Fix build error:./drivers/gpu/drm/i915/selftests/i915_random.h: In function i915_prandom_u32_max_state:./drivers/gpu/drm/i915/selftests/i915_random.h:48:23: error:
implicit declaration of function mul_u32_u32; did you mean mul_u64_u32_div? [-Werror=implicit-function-declaration]
return upper_32_bits(mul_u32_u32(prandom_u32_state(state), ep_ro));
--- drivers/gpu/drm/i915/selftests/i915_random.h | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/i915/selftests/i915_random.h +1 -0
@@ -25,6 +25,7 @@#ifndef __I915_SELFTESTS_RANDOM_H__#define __I915_SELFTESTS_RANDOM_H__ +#include <linux/math64.h> #include <linux/random.h> #include "../i915_selftest.h"
Greg Kroah-Hartman
maintainerPATCH 71/222 x86/resctrl: Fix potential memory leak
In reply to Greg Kroah-HartmanFrom: Shakeel Butt <[email protected]>
commit ab6a2114433a3b5b555983dcb9b752a85255f04b upstream.
set_cache_qos_cfg() is leaking memory when the given level is not RDT_RESOURCE_L3 or RDT_RESOURCE_L2. At the moment, this function is called with only valid levels but move the allocation after the valid level checks in order to make it more robust and future proof.
[ bp: Massage commit message. ]
--- arch/x86/kernel/cpu/resctrl/rdtgroup.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
arch/x86/kernel/cpu/resctrl/rdtgroup.c +3 -3
@@ -1741,9 +1741,6 @@ static int set_cache_qos_cfg(int level,struct rdt_domain *d;int cpu; -if (!zalloc_cpumask_var (&cpu_mask,GFP_KERNEL )) -return -ENOMEM ; -if (level ==RDT_RESOURCE_L3 ) update = l3_qos_cfg_update;else if (level ==RDT_RESOURCE_L2 )
@@ -1751,6 +1748,9 @@ static int set_cache_qos_cfg(int level,else return -EINVAL ; +if (!zalloc_cpumask_var (&cpu_mask,GFP_KERNEL )) +return -ENOMEM ; + r_l = &rdt_resources_all[level];list_for_each_entry (d, &r_l->domains, list) {/* Pick one CPU from each domain instance to update MSR */
Greg Kroah-Hartman
maintainerPATCH 72/222 efi/earlycon: Fix write-combine mapping on x86
In reply to Greg Kroah-HartmanFrom: Arvind Sankar <[email protected]>
commit d92b54570d24d017d2630e314b525ed792f5aa6c upstream.
On x86, until PAT is initialized, WC translates into UC-. Since we calculate and store pgprot_writecombine(PAGE_KERNEL) when earlycon is initialized, this means we actually use UC- mappings instead of WC mappings, which makes scrolling very slow.
Instead store a boolean flag to indicate whether we want to use writeback or write-combine mappings, and recalculate the actual pgprot_t we need on every mapping. Once PAT is initialized, we will start using write-combine mappings, which speeds up the scrolling considerably.
--- drivers/firmware/efi/earlycon.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-)
drivers/firmware/efi/earlycon.c +7 -9
@@ -17,7 +17,7 @@ static const struct console *earlycon_costatic const struct font_desc *font;static u32 efi_x, efi_y;static u64 fb_base; -static pgprot_t fb_prot; +static bool fb_wb;static void *efi_fb;/*
@@ -33,10 +33,8 @@ static int __init efi_earlycon_remap_fb(if (!earlycon_console || !(earlycon_console->flags &CON_ENABLED ))return 0 ; -if (pgprot_val (fb_prot) ==pgprot_val (PAGE_KERNEL )) - efi_fb =memremap (fb_base, screen_info.lfb_size,MEMREMAP_WB ); -else - efi_fb =memremap (fb_base, screen_info.lfb_size,MEMREMAP_WC ); + efi_fb =memremap (fb_base, screen_info.lfb_size, + fb_wb ?MEMREMAP_WB :MEMREMAP_WC );return efi_fb ?0 : -ENOMEM ; }
@@ -53,9 +51,12 @@ late_initcall(efi_earlycon_unmap_fb);static __ref void *efi_earlycon_map (unsigned long start,unsigned long len) { +pgprot_t fb_prot; +if (efi_fb)return efi_fb + start; + fb_prot = fb_wb ?PAGE_KERNEL :pgprot_writecombine (PAGE_KERNEL );return early_memremap_prot (fb_base + start, len,pgprot_val (fb_prot)); }
@@ -215,10 +216,7 @@ static int __init efi_earlycon_setup(strif (screen_info.capabilities &VIDEO_CAPABILITY_64BIT_BASE ) fb_base |= (u64 )screen_info.ext_lfb_base <<32 ; -if (opt && !strcmp (opt,"ram" )) - fb_prot =PAGE_KERNEL ; -else - fb_prot =pgprot_writecombine (PAGE_KERNEL ); + fb_wb = opt && !strcmp (opt,"ram" ); si = &screen_info; xres = si->lfb_width;
Greg Kroah-Hartman
maintainerPATCH 73/222 s390/setup: Fix secure ipl message
In reply to Greg Kroah-HartmanFrom: Philipp Rudo <[email protected]>
commit 40260b01d029ba374637838213af500e03305326 upstream.
The new machine loader on z15 always creates an IPL Report block and thus sets the IPL_PL_FLAG_IPLSR even when secure boot is disabled. This causes the wrong message being printed at boot. Fix this by checking for IPL_PL_FLAG_SIPL instead.
--- arch/s390/kernel/setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/s390/kernel/setup.c +1 -1
@@ -1059,7 +1059,7 @@ static void __init log_component_list(voif (!early_ipl_comp_list_addr)return ; -if (ipl_block.hdr.flags &IPL_PL_FLAG_IPLSR ) +if (ipl_block.hdr.flags &IPL_PL_FLAG_SIPL )pr_info ("Linux is running with Secure-IPL enabled\n" );else pr_info ("Linux is running with Secure-IPL disabled\n" );
Greg Kroah-Hartman
maintainerPATCH 74/222 clk: samsung: exynos5420: Keep top G3D clocks enabled
In reply to Greg Kroah-HartmanFrom: Marek Szyprowski <[email protected]>
commit 67f96ff7c8f073648696eab50fd23ded23441067 upstream.
In Exynos542x/5800 SoCs, the G3D leaf clocks are located in the G3D power domain. This is similar to the other hardware modules and their power domains. However there is one thing specific to G3D clocks hierarchy. Unlike other hardware modules, the G3D clocks hierarchy doesn't have any gate clock between the TOP part of the hierarchy and the part located in the power domain and some SoC internal busses are sourced directly from the TOP muxes. The consequence of this design if the fact that the TOP part of the hierarchy has to be enabled permanently to ensure proper operation of the SoC power related components (G3D power domain and Exynos Power Management Unit for system suspend/resume).
This patch adds an explicit call to clk_prepare_enable() on the last MUX in the TOP part of G3D clock hierarchy to keep it enabled permanently to ensure that the internal busses get their clock regardless of the main G3D clock enablement status.
This fixes following imprecise abort issue observed on Odroid XU3/XU4 after enabling Panfrost driver by commit 1a5a85c56402 "ARM: dts: exynos:
Add Mali/GPU node on Exynos5420 and enable it on Odroid XU3/4"):
panfrost 11800000.gpu: clock rate = 400000000
panfrost 11800000.gpu: failed to get regulator: -517 panfrost 11800000.gpu: regulator init failed -517 Power domain G3D disable failed
...
panfrost 11800000.gpu: clock rate = 400000000
8<--- cut here ---
Unhandled fault: imprecise external abort (0x1406) at 0x00000000 pgd = (ptrval)
[00000000] *pgd=00000000
Internal error: : 1406 [#1] PREEMPT SMP ARM Modules linked in: CPU: 7 PID: 53 Comm: kworker/7:1 Not tainted 5.4.0-rc8-next-20191119-00032-g56f1001191a6 #6923 Hardware name: SAMSUNG EXYNOS (Flattened Device Tree) Workqueue: events deferred_probe_work_func PC is at panfrost_gpu_soft_reset+0x94/0x110 LR is at ___might_sleep+0x128/0x2dc
...
[<c05c231c>] (panfrost_gpu_soft_reset) from [<c05c2704>] (panfrost_gpu_init+0x10/0x67c) [<c05c2704>] (panfrost_gpu_init) from [<c05c15d0>] (panfrost_device_init+0x158/0x2cc) [<c05c15d0>] (panfrost_device_init) from [<c05c0cb0>] (panfrost_probe+0x80/0x178) [<c05c0cb0>] (panfrost_probe) from [<c05cfaa0>] (platform_drv_probe+0x48/0x9c) [<c05cfaa0>] (platform_drv_probe) from [<c05cd20c>] (really_probe+0x1c4/0x474) [<c05cd20c>] (really_probe) from [<c05cd694>] (driver_probe_device+0x78/0x1bc) [<c05cd694>] (driver_probe_device) from [<c05cb374>] (bus_for_each_drv+0x74/0xb8) [<c05cb374>] (bus_for_each_drv) from [<c05ccfa8>] (__device_attach+0xd4/0x16c) [<c05ccfa8>] (__device_attach) from [<c05cc110>] (bus_probe_device+0x88/0x90) [<c05cc110>] (bus_probe_device) from [<c05cc634>] (deferred_probe_work_func+0x4c/0xd0) [<c05cc634>] (deferred_probe_work_func) from [<c0149df0>] (process_one_work+0x300/0x864) [<c0149df0>] (process_one_work) from [<c014a3ac>] (worker_thread+0x58/0x5a0) [<c014a3ac>] (worker_thread) from [<c0151174>] (kthread+0x12c/0x160) [<c0151174>] (kthread) from [<c01010b4>] (ret_from_fork+0x14/0x20)
Exception stack(0xee03dfb0 to 0xee03dff8) ... Code: e594300c e5933020 e3130c01 1a00000f (ebefff50). ---[ end trace badde2b74a65a540 ]---
In the above case, the Panfrost driver disables G3D clocks after failure of getting the needed regulator and return with -EPROVE_DEFER code. This causes G3D power domain disable failure and then, during second probe an imprecise abort is triggered due to undefined power domain state.
--- drivers/clk/samsung/clk-exynos5420.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/clk/samsung/clk-exynos5420.c +8 -0
@@ -12,6 +12,7 @@#include <linux/clk-provider.h> #include <linux/of.h> #include <linux/of_address.h> +#include <linux/clk.h> #include "clk.h" #include "clk-cpu.h"
@@ -1630,6 +1631,13 @@ static void __init exynos5x_clk_init(str exynos5x_subcmus); } +/* +* Keep top part of G3D clock path enabled permanently to ensure +* that the internal busses get their clock regardless of the +* main G3D clock enablement status. +*/ +clk_prepare_enable (__clk_lookup ("mout_sw_aclk_g3d" )); +samsung_clk_of_add_provider (np, ctx); }
Greg Kroah-Hartman
maintainerPATCH 75/222 perf hists: Fix variable names inconsistency in hists__for_each() macro
In reply to Greg Kroah-HartmanFrom: Yuya Fujita <[email protected]>
commit 55347ec340af401437680fd0e88df6739a967f9f upstream.
Variable names are inconsistent in hists__for_each macro().
Due to this inconsistency, the macro replaces its second argument with "fmt" regardless of its original name.
So far it works because only "fmt" is passed to the second argument. However, this behavior is not expected and should be fixed.
--- tools/perf/util/hist.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
tools/perf/util/hist.h +2 -2
@@ -339,10 +339,10 @@ static inline void perf_hpp__prepend_sor list_for_each_entry_safe(format, tmp, &(_list)->sorts, sort_list)#define hists__for_each_format (hists, format) \ - perf_hpp_list__for_each_format((hists)->hpp_list, fmt) + perf_hpp_list__for_each_format((hists)->hpp_list, format)#define hists__for_each_sort_list (hists, format) \ - perf_hpp_list__for_each_sort_list((hists)->hpp_list, fmt) + perf_hpp_list__for_each_sort_list((hists)->hpp_list, format)extern struct perf_hpp_fmt perf_hpp__format[];
Greg Kroah-Hartman
maintainerPATCH 76/222 locking/lockdep: Fix buffer overrun problem in stack_trace[]
In reply to Greg Kroah-HartmanFrom: Waiman Long <[email protected]>
commit d91f3057263ceb691ef527e71b41a56b17f6c869 upstream.
If the lockdep code is really running out of the stack_trace entries, it is likely that buffer overrun can happen and the data immediately after stack_trace[] will be corrupted.
If there is less than LOCK_TRACE_SIZE_IN_LONGS entries left before the call to save_trace(), the max_entries computation will leave it with a very large positive number because of its unsigned nature. The subsequent call to stack_trace_save() will then corrupt the data after stack_trace[]. Fix that by changing max_entries to a signed integer and check for negative value before calling stack_trace_save().
--- kernel/locking/lockdep.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
kernel/locking/lockdep.c +3 -4
@@ -482,7 +482,7 @@ static struct lock_trace *save_trace(voistruct lock_trace *trace, *t2;struct hlist_head *hash_head;u32 hash; -unsigned int max_entries; +int max_entries;BUILD_BUG_ON_NOT_POWER_OF_2 (STACK_TRACE_HASH_SIZE );BUILD_BUG_ON (LOCK_TRACE_SIZE_IN_LONGS >=MAX_STACK_TRACE_ENTRIES );
@@ -490,10 +490,8 @@ static struct lock_trace *save_trace(voi trace = (struct lock_trace *)(stack_trace + nr_stack_trace_entries); max_entries =MAX_STACK_TRACE_ENTRIES - nr_stack_trace_entries -LOCK_TRACE_SIZE_IN_LONGS ; - trace->nr_entries =stack_trace_save (trace->entries, max_entries,3 ); -if (nr_stack_trace_entries >=MAX_STACK_TRACE_ENTRIES - -LOCK_TRACE_SIZE_IN_LONGS -1 ) { +if (max_entries <=0 ) {if (!debug_locks_off_graph_unlock ())return NULL ;
@@ -502,6 +500,7 @@ static struct lock_trace *save_trace(voireturn NULL ; } + trace->nr_entries =stack_trace_save (trace->entries, max_entries,3 ); hash =jhash (trace->entries, trace->nr_entries *sizeof (trace->entries[0 ]),0 );
Greg Kroah-Hartman
maintainerPATCH 77/222 perf report: Fix incorrectly added dimensions as switch perf data file
In reply to Greg Kroah-HartmanFrom: Jin Yao <[email protected]>
commit 0feba17bd7ee3b7e03d141f119049dcc23efa94e upstream.
We observed an issue that was some extra columns displayed after switching perf data file in browser. The steps to reproduce:
1. perf record -a -e cycles,instructions -- sleep 3
2. perf report --group
3. In browser, we use hotkey 's' to switch to another perf.data
4. Now in browser, the extra columns 'Self' and 'Children' are displayed.
The issue is setup_sorting() executed again after repeat path, so dimensions are added again.
This patch checks the last key returned from __cmd_report(). If it's K_SWITCH_INPUT_DATA, skips the setup_sorting().
--- tools/perf/builtin-report.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
tools/perf/builtin-report.c +4 -1
@@ -1031,6 +1031,7 @@ int cmd_report(int argc, const char **arstruct stat st;bool has_br_stack = false;int branch_mode =-1 ; +int last_key =0 ;bool branch_call_mode = false;#define CALLCHAIN_DEFAULT_OPT "graph,0.5,caller,function,percent"static const char report_callchain_help[] ="Display call graph (stack chain/backtrace):\n\n"
@@ -1396,7 +1397,8 @@ repeat: sort_order = sort_tmp; } -if (setup_sorting (session->evlist) <0 ) { +if ((last_key !=K_SWITCH_INPUT_DATA ) && + (setup_sorting (session->evlist) <0 )) {if (sort_order)parse_options_usage (report_usage, options,"s" ,1 );if (field_order)
@@ -1475,6 +1477,7 @@ repeat: ret =__cmd_report (&report);if (ret ==K_SWITCH_INPUT_DATA ) {perf_session__delete (session); + last_key =K_SWITCH_INPUT_DATA ; goto repeat; }else ret =0 ;
Greg Kroah-Hartman
maintainerPATCH 78/222 mm/shmem.c: thp, shmem: fix conflict of above-47bit hint address and PMD alignment
In reply to Greg Kroah-HartmanFrom: Kirill A. Shutemov <[email protected]>
commit 991589974d9c9ecb24ee3799ec8c415c730598a2 upstream.
Shmem/tmpfs tries to provide THP-friendly mappings if huge pages are enabled. But it doesn't work well with above-47bit hint address.
Normally, the kernel doesn't create userspace mappings above 47-bit, even if the machine allows this (such as with 5-level paging on x86-64). Not all user space is ready to handle wide addresses. It's known that at least some JIT compilers use higher bits in pointers to encode their information.
Userspace can ask for allocation from full address space by specifying hint address (with or without MAP_FIXED) above 47-bits. If the application doesn't need a particular address, but wants to allocate from whole address space it can specify -1 as a hint address.
Unfortunately, this trick breaks THP alignment in shmem/tmp:shmem_get_unmapped_area() would not try to allocate PMD-aligned area if *any* hint address specified.
This can be fixed by requesting the aligned area if the we failed to allocated at user-specified hint address. The request with inflated length will also take the user-specified hint address. This way we will not lose an allocation request from the full address space.
--- mm/shmem.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
mm/shmem.c +4 -3
@@ -2106,9 +2106,10 @@ unsigned long shmem_get_unmapped_area(st/* * Our priority is to support MAP_SHARED mapped hugely; * and support MAP_PRIVATE mapped hugely too, until it is COWed. -* But if caller specified an address hint, respect that as before. +* But if caller specified an address hint and we allocated area there +* successfully, respect that as before. */ -if (uaddr) +if (uaddr == addr)return addr;if (shmem_huge !=SHMEM_HUGE_FORCE ) {
@@ -2142,7 +2143,7 @@ unsigned long shmem_get_unmapped_area(stif (inflated_len < len)return addr; - inflated_addr =get_area (NULL ,0 , inflated_len,0 , flags); + inflated_addr =get_area (NULL , uaddr, inflated_len,0 , flags);if (IS_ERR_VALUE (inflated_addr))return addr;if (inflated_addr & ~PAGE_MASK )
Greg Kroah-Hartman
maintainerPATCH 79/222 mm/huge_memory.c: thp: fix conflict of above-47bit hint address and PMD alignment
In reply to Greg Kroah-HartmanFrom: Kirill A. Shutemov <[email protected]>
commit 97d3d0f9a1cf132c63c0b8b8bd497b8a56283dd9 upstream.
Patch series "Fix two above-47bit hint address vs. THP bugs".
The two get_unmapped_area() implementations have to be fixed to provide THP-friendly mappings if above-47bit hint address is specified.
This patch (of 2):
Filesystems use thp_get_unmapped_area() to provide THP-friendly mappings. For DAX in particular.
Normally, the kernel doesn't create userspace mappings above 47-bit, even if the machine allows this (such as with 5-level paging on x86-64). Not all user space is ready to handle wide addresses. It's known that at least some JIT compilers use higher bits in pointers to encode their information.
Userspace can ask for allocation from full address space by specifying hint address (with or without MAP_FIXED) above 47-bits. If the application doesn't need a particular address, but wants to allocate from whole address space it can specify -1 as a hint address.
Unfortunately, this trick breaks thp_get_unmapped_area(): the function would not try to allocate PMD-aligned area if *any* hint address specified.
Modify the routine to handle it correctly:
- Try to allocate the space at the specified hint address with length padding required for PMD alignment.
- If failed, retry without length padding (but with the same hint address);
- If the returned address matches the hint address return it.
- Otherwise, align the address as required for THP and return.
The user specified hint address is passed down to get_unmapped_area() so above-47bit hint address will be taken into account without breaking alignment requirements.
--- mm/huge_memory.c | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-)
mm/huge_memory.c +24 -14
@@ -527,13 +527,13 @@ void prep_transhuge_page(struct page *paset_compound_page_dtor (page,TRANSHUGE_PAGE_DTOR ); } -static unsigned long __thp_get_unmapped_area (struct file *filp,unsigned long len, +static unsigned long __thp_get_unmapped_area (struct file *filp, +unsigned long addr,unsigned long len,loff_t off,unsigned long flags,unsigned long size) { -unsigned long addr;loff_t off_end = off + len;loff_t off_align =round_up (off, size); -unsigned long len_pad; +unsigned long len_pad, ret;if (off_end <= off_align || (off_end - off_align) < size)return 0 ;
@@ -542,30 +542,40 @@ static unsigned long __thp_get_unmapped_if (len_pad < len || (off + len_pad) < off)return 0 ; - addr = current->mm->get_unmapped_area (filp,0 , len_pad, + ret = current->mm->get_unmapped_area (filp, addr, len_pad, off >>PAGE_SHIFT , flags); -if (IS_ERR_VALUE (addr)) + +/* +* The failure might be due to length padding. The caller will retry +* without the padding. +*/ +if (IS_ERR_VALUE (ret))return 0 ; - addr += (off - addr) & (size -1 ); -return addr; +/* +* Do not try to align to THP boundary if allocation at the address +* hint succeeds. +*/ +if (ret == addr) +return addr; + + ret += (off - ret) & (size -1 ); +return ret; }unsigned long thp_get_unmapped_area (struct file *filp,unsigned long addr,unsigned long len,unsigned long pgoff,unsigned long flags) { +unsigned long ret;loff_t off = (loff_t )pgoff <<PAGE_SHIFT ; -if (addr) - goto out;if (!IS_DAX (filp->f_mapping->host) || !IS_ENABLED (CONFIG_FS_DAX_PMD )) goto out; - addr =__thp_get_unmapped_area (filp, len, off, flags,PMD_SIZE ); -if (addr) -return addr; - - out: + ret =__thp_get_unmapped_area (filp, addr, len, off, flags,PMD_SIZE ); +if (ret) +return ret; +out:return current->mm->get_unmapped_area (filp, addr, len, pgoff, flags); }EXPORT_SYMBOL_GPL (thp_get_unmapped_area);
Greg Kroah-Hartman
maintainerPATCH 80/222 mm: memcg/slab: fix percpu slab vmstats flushing
In reply to Greg Kroah-HartmanFrom: Roman Gushchin <[email protected]>
commit 4a87e2a25dc27131c3cce5e94421622193305638 upstream.
Currently slab percpu vmstats are flushed twice: during the memcg offlining and just before freeing the memcg structure. Each time percpu counters are summed, added to the atomic counterparts and propagated up by the cgroup tree.
The second flushing is required due to how recursive vmstats are
implemented: counters are batched in percpu variables on a local level, and once a percpu value is crossing some predefined threshold, it spills over to atomic values on the local and each ascendant levels. It means that without flushing some numbers cached in percpu variables will be dropped on floor each time a cgroup is destroyed. And with uptime the error on upper levels might become noticeable.
The first flushing aims to make counters on ancestor levels more precise. Dying cgroups may resume in the dying state for a long time. After kmem_cache reparenting which is performed during the offlining slab counters of the dying cgroup don't have any chances to be updated, because any slab operations will be performed on the parent level. It means that the inaccuracy caused by percpu batching will not decrease up to the final destruction of the cgroup. By the original idea flushing slab counters during the offlining should minimize the visible inaccuracy of slab counters on the parent level.
The problem is that percpu counters are not zeroed after the first flushing. So every cached percpu value is summed twice. It creates a small error (up to 32 pages per cpu, but usually less) which accumulates on parent cgroup level. After creating and destroying of thousands of child cgroups, slab counter on parent level can be way off the real value.
For now, let's just stop flushing slab counters on memcg offlining. It can't be done correctly without scheduling a work on each cpu: reading and zeroing it during css offlining can race with an asynchronous update, which doesn't expect values to be changed underneath.
With this change, slab counters on parent level will become eventually consistent. Once all dying children are gone, values are correct. And if not, the error is capped by 32 * NR_CPUS pages per dying cgroup.
It's not perfect, as slab are reparented, so any updates after the reparenting will happen on the parent level. It means that if a slab page was allocated, a counter on child level was bumped, then the page was reparented and freed, the annihilation of positive and negative counter values will not happen until the child cgroup is released. It makes slab counters different from others, and it might want us to implement flushing in a correct form again. But it's also a question of
performance: scheduling a work on each cpu isn't free, and it's an open question if the benefit of having more accurate counters is worth it.
We might also consider flushing all counters on offlining, not only slab counters.
So let's fix the main problem now: make the slab counters eventually consistent, so at least the error won't grow with uptime (or more precisely the number of created and destroyed cgroups). And think about the accuracy of counters separately.
--- include/linux/mmzone.h | 5 ++--- mm/memcontrol.c | 37 +++++++++---------------------------- 2 files changed, 11 insertions(+), 31 deletions(-)
include/linux/mmzone.h +2 -3
@@ -215,9 +215,8 @@ enum node_stat_item {NR_INACTIVE_FILE ,/* " " " " " */ NR_ACTIVE_FILE ,/* " " " " " */ NR_UNEVICTABLE ,/* " " " " " */ -NR_SLAB_RECLAIMABLE ,/* Please do not reorder this item */ -NR_SLAB_UNRECLAIMABLE ,/* and this one without looking at -* memcg_flush_percpu_vmstats() first. */ +NR_SLAB_RECLAIMABLE , +NR_SLAB_UNRECLAIMABLE ,NR_ISOLATED_ANON ,/* Temporary isolated pages from anon lru */ NR_ISOLATED_FILE ,/* Temporary isolated pages from file lru */ WORKINGSET_NODES,
mm/memcontrol.c +9 -28
@@ -3404,49 +3404,34 @@ static u64 mem_cgroup_read_u64(struct cg } } -static void memcg_flush_percpu_vmstats (struct mem_cgroup *memcg,bool slab_only) +static void memcg_flush_percpu_vmstats (struct mem_cgroup *memcg) { -unsigned long stat[MEMCG_NR_STAT ]; +unsigned long stat[MEMCG_NR_STAT ] = {0 };struct mem_cgroup *mi;int node, cpu, i; -int min_idx, max_idx; - -if (slab_only) { - min_idx =NR_SLAB_RECLAIMABLE ; - max_idx =NR_SLAB_UNRECLAIMABLE ; - }else { - min_idx =0 ; - max_idx =MEMCG_NR_STAT ; - } - -for (i = min_idx; i < max_idx; i++) - stat[i] =0 ;for_each_online_cpu (cpu) -for (i = min_idx; i < max_idx; i++) +for (i =0 ; i <MEMCG_NR_STAT ; i++) stat[i] +=per_cpu (memcg->vmstats_percpu->stat[i], cpu);for (mi = memcg; mi; mi =parent_mem_cgroup (mi)) -for (i = min_idx; i < max_idx; i++) +for (i =0 ; i <MEMCG_NR_STAT ; i++)atomic_long_add (stat[i], &mi->vmstats[i]); -if (!slab_only) - max_idx =NR_VM_NODE_STAT_ITEMS ; -for_each_node (node) {struct mem_cgroup_per_node *pn = memcg->nodeinfo[node];struct mem_cgroup_per_node *pi; -for (i = min_idx; i < max_idx; i++) +for (i =0 ; i <NR_VM_NODE_STAT_ITEMS ; i++) stat[i] =0 ;for_each_online_cpu (cpu) -for (i = min_idx; i < max_idx; i++) +for (i =0 ; i <NR_VM_NODE_STAT_ITEMS ; i++) stat[i] +=per_cpu ( pn->lruvec_stat_cpu->count[i], cpu);for (pi = pn; pi; pi =parent_nodeinfo (pi, node)) -for (i = min_idx; i < max_idx; i++) +for (i =0 ; i <NR_VM_NODE_STAT_ITEMS ; i++)atomic_long_add (stat[i], &pi->lruvec_stat[i]); } }
@@ -3520,13 +3505,9 @@ static void memcg_offline_kmem(struct me parent = root_mem_cgroup;/* -* Deactivate and reparent kmem_caches. Then flush percpu -* slab statistics to have precise values at the parent and -* all ancestor levels. It's required to keep slab stats -* accurate after the reparenting of kmem_caches. +* Deactivate and reparent kmem_caches. */ memcg_deactivate_kmem_caches (memcg, parent); -memcg_flush_percpu_vmstats (memcg, true); kmemcg_id = memcg->kmemcg_id;BUG_ON (kmemcg_id <0 );
@@ -5037,7 +5018,7 @@ static void mem_cgroup_free(struct mem_c* Flush percpu vmstats and vmevents to guarantee the value correctness * on parent's and all ancestor levels. */ -memcg_flush_percpu_vmstats (memcg, false); +memcg_flush_percpu_vmstats (memcg);memcg_flush_percpu_vmevents (memcg);__mem_cgroup_free (memcg); }
Greg Kroah-Hartman
maintainerPATCH 81/222 mm: memcg/slab: call flush_memcg_workqueue() only if memcg workqueue is valid
In reply to Greg Kroah-HartmanFrom: Adrian Huang <[email protected]>
commit 2fe20210fc5f5e62644678b8f927c49f2c6f42a7 upstream.
When booting with amd_iommu=off, the following WARNING message appears:
AMD-Vi: AMD IOMMU disabled on kernel command-line
------------[ cut here ]------------ WARNING: CPU: 0 PID: 0 at kernel/workqueue.c:2772 flush_workqueue+0x42e/0x450 Modules linked in: CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.5.0-rc3-amd-iommu #6 Hardware name: Lenovo ThinkSystem SR655-2S/7D2WRCZ000, BIOS D8E101L-1.00 12/05/2019 RIP: 0010:flush_workqueue+0x42e/0x450 Code: ff 0f 0b e9 7a fd ff ff 4d 89 ef e9 33 fe ff ff 0f 0b e9 7f fd ff ff 0f 0b e9 bc fd ff ff 0f 0b e9 a8 fd ff ff e8 52 2c fe ff <0f> 0b 31 d2 48 c7 c6 e0 88 c5 95 48 c7 c7 d8 ad f0 95 e8 19 f5 04 Call Trace: kmem_cache_destroy+0x69/0x260 iommu_go_to_state+0x40c/0x5ab amd_iommu_prepare+0x16/0x2a irq_remapping_prepare+0x36/0x5f enable_IR_x2apic+0x21/0x172 default_setup_apic_routing+0x12/0x6f apic_intr_mode_init+0x1a1/0x1f1 x86_late_time_init+0x17/0x1c start_kernel+0x480/0x53f secondary_startup_64+0xb6/0xc0 ---[ end trace 30894107c3749449 ]--- x2apic: IRQ remapping doesn't support X2APIC mode x2apic disabled
The warning is caused by the calling of 'kmem_cache_destroy()' in free_iommu_resources(). Here is the call path:
free_iommu_resources
kmem_cache_destroy
flush_memcg_workqueue
flush_workqueue
The root cause is that the IOMMU subsystem runs before the workqueue subsystem, which the variable 'wq_online' is still 'false'. This leads to the statement 'if (WARN_ON(!wq_online))' in flush_workqueue() is 'true'.
Since the variable 'memcg_kmem_cache_wq' is not allocated during the time, it is unnecessary to call flush_memcg_workqueue(). This prevents the WARNING message triggered by flush_workqueue().
--- mm/slab_common.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
mm/slab_common.c +2 -1
@@ -903,7 +903,8 @@ static void flush_memcg_workqueue(struct* deactivates the memcg kmem_caches through workqueue. Make sure all * previous workitems on workqueue are processed. */ -flush_workqueue (memcg_kmem_cache_wq); +if (likely (memcg_kmem_cache_wq)) +flush_workqueue (memcg_kmem_cache_wq);/* * If we're racing with children kmem_cache deactivation, it might
Greg Kroah-Hartman
maintainerPATCH 82/222 mm, debug_pagealloc: dont rely on static keys too early
In reply to Greg Kroah-HartmanFrom: Vlastimil Babka <[email protected]>
commit 8e57f8acbbd121ecfb0c9dc13b8b030f86c6bd3b upstream.
Commit 96a2b03f281d ("mm, debug_pagelloc: use static keys to enable debugging") has introduced a static key to reduce overhead when debug_pagealloc is compiled in but not enabled. It relied on the assumption that jump_label_init() is called before parse_early_param() as in start_kernel(), so when the "debug_pagealloc=on" option is parsed, it is safe to enable the static key.
However, it turns out multiple architectures call parse_early_param() earlier from their setup_arch(). x86 also calls jump_label_init() even earlier, so no issue was found while testing the commit, but same is not true for e.g. ppc64 and s390 where the kernel would not boot with debug_pagealloc=on as found by our QA.
To fix this without tricky changes to init code of multiple architectures, this patch partially reverts the static key conversion from 96a2b03f281d. Init-time and non-fastpath calls (such as in arch code) of debug_pagealloc_enabled() will again test a simple bool variable. Fastpath mm code is converted to a new debug_pagealloc_enabled_static() variant that relies on the static key, which is enabled in a well-defined point in mm_init() where it's guaranteed that jump_label_init() has been called, regardless of architecture.
--- include/linux/mm.h | 18 +++++++++++++++--- init/main.c | 1 + mm/page_alloc.c | 37 +++++++++++++------------------------ mm/slab.c | 4 ++-- mm/slub.c | 2 +- mm/vmalloc.c | 4 ++-- 6 files changed, 34 insertions(+), 32 deletions(-)
include/linux/mm.h +15 -3
@@ -2666,14 +2666,26 @@ static inline bool want_init_on_free(voi !page_poisoning_enabled (); } -#ifdef CONFIG_DEBUG_PAGEALLOC_ENABLE_DEFAULT -DECLARE_STATIC_KEY_TRUE (_debug_pagealloc_enabled); +#ifdef CONFIG_DEBUG_PAGEALLOC +extern void init_debug_pagealloc (void );#else -DECLARE_STATIC_KEY_FALSE (_debug_pagealloc_enabled); +static inline void init_debug_pagealloc (void ) {}#endif +extern bool _debug_pagealloc_enabled_early; +DECLARE_STATIC_KEY_FALSE (_debug_pagealloc_enabled);static inline bool debug_pagealloc_enabled (void ) { +return IS_ENABLED (CONFIG_DEBUG_PAGEALLOC ) && + _debug_pagealloc_enabled_early; +} + +/* +* For use in fast paths after init_debug_pagealloc() has run, or when a +* false negative result is not harmful when called too early. +*/ +static inline bool debug_pagealloc_enabled_static (void ) +{if (!IS_ENABLED (CONFIG_DEBUG_PAGEALLOC ))return false;
init/main.c +1 -0
@@ -553,6 +553,7 @@ static void __init mm_init(void)* bigger than MAX_ORDER unless SPARSEMEM. */ page_ext_init_flatmem (); +init_debug_pagealloc ();report_meminit ();mem_init ();kmem_cache_init ();
mm/page_alloc.c +13 -24
@@ -694,34 +694,27 @@ void prep_compound_page(struct page *pag#ifdef CONFIG_DEBUG_PAGEALLOC unsigned int _debug_guardpage_minorder; -#ifdef CONFIG_DEBUG_PAGEALLOC_ENABLE_DEFAULT -DEFINE_STATIC_KEY_TRUE (_debug_pagealloc_enabled); -#else +bool _debug_pagealloc_enabled_early__read_mostly + =IS_ENABLED (CONFIG_DEBUG_PAGEALLOC_ENABLE_DEFAULT ); +EXPORT_SYMBOL (_debug_pagealloc_enabled_early);DEFINE_STATIC_KEY_FALSE (_debug_pagealloc_enabled); -#endif EXPORT_SYMBOL (_debug_pagealloc_enabled);DEFINE_STATIC_KEY_FALSE (_debug_guardpage_enabled);static int __init early_debug_pagealloc (char *buf) { -bool enable = false; - -if (kstrtobool (buf, &enable)) -return -EINVAL ; - -if (enable) -static_branch_enable (&_debug_pagealloc_enabled); - -return 0 ; +return kstrtobool (buf, &_debug_pagealloc_enabled_early); }early_param ("debug_pagealloc" , early_debug_pagealloc); -static void init_debug_guardpage (void ) +void init_debug_pagealloc (void ) {if (!debug_pagealloc_enabled ())return ; +static_branch_enable (&_debug_pagealloc_enabled); +if (!debug_guardpage_minorder ())return ;
@@ -1186,7 +1179,7 @@ static __always_inline bool free_pages_p*/ arch_free_page (page, order); -if (debug_pagealloc_enabled ()) +if (debug_pagealloc_enabled_static ())kernel_map_pages (page,1 << order,0 );kasan_free_nondeferred_pages (page, order);
@@ -1207,7 +1200,7 @@ static bool free_pcp_prepare(struct pagestatic bool bulkfree_pcp_prepare (struct page *page) { -if (debug_pagealloc_enabled ()) +if (debug_pagealloc_enabled_static ())return free_pages_check (page);else return false;
@@ -1221,7 +1214,7 @@ static bool bulkfree_pcp_prepare(struct*/ static bool free_pcp_prepare (struct page *page) { -if (debug_pagealloc_enabled ()) +if (debug_pagealloc_enabled_static ())return free_pages_prepare (page,0 , true);else return free_pages_prepare (page,0 , false);
@@ -1973,10 +1966,6 @@ void __init page_alloc_init_late(void)for_each_populated_zone (zone)set_zone_contiguous (zone); - -#ifdef CONFIG_DEBUG_PAGEALLOC -init_debug_guardpage (); -#endif }#ifdef CONFIG_CMA
@@ -2106,7 +2095,7 @@ static inline bool free_pages_prezeroed(*/ static inline bool check_pcp_refill (struct page *page) { -if (debug_pagealloc_enabled ()) +if (debug_pagealloc_enabled_static ())return check_new_page (page);else return false;
@@ -2128,7 +2117,7 @@ static inline bool check_pcp_refill(stru }static inline bool check_new_pcp (struct page *page) { -if (debug_pagealloc_enabled ()) +if (debug_pagealloc_enabled_static ())return check_new_page (page);else return false;
@@ -2155,7 +2144,7 @@ inline void post_alloc_hook(struct pageset_page_refcounted (page);arch_alloc_page (page, order); -if (debug_pagealloc_enabled ()) +if (debug_pagealloc_enabled_static ())kernel_map_pages (page,1 << order,1 );kasan_alloc_pages (page, order);kernel_poison_pages (page,1 << order,1 );
mm/slab.c +2 -2
@@ -1415,7 +1415,7 @@ static void kmem_rcu_free(struct rcu_hea#if DEBUG static bool is_debug_pagealloc_cache (struct kmem_cache *cachep) { -if (debug_pagealloc_enabled () &&OFF_SLAB (cachep) && +if (debug_pagealloc_enabled_static () &&OFF_SLAB (cachep) && (cachep->size %PAGE_SIZE ) ==0 )return true;
@@ -2007,7 +2007,7 @@ int __kmem_cache_create(struct kmem_cach* to check size >= 256. It guarantees that all necessary small * sized slab is initialized in current slab initialization sequence. */ -if (debug_pagealloc_enabled () && (flags &SLAB_POISON ) && +if (debug_pagealloc_enabled_static () && (flags &SLAB_POISON ) && size >=256 && cachep->object_size >cache_line_size ()) {if (size <PAGE_SIZE || size %PAGE_SIZE ==0 ) {size_t tmp_size =ALIGN (size,PAGE_SIZE );
mm/slub.c +1 -1
@@ -290,7 +290,7 @@ static inline void *get_freepointer_safeunsigned long freepointer_addr;void *p; -if (!debug_pagealloc_enabled ()) +if (!debug_pagealloc_enabled_static ())return get_freepointer (s, object); freepointer_addr = (unsigned long )object + s->offset;
mm/vmalloc.c +2 -2
@@ -1349,7 +1349,7 @@ static void free_unmap_vmap_area(struct {flush_cache_vunmap (va->va_start, va->va_end);unmap_vmap_area (va); -if (debug_pagealloc_enabled ()) +if (debug_pagealloc_enabled_static ())flush_tlb_kernel_range (va->va_start, va->va_end);free_vmap_area_noflush (va);
@@ -1647,7 +1647,7 @@ static void vb_free(const void *addr, unvunmap_page_range ((unsigned long )addr, (unsigned long )addr + size); -if (debug_pagealloc_enabled ()) +if (debug_pagealloc_enabled_static ())flush_tlb_kernel_range ((unsigned long )addr, (unsigned long )addr + size);
Greg Kroah-Hartman
maintainerPATCH 83/222 btrfs: rework arguments of btrfs_unlink_subvol
In reply to Greg Kroah-HartmanFrom: Josef Bacik <[email protected]>
[ Upstream commit 045d3967b6920b663fc010ad414ade1b24143bd1 ]
btrfs_unlink_subvol takes the name of the dentry and the root objectid based on what kind of inode this is, either a real subvolume link or a empty one that we inherited as a snapshot. We need to fix how we unlink in the case for BTRFS_EMPTY_SUBVOL_DIR_OBJECTID in the future, so rework btrfs_unlink_subvol to just take the dentry and handle getting the right objectid given the type of inode this is. There is no functional change here, simply pushing the work into btrfs_unlink_subvol() proper.
--- fs/btrfs/inode.c | 46 ++++++++++++++++++++-------------------------- 1 file changed, 20 insertions(+), 26 deletions(-)
fs/btrfs/inode.c +20 -26
@@ -4215,18 +4215,30 @@ out: }static int btrfs_unlink_subvol (struct btrfs_trans_handle *trans, -struct inode *dir,u64 objectid, -const char *name,int name_len) +struct inode *dir,struct dentry *dentry) {struct btrfs_root *root =BTRFS_I (dir)->root; +struct btrfs_inode *inode =BTRFS_I (d_inode (dentry));struct btrfs_path *path;struct extent_buffer *leaf;struct btrfs_dir_item *di;struct btrfs_key key; +const char *name = dentry->d_name.name; +int name_len = dentry->d_name.len;u64 index;int ret; +u64 objectid;u64 dir_ino =btrfs_ino (BTRFS_I (dir)); +if (btrfs_ino (inode) ==BTRFS_FIRST_FREE_OBJECTID ) { + objectid = inode->root->root_key.objectid; + }else if (btrfs_ino (inode) ==BTRFS_EMPTY_SUBVOL_DIR_OBJECTID ) { + objectid = inode->location.objectid; + }else { +WARN_ON (1 ); +return -EINVAL ; + } + path =btrfs_alloc_path ();if (!path)return -ENOMEM ;
@@ -4464,8 +4476,7 @@ int btrfs_delete_subvolume(struct inodebtrfs_record_snapshot_destroy (trans,BTRFS_I (dir)); - ret =btrfs_unlink_subvol (trans, dir, dest->root_key.objectid, - dentry->d_name.name, dentry->d_name.len); + ret =btrfs_unlink_subvol (trans, dir, dentry);if (ret) { err = ret;btrfs_abort_transaction (trans, ret);
@@ -4560,10 +4571,7 @@ static int btrfs_rmdir(struct inode *dirreturn PTR_ERR (trans);if (unlikely (btrfs_ino (BTRFS_I (inode)) ==BTRFS_EMPTY_SUBVOL_DIR_OBJECTID )) { - err =btrfs_unlink_subvol (trans, dir, -BTRFS_I (inode)->location.objectid, - dentry->d_name.name, - dentry->d_name.len); + err =btrfs_unlink_subvol (trans, dir, dentry); goto out; }
@@ -9519,7 +9527,6 @@ static int btrfs_rename_exchange(structu64 new_ino =btrfs_ino (BTRFS_I (new_inode));u64 old_idx =0 ;u64 new_idx =0 ; -u64 root_objectid;int ret;bool root_log_pinned = false;bool dest_log_pinned = false;
@@ -9625,10 +9632,7 @@ static int btrfs_rename_exchange(struct/* src is a subvolume */ if (old_ino ==BTRFS_FIRST_FREE_OBJECTID ) { - root_objectid =BTRFS_I (old_inode)->root->root_key.objectid; - ret =btrfs_unlink_subvol (trans, old_dir, root_objectid, - old_dentry->d_name.name, - old_dentry->d_name.len); + ret =btrfs_unlink_subvol (trans, old_dir, old_dentry); }else {/* src is an inode */ ret = __btrfs_unlink_inode(trans, root, BTRFS_I(old_dir), BTRFS_I(old_dentry->d_inode),
@@ -9644,10 +9648,7 @@ static int btrfs_rename_exchange(struct/* dest is a subvolume */ if (new_ino ==BTRFS_FIRST_FREE_OBJECTID ) { - root_objectid =BTRFS_I (new_inode)->root->root_key.objectid; - ret =btrfs_unlink_subvol (trans, new_dir, root_objectid, - new_dentry->d_name.name, - new_dentry->d_name.len); + ret =btrfs_unlink_subvol (trans, new_dir, new_dentry); }else {/* dest is an inode */ ret = __btrfs_unlink_inode(trans, dest, BTRFS_I(new_dir), BTRFS_I(new_dentry->d_inode),
@@ -9845,7 +9846,6 @@ static int btrfs_rename(struct inode *olstruct inode *new_inode =d_inode (new_dentry);struct inode *old_inode =d_inode (old_dentry);u64 index =0 ; -u64 root_objectid;int ret;u64 old_ino =btrfs_ino (BTRFS_I (old_inode));bool log_pinned = false;
@@ -9953,10 +9953,7 @@ static int btrfs_rename(struct inode *ol BTRFS_I(old_inode), 1);if (unlikely (old_ino ==BTRFS_FIRST_FREE_OBJECTID )) { - root_objectid =BTRFS_I (old_inode)->root->root_key.objectid; - ret =btrfs_unlink_subvol (trans, old_dir, root_objectid, - old_dentry->d_name.name, - old_dentry->d_name.len); + ret =btrfs_unlink_subvol (trans, old_dir, old_dentry); }else { ret = __btrfs_unlink_inode(trans, root, BTRFS_I(old_dir), BTRFS_I(d_inode(old_dentry)),
@@ -9975,10 +9972,7 @@ static int btrfs_rename(struct inode *ol new_inode->i_ctime =current_time (new_inode);if (unlikely (btrfs_ino (BTRFS_I (new_inode)) ==BTRFS_EMPTY_SUBVOL_DIR_OBJECTID )) { - root_objectid =BTRFS_I (new_inode)->location.objectid; - ret =btrfs_unlink_subvol (trans, new_dir, root_objectid, - new_dentry->d_name.name, - new_dentry->d_name.len); + ret =btrfs_unlink_subvol (trans, new_dir, new_dentry);BUG_ON (new_inode->i_nlink ==0 ); }else { ret = btrfs_unlink_inode(trans, dest, BTRFS_I(new_dir),
Greg Kroah-Hartman
maintainerPATCH 84/222 btrfs: fix invalid removal of root ref
In reply to Greg Kroah-HartmanFrom: Josef Bacik <[email protected]>
commit d49d3287e74ffe55ae7430d1e795e5f9bf7359ea upstream.
If we have the following sequence of events
btrfs sub create A
btrfs sub create A/B
btrfs sub snap A C
mkdir C/foo
mv A/B C/foo
rm -rf *
We will end up with a transaction abort.
The reason for this is because we create a root ref for B pointing to A. When we create a snapshot of C we still have B in our tree, but because the root ref points to A and not C we will make it appear to be empty.
The problem happens when we move B into C. This removes the root ref for B pointing to A and adds a ref of B pointing to C. When we rmdir C we'll see that we have a ref to our root and remove the root ref, despite not actually matching our reference name.
Now btrfs_del_root_ref() allowing this to work is a bug as well, however we know that this inode does not actually point to a root ref in the first place, so we shouldn't be calling btrfs_del_root_ref() in the first place and instead simply look up our dir index for this item and do the rest of the removal.
--- fs/btrfs/inode.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-)
fs/btrfs/inode.c +19 -8
@@ -4260,13 +4260,16 @@ static int btrfs_unlink_subvol(struct bt }btrfs_release_path (path); - ret =btrfs_del_root_ref (trans, objectid, root->root_key.objectid, - dir_ino, &index, name, name_len); -if (ret <0 ) { -if (ret != -ENOENT ) { -btrfs_abort_transaction (trans, ret); - goto out; - } +/* +* This is a placeholder inode for a subvolume we didn't have a +* reference to at the time of the snapshot creation. In the meantime +* we could have renamed the real subvol link into our snapshot, so +* depending on btrfs_del_root_ref to return -ENOENT here is incorret. +* Instead simply lookup the dir_index_item for this entry so we can +* remove it. Otherwise we know we have a ref to the root and we can +* call btrfs_del_root_ref, and it _shouldn't_ fail. +*/ +if (btrfs_ino (inode) ==BTRFS_EMPTY_SUBVOL_DIR_OBJECTID ) { di =btrfs_search_dir_index_item (root, path, dir_ino, name, name_len);if (IS_ERR_OR_NULL (di)) {
@@ -4281,8 +4284,16 @@ static int btrfs_unlink_subvol(struct bt leaf = path->nodes[0 ];btrfs_item_key_to_cpu (leaf, &key, path->slots[0 ]); index = key.offset; +btrfs_release_path (path); + }else { + ret =btrfs_del_root_ref (trans, objectid, + root->root_key.objectid, dir_ino, + &index, name, name_len); +if (ret) { +btrfs_abort_transaction (trans, ret); + goto out; + } } -btrfs_release_path (path); ret =btrfs_delete_delayed_dir_index (trans,BTRFS_I (dir), index);if (ret) {
Greg Kroah-Hartman
maintainerPATCH 85/222 btrfs: do not delete mismatched root refs
In reply to Greg Kroah-HartmanFrom: Josef Bacik <[email protected]>
commit 423a716cd7be16fb08690760691befe3be97d3fc upstream.
btrfs_del_root_ref() will simply WARN_ON() if the ref doesn't match in any way, and then continue to delete the reference. This shouldn't happen, we have these values because there's more to the reference than the original root and the sub root. If any of these checks fail, return -ENOENT.
--- fs/btrfs/root-tree.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
fs/btrfs/root-tree.c +6 -4
@@ -376,11 +376,13 @@ again: leaf = path->nodes[0 ]; ref =btrfs_item_ptr (leaf, path->slots[0 ], struct btrfs_root_ref); - -WARN_ON (btrfs_root_ref_dirid (leaf, ref) != dirid); -WARN_ON (btrfs_root_ref_name_len (leaf, ref) != name_len); ptr = (unsigned long )(ref +1 ); -WARN_ON (memcmp_extent_buffer (leaf, name, ptr, name_len)); +if ((btrfs_root_ref_dirid (leaf, ref) != dirid) || + (btrfs_root_ref_name_len (leaf, ref) != name_len) || +memcmp_extent_buffer (leaf, name, ptr, name_len)) { + err = -ENOENT ; + goto out; + } *sequence =btrfs_root_ref_sequence (leaf, ref); ret =btrfs_del_item (trans, tree_root, path);
Greg Kroah-Hartman
maintainerPATCH 86/222 btrfs: relocation: fix reloc_root lifespan and access
In reply to Greg Kroah-HartmanFrom: Qu Wenruo <[email protected]>
commit 6282675e6708ec78518cc0e9ad1f1f73d7c5c53d upstream.
[BUG]
There are several different KASAN reports for balance + snapshot workloads. Involved call paths include:
should_ignore_root+0x54/0xb0 [btrfs] build_backref_tree+0x11af/0x2280 [btrfs] relocate_tree_blocks+0x391/0xb80 [btrfs] relocate_block_group+0x3e5/0xa00 [btrfs] btrfs_relocate_block_group+0x240/0x4d0 [btrfs] btrfs_relocate_chunk+0x53/0xf0 [btrfs] btrfs_balance+0xc91/0x1840 [btrfs] btrfs_ioctl_balance+0x416/0x4e0 [btrfs] btrfs_ioctl+0x8af/0x3e60 [btrfs] do_vfs_ioctl+0x831/0xb10 create_reloc_root+0x9f/0x460 [btrfs] btrfs_reloc_post_snapshot+0xff/0x6c0 [btrfs] create_pending_snapshot+0xa9b/0x15f0 [btrfs] create_pending_snapshots+0x111/0x140 [btrfs] btrfs_commit_transaction+0x7a6/0x1360 [btrfs] btrfs_mksubvol+0x915/0x960 [btrfs] btrfs_ioctl_snap_create_transid+0x1d5/0x1e0 [btrfs] btrfs_ioctl_snap_create_v2+0x1d3/0x270 [btrfs] btrfs_ioctl+0x241b/0x3e60 [btrfs] do_vfs_ioctl+0x831/0xb10 btrfs_reloc_pre_snapshot+0x85/0xc0 [btrfs] create_pending_snapshot+0x209/0x15f0 [btrfs] create_pending_snapshots+0x111/0x140 [btrfs] btrfs_commit_transaction+0x7a6/0x1360 [btrfs] btrfs_mksubvol+0x915/0x960 [btrfs] btrfs_ioctl_snap_create_transid+0x1d5/0x1e0 [btrfs] btrfs_ioctl_snap_create_v2+0x1d3/0x270 [btrfs] btrfs_ioctl+0x241b/0x3e60 [btrfs] do_vfs_ioctl+0x831/0xb10
[CAUSE]
All these call sites are only relying on root->reloc_root, which can undergo btrfs_drop_snapshot(), and since we don't have real refcount based protection to reloc roots, we can reach already dropped reloc root, triggering KASAN.
[FIX]
To avoid such access to unstable root->reloc_root, we should check BTRFS_ROOT_DEAD_RELOC_TREE bit first.
This patch introduces wrappers that provide the correct way to check the bit with memory barriers protection.
Most callers don't distinguish merged reloc tree and no reloc tree. The only exception is should_ignore_root(), as merged reloc tree can be ignored, while no reloc tree shouldn't.
[CRITICAL SECTION ANALYSIS]
Although test_bit()/set_bit()/clear_bit() doesn't imply a barrier, the DEAD_RELOC_TREE bit has extra help from transaction as a higher level barrier, the lifespan of root::reloc_root and DEAD_RELOC_TREE bit are:
NULL: reloc_root is NULL PTR: reloc_root is not NULL
0: DEAD_RELOC_ROOT bit not set DEAD: DEAD_RELOC_ROOT bit set
(NULL, 0) Initial state __
| /\ Section A
btrfs_init_reloc_root() \/
| __
(PTR, 0) reloc_root initialized /\
| |
btrfs_update_reloc_root() | Section B
| |
(PTR, DEAD) reloc_root has been merged \/
| __
=== btrfs_commit_transaction() ====================
| /\
clean_dirty_subvols() |
| | Section C
(NULL, DEAD) reloc_root cleanup starts \/
| __
btrfs_drop_snapshot() /\
| | Section D
(NULL, 0) Back to initial state \/Every have_reloc_root() or test_bit(DEAD_RELOC_ROOT) caller holds transaction handle, so none of such caller can cross transaction boundary.
In Section A, every caller just found no DEAD bit, and grab reloc_root.
In the cross section A-B, caller may get no DEAD bit, but since reloc_root is still completely valid thus accessing reloc_root is completely safe.
No test_bit() caller can cross the boundary of Section B and Section C.
In Section C, every caller found the DEAD bit, so no one will access reloc_root.
In the cross section C-D, either caller gets the DEAD bit set, avoiding access reloc_root no matter if it's safe or not. Or caller get the DEAD bit cleared, then access reloc_root, which is already NULL, nothing will be wrong.
The memory write barriers are between the reloc_root updates and bit set/clear, the pairing read side is before test_bit.
--- fs/btrfs/relocation.c | 51 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 5 deletions(-)
fs/btrfs/relocation.c +46 -5
@@ -517,6 +517,34 @@ static int update_backref_cache(struct breturn 1 ; } +static bool reloc_root_is_dead (struct btrfs_root *root) +{ +/* +* Pair with set_bit/clear_bit in clean_dirty_subvols and +* btrfs_update_reloc_root. We need to see the updated bit before +* trying to access reloc_root +*/ +smp_rmb (); +if (test_bit (BTRFS_ROOT_DEAD_RELOC_TREE , &root->state)) +return true; +return false; +} + +/* +* Check if this subvolume tree has valid reloc tree. +* +* Reloc tree after swap is considered dead, thus not considered as valid. +* This is enough for most callers, as they don't distinguish dead reloc root +* from no reloc root. But should_ignore_root() below is a special case. +*/ +static bool have_reloc_root (struct btrfs_root *root) +{ +if (reloc_root_is_dead (root)) +return false; +if (!root->reloc_root) +return false; +return true; +}static int should_ignore_root (struct btrfs_root *root) {
@@ -525,6 +553,10 @@ static int should_ignore_root(struct btrif (!test_bit (BTRFS_ROOT_REF_COWS , &root->state))return 0 ; +/* This root has been merged with its reloc tree, we can ignore it */ +if (reloc_root_is_dead (root)) +return 1 ; + reloc_root = root->reloc_root;if (!reloc_root)return 0 ;
@@ -1439,7 +1471,7 @@ int btrfs_init_reloc_root(struct btrfs_t* The subvolume has reloc tree but the swap is finished, no need to * create/update the dead reloc tree */ -if (test_bit (BTRFS_ROOT_DEAD_RELOC_TREE , &root->state)) +if (reloc_root_is_dead (root))return 0 ;if (root->reloc_root) {
@@ -1478,8 +1510,7 @@ int btrfs_update_reloc_root(struct btrfsstruct btrfs_root_item *root_item;int ret; -if (test_bit (BTRFS_ROOT_DEAD_RELOC_TREE , &root->state) || - !root->reloc_root) +if (!have_reloc_root (root)) goto out; reloc_root = root->reloc_root;
@@ -1489,6 +1520,11 @@ int btrfs_update_reloc_root(struct btrfsif (fs_info->reloc_ctl->merge_reloc_tree &&btrfs_root_refs (root_item) ==0 ) {set_bit (BTRFS_ROOT_DEAD_RELOC_TREE , &root->state); +/* +* Mark the tree as dead before we change reloc_root so +* have_reloc_root will not touch it from now on. +*/ +smp_wmb ();__del_reloc_root (reloc_root); }
@@ -2202,6 +2238,11 @@ static int clean_dirty_subvols(struct reif (ret2 <0 && !ret) ret = ret2; } +/* +* Need barrier to ensure clear_bit() only happens after +* root->reloc_root = NULL. Pairs with have_reloc_root. +*/ +smp_wmb ();clear_bit (BTRFS_ROOT_DEAD_RELOC_TREE , &root->state);btrfs_put_fs_root (root); }else {
@@ -4721,7 +4762,7 @@ void btrfs_reloc_pre_snapshot(struct btrstruct btrfs_root *root = pending->root;struct reloc_control *rc = root->fs_info->reloc_ctl; -if (!root->reloc_root || !rc) +if (!rc || !have_reloc_root (root))return ;if (!rc->merge_reloc_tree)
@@ -4755,7 +4796,7 @@ int btrfs_reloc_post_snapshot(struct btrstruct reloc_control *rc = root->fs_info->reloc_ctl;int ret; -if (!root->reloc_root || !rc) +if (!rc || !have_reloc_root (root))return 0 ; rc = root->fs_info->reloc_ctl;
Greg Kroah-Hartman
maintainerPATCH 87/222 btrfs: fix memory leak in qgroup accounting
In reply to Greg Kroah-HartmanFrom: Johannes Thumshirn <[email protected]>
commit 26ef8493e1ab771cb01d27defca2fa1315dc3980 upstream.
When running xfstests on the current btrfs I get the following splat from kmemleak:
unreferenced object 0xffff88821b2404e0 (size 32):
comm "kworker/u4:7", pid 26663, jiffies 4295283698 (age 8.776s) hex dump (first 32 bytes):
01 00 00 00 00 00 00 00 10 ff fd 26 82 88 ff ff ...........&....
10 ff fd 26 82 88 ff ff 20 ff fd 26 82 88 ff ff ...&.... ..&....
backtrace:
[<00000000f94fd43f>] ulist_alloc+0x25/0x60 [btrfs]
[<00000000fd023d99>] btrfs_find_all_roots_safe+0x41/0x100 [btrfs]
[<000000008f17bd32>] btrfs_find_all_roots+0x52/0x70 [btrfs]
[<00000000b7660afb>] btrfs_qgroup_rescan_worker+0x343/0x680 [btrfs]
[<0000000058e66778>] btrfs_work_helper+0xac/0x1e0 [btrfs]
[<00000000f0188930>] process_one_work+0x1cf/0x350
[<00000000af5f2f8e>] worker_thread+0x28/0x3c0
[<00000000b55a1add>] kthread+0x109/0x120
[<00000000f88cbd17>] ret_from_fork+0x35/0x40This corresponds to:
(gdb) l *(btrfs_find_all_roots_safe+0x41)
0x8d7e1 is in btrfs_find_all_roots_safe (fs/btrfs/backref.c:1413).
1408
1409 tmp = ulist_alloc(GFP_NOFS);
1410 if (!tmp)
1411 return -ENOMEM;
1412 *roots = ulist_alloc(GFP_NOFS);
1413 if (!*roots) {
1414 ulist_free(tmp);
1415 return -ENOMEM;
1416 }
1417Following the lifetime of the allocated 'roots' ulist, it gets freed again in btrfs_qgroup_account_extent().
But this does not happen if the function is called with the 'BTRFS_FS_QUOTA_ENABLED' flag cleared, then btrfs_qgroup_account_extent() does a short leave and directly returns.
Instead of directly returning we should jump to the 'out_free' in order to free all resources as expected.
--- fs/btrfs/qgroup.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
fs/btrfs/qgroup.c +5 -1
@@ -2423,8 +2423,12 @@ int btrfs_qgroup_account_extent(struct bu64 nr_old_roots =0 ;int ret =0 ; +/* +* If quotas get disabled meanwhile, the resouces need to be freed and +* we can't just exit here. +*/ if (!test_bit (BTRFS_FS_QUOTA_ENABLED , &fs_info->flags)) -return 0 ; + goto out_free;if (new_roots) {if (!maybe_fs_roots (new_roots))
Greg Kroah-Hartman
maintainerPATCH 88/222 btrfs: check rw_devices, not num_devices for balance
In reply to Greg Kroah-HartmanFrom: Josef Bacik <[email protected]>
commit b35cf1f0bf1f2b0b193093338414b9bd63b29015 upstream.
The fstest btrfs/154 reports
[ 8675.381709] BTRFS: Transaction aborted (error -28) [ 8675.383302] WARNING: CPU: 1 PID: 31900 at fs/btrfs/block-group.c:2038 btrfs_create_pending_block_groups+0x1e0/0x1f0 [btrfs] [ 8675.390925] CPU: 1 PID: 31900 Comm: btrfs Not tainted 5.5.0-rc6-default+ #935 [ 8675.392780] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.0-59-gc9ba527-rebuilt.opensuse.org 04/01/2014 [ 8675.395452] RIP: 0010:btrfs_create_pending_block_groups+0x1e0/0x1f0 [btrfs] [ 8675.402672] RSP: 0018:ffffb2090888fb00 EFLAGS: 00010286 [ 8675.404413] RAX: 0000000000000000 RBX: ffff92026dfa91c8 RCX: 0000000000000001 [ 8675.406609] RDX: 0000000000000000 RSI: ffffffff8e100899 RDI: ffffffff8e100971 [ 8675.408775] RBP: ffff920247c61660 R08: 0000000000000000 R09: 0000000000000000 [ 8675.410978] R10: 0000000000000000 R11: 0000000000000000 R12: 00000000ffffffe4 [ 8675.412647] R13: ffff92026db74000 R14: ffff920247c616b8 R15: ffff92026dfbc000 [ 8675.413994] FS: 00007fd5e57248c0(0000) GS:ffff92027d800000(0000) knlGS:0000000000000000 [ 8675.416146] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 8675.417833] CR2: 0000564aa51682d8 CR3: 000000006dcbc004 CR4: 0000000000160ee0 [ 8675.419801] Call Trace: [ 8675.420742] btrfs_start_dirty_block_groups+0x355/0x480 [btrfs] [ 8675.422600] btrfs_commit_transaction+0xc8/0xaf0 [btrfs] [ 8675.424335] reset_balance_state+0x14a/0x190 [btrfs] [ 8675.425824] btrfs_balance.cold+0xe7/0x154 [btrfs] [ 8675.427313] ? kmem_cache_alloc_trace+0x235/0x2c0 [ 8675.428663] btrfs_ioctl_balance+0x298/0x350 [btrfs] [ 8675.430285] btrfs_ioctl+0x466/0x2550 [btrfs] [ 8675.431788] ? mem_cgroup_charge_statistics+0x51/0xf0 [ 8675.433487] ? mem_cgroup_commit_charge+0x56/0x400 [ 8675.435122] ? do_raw_spin_unlock+0x4b/0xc0 [ 8675.436618] ? _raw_spin_unlock+0x1f/0x30 [ 8675.438093] ? __handle_mm_fault+0x499/0x740 [ 8675.439619] ? do_vfs_ioctl+0x56e/0x770 [ 8675.441034] do_vfs_ioctl+0x56e/0x770 [ 8675.442411] ksys_ioctl+0x3a/0x70 [ 8675.443718] ? trace_hardirqs_off_thunk+0x1a/0x1c [ 8675.445333] __x64_sys_ioctl+0x16/0x20 [ 8675.446705] do_syscall_64+0x50/0x210 [ 8675.448059] entry_SYSCALL_64_after_hwframe+0x49/0xbe [ 8675.479187] BTRFS: error (device vdb) in btrfs_create_pending_block_groups:2038: errno=-28 No space left
We now use btrfs_can_overcommit() to see if we can flip a block group read only. Before this would fail because we weren't taking into account the usable un-allocated space for allocating chunks. With my patches we were allowed to do the balance, which is technically correct.
The test is trying to start balance on degraded mount. So now we're trying to allocate a chunk and cannot because we want to allocate a RAID1 chunk, but there's only 1 device that's available for usage. This results in an ENOSPC.
But we shouldn't even be making it this far, we don't have enough devices to restripe. The problem is we're using btrfs_num_devices(), that also includes missing devices. That's not actually what we want, we need to use rw_devices.
The chunk_mutex is not needed here, rw_devices changes only in device add, remove or replace, all are excluded by EXCL_OP mechanism.
--- fs/btrfs/volumes.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
fs/btrfs/volumes.c +5 -1
@@ -4066,7 +4066,11 @@ int btrfs_balance(struct btrfs_fs_info * } } - num_devices =btrfs_num_devices (fs_info); +/* +* rw_devices will not change at the moment, device add/delete/replace +* are excluded by EXCL_OP +*/ + num_devices = fs_info->fs_devices->rw_devices;/* * SINGLE profile on-disk has no profile bit, but in-memory we have a
Greg Kroah-Hartman
maintainerPATCH 89/222 Btrfs: always copy scrub arguments back to user space
In reply to Greg Kroah-HartmanFrom: Filipe Manana <[email protected]>
commit 5afe6ce748c1ea99e0d648153c05075e1ab93afb upstream.
If scrub returns an error we are not copying back the scrub arguments structure to user space. This prevents user space to know how much progress scrub has done if an error happened - this includes -ECANCELED which is returned when users ask for scrub to stop. A particular use case, which is used in btrfs-progs, is to resume scrub after it is canceled, in that case it relies on checking the progress from the scrub arguments structure and then use that progress in a call to resume scrub.
So fix this by always copying the scrub arguments structure to user space, overwriting the value returned to user space with -EFAULT only if copying the structure failed to let user space know that either that copying did not happen, and therefore the structure is stale, or it happened partially and the structure is probably not valid and corrupt due to the partial copy.
--- fs/btrfs/ioctl.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)
fs/btrfs/ioctl.c +13 -1
@@ -4254,7 +4254,19 @@ static long btrfs_ioctl_scrub(struct fil &sa->progress, sa->flags &BTRFS_SCRUB_READONLY , 0); -if (ret ==0 &©_to_user (arg, sa,sizeof (*sa))) +/* +* Copy scrub args to user space even if btrfs_scrub_dev() returned an +* error. This is important as it allows user space to know how much +* progress scrub has done. For example, if scrub is canceled we get +* -ECANCELED from btrfs_scrub_dev() and return that error back to user +* space. Later user space can inspect the progress from the structure +* btrfs_ioctl_scrub_args and resume scrub from where it left off +* previously (btrfs-progs does this). +* If we fail to copy the btrfs_ioctl_scrub_args structure to user space +* then return -EFAULT to signal the structure was not copied or it may +* be corrupt and unreliable due to a partial copy. +*/ +if (copy_to_user (arg, sa,sizeof (*sa))) ret = -EFAULT ;if (!(sa->flags &BTRFS_SCRUB_READONLY ))
Greg Kroah-Hartman
maintainerPATCH 90/222 mm/memory_hotplug: dont free usage map when removing a re-added early section
In reply to Greg Kroah-HartmanFrom: David Hildenbrand <[email protected]>
commit 8068df3b60373c390198f660574ea14c8098de57 upstream.
When we remove an early section, we don't free the usage map, as the usage maps of other sections are placed into the same page. Once the section is removed, it is no longer an early section (especially, the memmap is freed). When we re-add that section, the usage map is reused, however, it is no longer an early section. When removing that section again, we try to kfree() a usage map that was allocated during early boot - bad.
Let's check against PageReserved() to see if we are dealing with an usage map that was allocated during boot. We could also check against !(PageSlab(usage_page) || PageCompound(usage_page)), but PageReserved() is cleaner.
Can be triggered using memtrace under ppc64/powernv:
$ mount -t debugfs none /sys/kernel/debug/
$ echo 0x20000000 > /sys/kernel/debug/powerpc/memtrace/enable
$ echo 0x20000000 > /sys/kernel/debug/powerpc/memtrace/enable
------------[ cut here ]------------
kernel BUG at mm/slub.c:3969!
Oops: Exception in kernel mode, sig: 5 [#1]
LE PAGE_SIZE=3D64K MMU=3DHash SMP NR_CPUS=3D2048 NUMA PowerNV
Modules linked in:
CPU: 0 PID: 154 Comm: sh Not tainted 5.5.0-rc2-next-20191216-00005-g0be1dba7b7c0 #61
NIP kfree+0x338/0x3b0
LR section_deactivate+0x138/0x200
Call Trace:
section_deactivate+0x138/0x200
__remove_pages+0x114/0x150
arch_remove_memory+0x3c/0x160
try_remove_memory+0x114/0x1a0
__remove_memory+0x20/0x40
memtrace_enable_set+0x254/0x850
simple_attr_write+0x138/0x160
full_proxy_write+0x8c/0x110
__vfs_write+0x38/0x70
vfs_write+0x11c/0x2a0
ksys_write+0x84/0x140
system_call+0x5c/0x68
---[ end trace 4b053cbd84e0db62 ]---The first invocation will offline+remove memory blocks. The second invocation will first add+online them again, in order to offline+remove them again (usually we are lucky and the exact same memory blocks will get "reallocated").
Tested on powernv with boot memory: The usage map will not get freed. Tested on x86-64 with DIMMs: The usage map will get freed.
Using Dynamic Memory under a Power DLAPR can trigger it easily.
Triggering removal (I assume after previously removed+re-added) of memory from the HMC GUI can crash the kernel with the same call trace and is fixed by this patch.
--- mm/sparse.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
mm/sparse.c +8 -1
@@ -775,7 +775,14 @@ static void section_deactivate(unsignedif (bitmap_empty (subsection_map,SUBSECTIONS_PER_SECTION )) {unsigned long section_nr =pfn_to_section_nr (pfn); -if (!section_is_early) { +/* +* When removing an early section, the usage map is kept (as the +* usage maps of other sections fall into the same page). It +* will be re-used when re-adding the section - which is then no +* longer an early section. If the usage map is PageReserved, it +* was allocated during boot. +*/ +if (!PageReserved (virt_to_page (ms->usage))) {kfree (ms->usage); ms->usage =NULL ; }
Greg Kroah-Hartman
maintainerPATCH 91/222 mm/page-writeback.c: avoid potential division by zero in wb_min_max_ratio()
In reply to Greg Kroah-HartmanFrom: Wen Yang <[email protected]>
commit 6d9e8c651dd979aa666bee15f086745f3ea9c4b3 upstream.
Patch series "use div64_ul() instead of div_u64() if the divisor is unsigned long".
We were first inspired by commit b0ab99e7736a ("sched: Fix possible divide by zero in avg_atom () calculation"), then refer to the recently analyzed mm code, we found this suspicious place.
201 if (min) {
202 min *= this_bw;
203 do_div(min, tot_bw);
204 }
And we also disassembled and confirmed it:
/usr/src/debug/kernel-4.9.168-016.ali3000/linux-4.9.168-016.ali3000.alios7.x86_64/mm/page-writeback.c: 201
0xffffffff811c37da <__wb_calc_thresh+234>: xor %r10d,%r10d 0xffffffff811c37dd <__wb_calc_thresh+237>: test %rax,%rax 0xffffffff811c37e0 <__wb_calc_thresh+240>: je 0xffffffff811c3800 <__wb_calc_thresh+272> /usr/src/debug/kernel-4.9.168-016.ali3000/linux-4.9.168-016.ali3000.alios7.x86_64/mm/page-writeback.c: 202 0xffffffff811c37e2 <__wb_calc_thresh+242>: imul %r8,%rax /usr/src/debug/kernel-4.9.168-016.ali3000/linux-4.9.168-016.ali3000.alios7.x86_64/mm/page-writeback.c: 203 0xffffffff811c37e6 <__wb_calc_thresh+246>: mov %r9d,%r10d ---> truncates it to 32 bits here 0xffffffff811c37e9 <__wb_calc_thresh+249>: xor %edx,%edx 0xffffffff811c37eb <__wb_calc_thresh+251>: div %r10 0xffffffff811c37ee <__wb_calc_thresh+254>: imul %rbx,%rax 0xffffffff811c37f2 <__wb_calc_thresh+258>: shr $0x2,%rax 0xffffffff811c37f6 <__wb_calc_thresh+262>: mul %rcx 0xffffffff811c37f9 <__wb_calc_thresh+265>: shr $0x2,%rdx 0xffffffff811c37fd <__wb_calc_thresh+269>: mov %rdx,%r10
This series uses div64_ul() instead of div_u64() if the divisor is unsigned long, to avoid truncation to 32-bit on 64-bit platforms.
This patch (of 3):
The variables 'min' and 'max' are unsigned long and do_div truncates them to 32 bits, which means it can test non-zero and be truncated to zero for division. Fix this issue by using div64_ul() instead.
--- mm/page-writeback.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
mm/page-writeback.c +2 -2
@@ -201,11 +201,11 @@ static void wb_min_max_ratio(struct bdi_if (this_bw < tot_bw) {if (min) { min *= this_bw; -do_div (min, tot_bw); + min =div64_ul (min, tot_bw); }if (max <100 ) { max *= this_bw; -do_div (max, tot_bw); + max =div64_ul (max, tot_bw); } }
Greg Kroah-Hartman
maintainerPATCH 92/222 mm: khugepaged: add trace status description for SCAN_PAGE_HAS_PRIVATE
In reply to Greg Kroah-HartmanFrom: Yang Shi <[email protected]>
commit 554913f600b45d73de12ad58c1ac7baa0f22a703 upstream.
Commit 99cb0dbd47a1 ("mm,thp: add read-only THP support for (non-shmem) FS") introduced a new khugepaged scan result: SCAN_PAGE_HAS_PRIVATE, but the corresponding description for trace events were not added.
--- include/trace/events/huge_memory.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
include/trace/events/huge_memory.h +2 -1
@@ -31,7 +31,8 @@ EM( SCAN_ALLOC_HUGE_PAGE_FAIL, "alloc_huge_page_failed") \ EM( SCAN_CGROUP_CHARGE_FAIL, "ccgroup_charge_failed") \ EM( SCAN_EXCEED_SWAP_PTE, "exceed_swap_pte") \ - EMe(SCAN_TRUNCATED, "truncated") \ + EM( SCAN_TRUNCATED, "truncated") \ + EMe(SCAN_PAGE_HAS_PRIVATE, "page_has_private") \#undef EM#undef EMe
Greg Kroah-Hartman
maintainerPATCH 93/222 ARM: dts: imx6qdl-sabresd: Remove incorrect power supply assignment
In reply to Greg Kroah-HartmanFrom: Anson Huang <[email protected]>
commit 4521de30fbb3f5be0db58de93582ebce72c9d44f upstream.
The vdd3p0 LDO's input should be from external USB VBUS directly, NOT PMIC's power supply, the vdd3p0 LDO's target output voltage can be controlled by SW, and it requires input voltage to be high enough, with incorrect power supply assigned, if the power supply's voltage is lower than the LDO target output voltage, it will return fail and skip the LDO voltage adjustment, so remove the power supply assignment for vdd3p0 to avoid such scenario.
--- arch/arm/boot/dts/imx6qdl-sabresd.dtsi | 4 ---- 1 file changed, 4 deletions(-)
arch/arm/boot/dts/imx6qdl-sabresd.dtsi +0 -4
@@ -749,10 +749,6 @@ vin-supply = <&vgen5_reg>; }; -®_vdd3p0 { - vin-supply = <&sw2_reg>; -}; - ®_vdd2p5 { vin-supply = <&vgen5_reg>; };
Greg Kroah-Hartman
maintainerPATCH 94/222 ARM: dts: imx6sx-sdb: Remove incorrect power supply assignment
In reply to Greg Kroah-HartmanFrom: Anson Huang <[email protected]>
commit d4918ebb5c256d26696a13e78ac68c146111191a upstream.
The vdd3p0 LDO's input should be from external USB VBUS directly, NOT PMIC's power supply, the vdd3p0 LDO's target output voltage can be controlled by SW, and it requires input voltage to be high enough, with incorrect power supply assigned, if the power supply's voltage is lower than the LDO target output voltage, it will return fail and skip the LDO voltage adjustment, so remove the power supply assignment for vdd3p0 to avoid such scenario.
--- arch/arm/boot/dts/imx6sx-sdb-reva.dts | 4 ---- arch/arm/boot/dts/imx6sx-sdb.dts | 4 ---- 2 files changed, 8 deletions(-)
arch/arm/boot/dts/imx6sx-sdb-reva.dts +0 -4
@@ -159,10 +159,6 @@ vin-supply = <&vgen6_reg>; }; -®_vdd3p0 { - vin-supply = <&sw2_reg>; -}; - ®_vdd2p5 { vin-supply = <&vgen6_reg>; };
arch/arm/boot/dts/imx6sx-sdb.dts +0 -4
@@ -141,10 +141,6 @@ vin-supply = <&vgen6_reg>; }; -®_vdd3p0 { - vin-supply = <&sw2_reg>; -}; - ®_vdd2p5 { vin-supply = <&vgen6_reg>; };
Greg Kroah-Hartman
maintainerPATCH 95/222 ARM: dts: imx6sl-evk: Remove incorrect power supply assignment
In reply to Greg Kroah-HartmanFrom: Anson Huang <[email protected]>
commit b4eb9ef0e29cd28c6fd684e0ab77bda824acb20e upstream.
The vdd3p0 LDO's input should be from external USB VBUS directly, NOT PMIC's power supply, the vdd3p0 LDO's target output voltage can be controlled by SW, and it requires input voltage to be high enough, with incorrect power supply assigned, if the power supply's voltage is lower than the LDO target output voltage, it will return fail and skip the LDO voltage adjustment, so remove the power supply assignment for vdd3p0 to avoid such scenario.
--- arch/arm/boot/dts/imx6sl-evk.dts | 4 ---- 1 file changed, 4 deletions(-)
arch/arm/boot/dts/imx6sl-evk.dts +0 -4
@@ -584,10 +584,6 @@ vin-supply = <&sw2_reg>; }; -®_vdd3p0 { - vin-supply = <&sw2_reg>; -}; - ®_vdd2p5 { vin-supply = <&sw2_reg>; };
Greg Kroah-Hartman
maintainerPATCH 96/222 ARM: dts: imx6sll-evk: Remove incorrect power supply assignment
In reply to Greg Kroah-HartmanFrom: Anson Huang <[email protected]>
commit 3479b2843c78ffb60247f522226ba68f93aee355 upstream.
The vdd3p0 LDO's input should be from external USB VBUS directly, NOT PMIC's power supply, the vdd3p0 LDO's target output voltage can be controlled by SW, and it requires input voltage to be high enough, with incorrect power supply assigned, if the power supply's voltage is lower than the LDO target output voltage, it will return fail and skip the LDO voltage adjustment, so remove the power supply assignment for vdd3p0 to avoid such scenario.
--- arch/arm/boot/dts/imx6sll-evk.dts | 4 ---- 1 file changed, 4 deletions(-)
arch/arm/boot/dts/imx6sll-evk.dts +0 -4
@@ -265,10 +265,6 @@ status = "okay"; }; -®_3p0 { - vin-supply = <&sw2_reg>; -}; - &snvs_poweroff { status = "okay"; };
Greg Kroah-Hartman
maintainerPATCH 97/222 ARM: dts: imx6q-icore-mipi: Use 1.5 version of i.Core MX6DL
In reply to Greg Kroah-HartmanFrom: Jagan Teki <[email protected]>
commit 4a132f60808ae3a751e107a373f8572012352d3c upstream.
The EDIMM STARTER KIT i.Core 1.5 MIPI Evaluation is based on the 1.5 version of the i.Core MX6 cpu module. The 1.5 version differs from the original one for a few details, including the ethernet PHY interface clock provider.
With this commit, the ethernet interface works properly:
SMSC LAN8710/LAN8720 2188000.ethernet-1:00: attached PHY driver
While before using the 1.5 version, ethernet failed to startup do to un-clocked PHY interface:
fec 2188000.ethernet eth0: could not attach to PHY
Similar fix has merged for i.Core MX6Q but missed to update for DL.
--- arch/arm/boot/dts/imx6dl-icore-mipi.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/boot/dts/imx6dl-icore-mipi.dts +1 -1
@@ -8,7 +8,7 @@ /dts-v1/; #include "imx6dl.dtsi" -#include "imx6qdl-icore.dtsi" +#include "imx6qdl-icore-1.5.dtsi" / { model = "Engicam i.CoreM6 DualLite/Solo MIPI Starter Kit";
Greg Kroah-Hartman
maintainerPATCH 98/222 ARM: dts: imx7: Fix Toradex Colibri iMX7S 256MB NAND flash support
In reply to Greg Kroah-HartmanFrom: Marcel Ziswiler <[email protected]>
commit 4b0b97e651ecf29f20248420b52b6864fbd40bc2 upstream.
Turns out when introducing the eMMC version the gpmi node required for NAND flash support got enabled exclusively on Colibri iMX7D 512MB.
--- arch/arm/boot/dts/imx7s-colibri.dtsi | 4 ++++ 1 file changed, 4 insertions(+)
arch/arm/boot/dts/imx7s-colibri.dtsi +4 -0
@@ -49,3 +49,7 @@ reg = <0x80000000 0x10000000>; }; }; + +&gpmi { + status = "okay"; +};
Greg Kroah-Hartman
maintainerPATCH 99/222 net: stmmac: 16KB buffer must be 16 byte aligned
In reply to Greg Kroah-HartmanFrom: Jose Abreu <[email protected]>
commit 8605131747e7e1fd8f6c9f97a00287aae2b2c640 upstream.
The 16KB RX Buffer must also be 16 byte aligned. Fix it.
--- drivers/net/ethernet/stmicro/stmmac/common.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/net/ethernet/stmicro/stmmac/common.h +2 -3
@@ -364,9 +364,8 @@ struct dma_features {unsigned int arpoffsel; }; -/* GMAC TX FIFO is 8K, Rx FIFO is 16K */ -#define BUF_SIZE_16KiB 16384 -/* RX Buffer size must be < 8191 and multiple of 4/8/16 bytes */ +/* RX Buffer size must be multiple of 4/8/16 bytes */ +#define BUF_SIZE_16KiB 16368#define BUF_SIZE_8KiB 8188#define BUF_SIZE_4KiB 4096#define BUF_SIZE_2KiB 2048
Greg Kroah-Hartman
maintainerPATCH 100/222 net: stmmac: Enable 16KB buffer size
In reply to Greg Kroah-HartmanFrom: Jose Abreu <[email protected]>
commit b2f3a481c4cd62f78391b836b64c0a6e72b503d2 upstream.
XGMAC supports maximum MTU that can go to 16KB. Lets add this check in the calculation of RX buffer size.
--- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +3 -1
@@ -1108,7 +1108,9 @@ static int stmmac_set_bfsize(int mtu, in {int ret = bufsize; -if (mtu >= BUF_SIZE_4KiB) +if (mtu >= BUF_SIZE_8KiB) + ret = BUF_SIZE_16KiB; +else if (mtu >= BUF_SIZE_4KiB) ret = BUF_SIZE_8KiB;else if (mtu >= BUF_SIZE_2KiB) ret = BUF_SIZE_4KiB;
Greg Kroah-Hartman
maintainerPATCH 101/222 reset: Fix {of,devm}_reset_control_array_get kerneldoc return types
In reply to Greg Kroah-HartmanFrom: Geert Uytterhoeven <[email protected]>
commit 723c0011c7f6992f57e2c629fa9c89141acc115f upstream.
of_reset_control_array_get() and devm_reset_control_array_get() return struct reset_control pointers, not internal struct reset_control_array pointers, just like all other reset control API calls.
Correct the kerneldoc to match the code.
--- drivers/reset/core.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/reset/core.c +2 -4
@@ -861,8 +861,7 @@ static int of_reset_control_get_count(st* @acquired: only one reset control may be acquired for a given controller * and ID * -* Returns pointer to allocated reset_control_array on success or -* error on failure +* Returns pointer to allocated reset_control on success or error on failure */ struct reset_control * of_reset_control_array_get(struct device_node *np, bool shared, bool optional,
@@ -915,8 +914,7 @@ EXPORT_SYMBOL_GPL(of_reset_control_array* that just have to be asserted or deasserted, without any * requirements on the order. * -* Returns pointer to allocated reset_control_array on success or -* error on failure +* Returns pointer to allocated reset_control on success or error on failure */ struct reset_control *devm_reset_control_array_get (struct device *dev,bool shared,bool optional)
Greg Kroah-Hartman
maintainerPATCH 102/222 tipc: fix potential hanging after b/rcast changing
In reply to Greg Kroah-HartmanFrom: Tuong Lien <[email protected]>
commit dca4a17d24ee9d878836ce5eb8dc25be1ffa5729 upstream.
In commit c55c8edafa91 ("tipc: smooth change between replicast and broadcast"), we allow instant switching between replicast and broadcast by sending a dummy 'SYN' packet on the last used link to synchronize packets on the links. The 'SYN' message is an object of link congestion also, so if that happens, a 'SOCK_WAKEUP' will be scheduled to be sent back to the socket...
However, in that commit, we simply use the same socket 'cong_link_cnt' counter for both the 'SYN' & normal payload message sending. Therefore, if both the replicast & broadcast links are congested, the counter will be not updated correctly but overwritten by the latter congestion. Later on, when the 'SOCK_WAKEUP' messages are processed, the counter is reduced one by one and eventually overflowed. Consequently, further activities on the socket will only wait for the false congestion signal to disappear but never been met.
Because sending the 'SYN' message is vital for the mechanism, it should be done anyway. This commit fixes the issue by marking the message with an error code e.g. 'TIPC_ERR_NO_PORT', so its sending should not face a link congestion, there is no need to touch the socket 'cong_link_cnt' either. In addition, in the event of any error (e.g. -ENOBUFS), we will purge the entire payload message queue and make a return immediately.
--- net/tipc/bcast.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-)
net/tipc/bcast.c +15 -9
@@ -305,17 +305,17 @@ static int tipc_rcast_xmit(struct net *n* @skb: socket buffer to copy * @method: send method to be used * @dests: destination nodes for message. -* @cong_link_cnt: returns number of encountered congested destination links * Returns 0 if success, otherwise errno */ static int tipc_mcast_send_sync (struct net *net,struct sk_buff *skb,struct tipc_mc_method *method, -struct tipc_nlist *dests, -u16 *cong_link_cnt) +struct tipc_nlist *dests) {struct tipc_msg *hdr, *_hdr;struct sk_buff_head tmpq;struct sk_buff *_skb; +u16 cong_link_cnt; +int rc =0 ;/* Is a cluster supporting with new capabilities ? */ if (!(tipc_net (net)->capabilities &TIPC_MCAST_RBCTL ))
@@ -343,18 +343,19 @@ static int tipc_mcast_send_sync(struct n _hdr =buf_msg (_skb);msg_set_size (_hdr,MCAST_H_SIZE );msg_set_is_rcast (_hdr, !msg_is_rcast (hdr)); +msg_set_errcode (_hdr,TIPC_ERR_NO_PORT );__skb_queue_head_init (&tmpq);__skb_queue_tail (&tmpq, _skb);if (method->rcast) -tipc_bcast_xmit (net, &tmpq, cong_link_cnt); + rc =tipc_bcast_xmit (net, &tmpq, &cong_link_cnt);else -tipc_rcast_xmit (net, &tmpq, dests, cong_link_cnt); + rc =tipc_rcast_xmit (net, &tmpq, dests, &cong_link_cnt);/* This queue should normally be empty by now */ __skb_queue_purge (&tmpq); -return 0 ; +return rc; }/* tipc_mcast_xmit - deliver message to indicated destination nodes
@@ -396,9 +397,14 @@ int tipc_mcast_xmit(struct net *net, strmsg_set_is_rcast (hdr, method->rcast);/* Switch method ? */ -if (rcast != method->rcast) -tipc_mcast_send_sync (net, skb, method, - dests, cong_link_cnt); +if (rcast != method->rcast) { + rc =tipc_mcast_send_sync (net, skb, method, dests); +if (unlikely (rc)) { +pr_err ("Unable to send SYN: method %d, rc %d\n" , + rcast, rc); + goto exit; + } + }if (method->rcast) rc =tipc_rcast_xmit (net, pkts, dests, cong_link_cnt);
Greg Kroah-Hartman
maintainerPATCH 103/222 tipc: fix retrans failure due to wrong destination
In reply to Greg Kroah-HartmanFrom: Tuong Lien <[email protected]>
commit abc9b4e0549b93fdaff56e9532bc49a2d7b04955 upstream.
When a user message is sent, TIPC will check if the socket has faced a congestion at link layer. If that happens, it will make a sleep to wait for the congestion to disappear. This leaves a gap for other users to take over the socket (e.g. multi threads) since the socket is released as well. Also, in case of connectionless (e.g. SOCK_RDM), user is free to send messages to various destinations (e.g. via 'sendto()'), then the socket's preformatted header has to be updated correspondingly prior to the actual payload message building.
Unfortunately, the latter action is done before the first action which causes a condition issue that the destination of a certain message can be modified incorrectly in the middle, leading to wrong destination when that message is built. Consequently, when the message is sent to the link layer, it gets stuck there forever because the peer node will simply reject it. After a number of retransmission attempts, the link is eventually taken down and the retransmission failure is reported.
This commit fixes the problem by rearranging the order of actions to prevent the race condition from occurring, so the message building is 'atomic' and its header will not be modified by anyone.
--- net/tipc/socket.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-)
net/tipc/socket.c +18 -14
@@ -1306,8 +1306,8 @@ static int __tipc_sendmsg(struct socketstruct tipc_msg *hdr = &tsk->phdr;struct tipc_name_seq *seq;struct sk_buff_head pkts; -u32 dport, dnode =0 ; -u32 type, inst; +u32 dport =0 , dnode =0 ; +u32 type =0 , inst =0 ;int mtu, rc;if (unlikely (dlen >TIPC_MAX_USER_MSG_SIZE ))
@@ -1360,23 +1360,11 @@ static int __tipc_sendmsg(struct socket type = dest->addr.name.name.type; inst = dest->addr.name.name.instance; dnode = dest->addr.name.domain; -msg_set_type (hdr,TIPC_NAMED_MSG ); -msg_set_hdr_sz (hdr,NAMED_H_SIZE ); -msg_set_nametype (hdr, type); -msg_set_nameinst (hdr, inst); -msg_set_lookup_scope (hdr,tipc_node2scope (dnode)); dport =tipc_nametbl_translate (net, type, inst, &dnode); -msg_set_destnode (hdr, dnode); -msg_set_destport (hdr, dport);if (unlikely (!dport && !dnode))return -EHOSTUNREACH ; }else if (dest->addrtype ==TIPC_ADDR_ID ) { dnode = dest->addr.id.node; -msg_set_type (hdr,TIPC_DIRECT_MSG ); -msg_set_lookup_scope (hdr,0 ); -msg_set_destnode (hdr, dnode); -msg_set_destport (hdr, dest->addr.id.ref); -msg_set_hdr_sz (hdr,BASIC_H_SIZE ); }else {return -EINVAL ; }
@@ -1387,6 +1375,22 @@ static int __tipc_sendmsg(struct socketif (unlikely (rc))return rc; +if (dest->addrtype ==TIPC_ADDR_NAME ) { +msg_set_type (hdr,TIPC_NAMED_MSG ); +msg_set_hdr_sz (hdr,NAMED_H_SIZE ); +msg_set_nametype (hdr, type); +msg_set_nameinst (hdr, inst); +msg_set_lookup_scope (hdr,tipc_node2scope (dnode)); +msg_set_destnode (hdr, dnode); +msg_set_destport (hdr, dport); + }else {/* TIPC_ADDR_ID */ +msg_set_type (hdr,TIPC_DIRECT_MSG ); +msg_set_lookup_scope (hdr,0 ); +msg_set_destnode (hdr, dnode); +msg_set_destport (hdr, dest->addr.id.ref); +msg_set_hdr_sz (hdr,BASIC_H_SIZE ); + } +__skb_queue_head_init (&pkts); mtu =tipc_node_get_mtu (net, dnode, tsk->portid); rc =tipc_msg_build (hdr, m,0 , dlen, mtu, &pkts);
Greg Kroah-Hartman
maintainerPATCH 104/222 net: fix kernel-doc warning in <linux/netdevice.h>
In reply to Greg Kroah-HartmanFrom: Randy Dunlap <[email protected]>
commit 1f26c0d3d24125992ab0026b0dab16c08df947c7 upstream.
Fix missing '*' kernel-doc notation that causes this warning:
../include/linux/netdevice.h:1779: warning: bad line: spinlock
--- include/linux/netdevice.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/netdevice.h +1 -1
@@ -1761,7 +1761,7 @@ enum netdev_priv_flags {* for hardware timestamping * @sfp_bus: attached &struct sfp_bus structure. * @qdisc_tx_busylock_key: lockdep class annotating Qdisc->busylock -spinlock +* spinlock * @qdisc_running_key: lockdep class annotating Qdisc->running seqcount * @qdisc_xmit_lock_key: lockdep class annotating * netdev_queue->_xmit_lock spinlock
Greg Kroah-Hartman
maintainerPATCH 105/222 block: Fix the type of sts in bsg_queue_rq()
In reply to Greg Kroah-HartmanFrom: Bart Van Assche <[email protected]>
commit c44a4edb20938c85b64a256661443039f5bffdea upstream.
This patch fixes the following sparse warnings:
block/bsg-lib.c:269:19: warning: incorrect type in initializer (different base types)block/bsg-lib.c:269:19: expected int stsblock/bsg-lib.c:269:19: got restricted blk_status_t [usertype]block/bsg-lib.c:286:16: warning: incorrect type in return expression (different base types)block/bsg-lib.c:286:16: expected restricted blk_status_tblock/bsg-lib.c:286:16: got int [assigned] sts
--- block/bsg-lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
block/bsg-lib.c +1 -1
@@ -266,7 +266,7 @@ static blk_status_t bsg_queue_rq(structstruct request *req = bd->rq;struct bsg_set *bset = container_of(q->tag_set, struct bsg_set, tag_set); -int sts =BLK_STS_IOERR ; +blk_status_t sts =BLK_STS_IOERR ;int ret;blk_mq_start_request (req);
Greg Kroah-Hartman
maintainerPATCH 106/222 drm/amd/display: Reorder detect_edp_sink_caps before link settings read.
In reply to Greg Kroah-HartmanFrom: Mario Kleiner <[email protected]>
[ Upstream commit 3b7c59754cc22760760a84ebddb8e0b1e8dd871b ]
read_current_link_settings_on_detect() on eDP 1.4+ may use the edp_supported_link_rates table which is set up by detect_edp_sink_caps(), so that function needs to be called first.
--- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/display/dc/core/dc_link.c +1 -1
@@ -809,8 +809,8 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason) }case SIGNAL_TYPE_EDP : { -read_edp_current_link_settings_on_detect (link);detect_edp_sink_caps (link); +read_edp_current_link_settings_on_detect (link); sink_caps.transaction_type =DDC_TRANSACTION_TYPE_I2C_OVER_AUX ; sink_caps.signal =SIGNAL_TYPE_EDP ;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 107/222 bpf: Fix incorrect verifier simulation of ARSH under ALU32
In reply to Greg Kroah-HartmanFrom: Daniel Borkmann <[email protected]>
commit 0af2ffc93a4b50948f9dad2786b7f1bd253bf0b9 upstream.
Anatoly has been fuzzing with kBdysch harness and reported a hang in one of the outcomes:
0: R1=ctx(id=0,off=0,imm=0) R10=fp0
0: (85) call bpf_get_socket_cookie#46
1: R0_w=invP(id=0) R10=fp0
1: (57) r0 &= 808464432
2: R0_w=invP(id=0,umax_value=808464432,var_off=(0x0; 0x30303030)) R10=fp0
2: (14) w0 -= 810299440
3: R0_w=invP(id=0,umax_value=4294967295,var_off=(0xcf800000; 0x3077fff0)) R10=fp0
3: (c4) w0 s>>= 1
4: R0_w=invP(id=0,umin_value=1740636160,umax_value=2147221496,var_off=(0x67c00000; 0x183bfff8)) R10=fp0 4: (76) if w0 s>= 0x30303030 goto pc+216
221: R0_w=invP(id=0,umin_value=1740636160,umax_value=2147221496,var_off=(0x67c00000; 0x183bfff8)) R10=fp0 221: (95) exit
processed 6 insns (limit 1000000) [...]
Taking a closer look, the program was xlated as follows:
# ./bpftool p d x i 12 0: (85) call bpf_get_socket_cookie#7800896 1: (bf) r6 = r0 2: (57) r6 &= 808464432 3: (14) w6 -= 810299440 4: (c4) w6 s>>= 1 5: (76) if w6 s>= 0x30303030 goto pc+216 6: (05) goto pc-1 7: (05) goto pc-1 8: (05) goto pc-1 [...] 220: (05) goto pc-1 221: (05) goto pc-1 222: (95) exit
Meaning, the visible effect is very similar to f54c7898ed1c ("bpf: Fix precision tracking for unbounded scalars"), that is, the fall-through branch in the instruction 5 is considered to be never taken given the conclusion from the min/max bounds tracking in w6, and therefore the dead-code sanitation rewrites it as goto pc-1. However, real-life input disagrees with verification analysis since a soft-lockup was observed.
The bug sits in the analysis of the ARSH. The definition is that we shift the target register value right by K bits through shifting in copies of its sign bit. In adjust_scalar_min_max_vals(), we do first coerce the register into 32 bit mode, same happens after simulating the operation. However, for the case of simulating the actual ARSH, we don't take the mode into account and act as if it's always 64 bit, but location of sign bit is different:
dst_reg->smin_value >>= umin_val; dst_reg->smax_value >>= umin_val; dst_reg->var_off = tnum_arshift(dst_reg->var_off, umin_val);
Consider an unknown R0 where bpf_get_socket_cookie() (or others) would for example return 0xffff. With the above ARSH simulation, we'd see the following results:
[...]
1: R1=ctx(id=0,off=0,imm=0) R2_w=invP65535 R10=fp0 1: (85) call bpf_get_socket_cookie#46
2: R0_w=invP(id=0) R10=fp0
2: (57) r0 &= 808464432
-> R0_runtime = 0x3030
3: R0_w=invP(id=0,umax_value=808464432,var_off=(0x0; 0x30303030)) R10=fp0
3: (14) w0 -= 810299440
-> R0_runtime = 0xcfb40000
4: R0_w=invP(id=0,umax_value=4294967295,var_off=(0xcf800000; 0x3077fff0)) R10=fp0
(0xffffffff)
4: (c4) w0 s>>= 1
-> R0_runtime = 0xe7da0000
5: R0_w=invP(id=0,umin_value=1740636160,umax_value=2147221496,var_off=(0x67c00000; 0x183bfff8)) R10=fp0
(0x67c00000) (0x7ffbfff8)[...]
In insn 3, we have a runtime value of 0xcfb40000, which is '1100 1111 1011 0100 0000 0000 0000 0000', the result after the shift has 0xe7da0000 that is '1110 0111 1101 1010 0000 0000 0000 0000', where the sign bit is correctly retained in 32 bit mode. In insn4, the umax was 0xffffffff, and changed into 0x7ffbfff8 after the shift, that is, '0111 1111 1111 1011 1111 1111 1111 1000' and means here that the simulation didn't retain the sign bit. With above logic, the updates happen on the 64 bit min/max bounds and given we coerced the register, the sign bits of the bounds are cleared as well, meaning, we need to force the simulation into s32 space for 32 bit alu mode.
Verification after the fix below. We're first analyzing the fall-through branch on 32 bit signed >= test eventually leading to rejection of the program in this specific case:
0: R1=ctx(id=0,off=0,imm=0) R10=fp0
0: (b7) r2 = 808464432
1: R1=ctx(id=0,off=0,imm=0) R2_w=invP808464432 R10=fp0
1: (85) call bpf_get_socket_cookie#46
2: R0_w=invP(id=0) R10=fp0
2: (bf) r6 = r0
3: R0_w=invP(id=0) R6_w=invP(id=0) R10=fp0
3: (57) r6 &= 808464432
4: R0_w=invP(id=0) R6_w=invP(id=0,umax_value=808464432,var_off=(0x0; 0x30303030)) R10=fp0
4: (14) w6 -= 810299440
5: R0_w=invP(id=0) R6_w=invP(id=0,umax_value=4294967295,var_off=(0xcf800000; 0x3077fff0)) R10=fp0 5: (c4) w6 s>>= 1
6: R0_w=invP(id=0) R6_w=invP(id=0,umin_value=3888119808,umax_value=4294705144,var_off=(0xe7c00000; 0x183bfff8)) R10=fp0
(0x67c00000) (0xfffbfff8)
6: (76) if w6 s>= 0x30303030 goto pc+216
7: R0_w=invP(id=0) R6_w=invP(id=0,umin_value=3888119808,umax_value=4294705144,var_off=(0xe7c00000; 0x183bfff8)) R10=fp0 7: (30) r0 = *(u8 *)skb[808464432]
BPF_LD_[ABS|IND] uses reserved fields
processed 8 insns (limit 1000000) [...]
--- include/linux/tnum.h | 2 +- kernel/bpf/tnum.c | 9 +++++++-- kernel/bpf/verifier.c | 13 ++++++++++--- 3 files changed, 18 insertions(+), 6 deletions(-)
include/linux/tnum.h +1 -1
@@ -30,7 +30,7 @@ struct tnum tnum_lshift(struct tnum a, u/* Shift (rsh) a tnum right (by a fixed shift) */ struct tnum tnum_rshift (struct tnum a,u8 shift);/* Shift (arsh) a tnum right (by a fixed min_shift) */ -struct tnum tnum_arshift (struct tnum a,u8 min_shift); +struct tnum tnum_arshift (struct tnum a,u8 min_shift,u8 insn_bitness);/* Add two tnums, return @a + @b */ struct tnum tnum_add (struct tnum a,struct tnum b);/* Subtract two tnums, return @a - @b */
kernel/bpf/tnum.c +7 -2
@@ -44,14 +44,19 @@ struct tnum tnum_rshift(struct tnum a, ureturn TNUM (a.value >> shift, a.mask >> shift); } -struct tnum tnum_arshift (struct tnum a,u8 min_shift) +struct tnum tnum_arshift (struct tnum a,u8 min_shift,u8 insn_bitness) {/* if a.value is negative, arithmetic shifting by minimum shift * will have larger negative offset compared to more shifting. * If a.value is nonnegative, arithmetic shifting by minimum shift * will have larger positive offset compare to more shifting. */ -return TNUM ((s64 )a.value >> min_shift, (s64 )a.mask >> min_shift); +if (insn_bitness ==32 ) +return TNUM ((u32)(((s32 )a.value) >> min_shift), + (u32)(((s32 )a.mask) >> min_shift)); +else +return TNUM ((s64 )a.value >> min_shift, + (s64 )a.mask >> min_shift); }struct tnum tnum_add (struct tnum a,struct tnum b)
kernel/bpf/verifier.c +10 -3
@@ -4824,9 +4824,16 @@ static int adjust_scalar_min_max_vals(st/* Upon reaching here, src_known is true and * umax_val is equal to umin_val. */ - dst_reg->smin_value >>= umin_val; - dst_reg->smax_value >>= umin_val; - dst_reg->var_off =tnum_arshift (dst_reg->var_off, umin_val); +if (insn_bitness ==32 ) { + dst_reg->smin_value = (u32)(((s32 )dst_reg->smin_value) >> umin_val); + dst_reg->smax_value = (u32)(((s32 )dst_reg->smax_value) >> umin_val); + }else { + dst_reg->smin_value >>= umin_val; + dst_reg->smax_value >>= umin_val; + } + + dst_reg->var_off =tnum_arshift (dst_reg->var_off, umin_val, + insn_bitness);/* blow away the dst_reg umin_value/umax_value and rely on * dst_reg var_off to refine the result.
Greg Kroah-Hartman
maintainerPATCH 108/222 bpf: Sockmap/tls, during free we may call tcp_bpf_unhash() in loop
In reply to Greg Kroah-HartmanFrom: John Fastabend <[email protected]>
commit 4da6a196f93b1af7612340e8c1ad8ce71e18f955 upstream.
When a sockmap is free'd and a socket in the map is enabled with tls we tear down the bpf context on the socket, the psock struct and state, and then call tcp_update_ulp(). The tcp_update_ulp() call is to inform the tls stack it needs to update its saved sock ops so that when the tls socket is later destroyed it doesn't try to call the now destroyed psock hooks.
This is about keeping stacked ULPs in good shape so they always have the right set of stacked ops.
However, recently unhash() hook was removed from TLS side. But, the sockmap/bpf side is not doing any extra work to update the unhash op when is torn down instead expecting TLS side to manage it. So both TLS and sockmap believe the other side is managing the op and instead no one updates the hook so it continues to point at tcp_bpf_unhash(). When unhash hook is called we call tcp_bpf_unhash() which detects the psock has already been destroyed and calls sk->sk_prot_unhash() which calls tcp_bpf_unhash() yet again and so on looping and hanging the core.
To fix have sockmap tear down logic fixup the stale pointer.
--- include/linux/skmsg.h | 1 + 1 file changed, 1 insertion(+)
include/linux/skmsg.h +1 -0
@@ -354,6 +354,7 @@ static inline void sk_psock_update_protostatic inline void sk_psock_restore_proto (struct sock *sk,struct sk_psock *psock) { + sk->sk_prot->unhash = psock->saved_unhash; sk->sk_write_space = psock->saved_write_space;if (psock->sk_proto) {
Greg Kroah-Hartman
maintainerPATCH 109/222 bpf: Sockmap, ensure sock lock held during tear down
In reply to Greg Kroah-HartmanFrom: John Fastabend <[email protected]>
commit 7e81a35302066c5a00b4c72d83e3ea4cad6eeb5b upstream.
The sock_map_free() and sock_hash_free() paths used to delete sockmap and sockhash maps walk the maps and destroy psock and bpf state associated with the socks in the map. When done the socks no longer have BPF programs attached and will function normally. This can happen while the socks in the map are still "live" meaning data may be sent/received during the walk.
Currently, though we don't take the sock_lock when the psock and bpf state is removed through this path. Specifically, this means we can be writing into the ops structure pointers such as sendmsg, sendpage, recvmsg, etc. while they are also being called from the networking side. This is not safe, we never used proper READ_ONCE/WRITE_ONCE semantics here if we believed it was safe. Further its not clear to me its even a good idea to try and do this on "live" sockets while networking side might also be using the socket. Instead of trying to reason about using the socks from both sides lets realize that every use case I'm aware of rarely deletes maps, in fact kubernetes/Cilium case builds map at init and never tears it down except on errors. So lets do the simple fix and grab sock lock.
This patch wraps sock deletes from maps in sock lock and adds some annotations so we catch any other cases easier.
--- net/core/skmsg.c | 2 ++ net/core/sock_map.c | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-)
net/core/skmsg.c +2 -0
@@ -594,6 +594,8 @@ EXPORT_SYMBOL_GPL(sk_psock_destroy);void sk_psock_drop (struct sock *sk,struct sk_psock *psock) { +sock_owned_by_me (sk); +sk_psock_cork_free (psock);sk_psock_zap_ingress (psock);
net/core/sock_map.c +6 -1
@@ -241,8 +241,11 @@ static void sock_map_free(struct bpf_mapstruct sock *sk; sk =xchg (psk,NULL ); -if (sk) +if (sk) { +lock_sock (sk);sock_map_unref (sk, psk); +release_sock (sk); + } }raw_spin_unlock_bh (&stab->lock);rcu_read_unlock ();
@@ -862,7 +865,9 @@ static void sock_hash_free(struct bpf_maraw_spin_lock_bh (&bucket->lock);hlist_for_each_entry_safe (elem, node, &bucket->head, node) {hlist_del_rcu (&elem->node); +lock_sock (elem->sk);sock_map_unref (elem->sk, elem); +release_sock (elem->sk); }raw_spin_unlock_bh (&bucket->lock); }
Greg Kroah-Hartman
maintainerPATCH 110/222 bpf: Sockmap/tls, push write_space updates through ulp updates
In reply to Greg Kroah-HartmanFrom: John Fastabend <[email protected]>
commit 33bfe20dd7117dd81fd896a53f743a233e1ad64f upstream.
When sockmap sock with TLS enabled is removed we cleanup bpf/psock state and call tcp_update_ulp() to push updates to TLS ULP on top. However, we don't push the write_space callback up and instead simply overwrite the op with the psock stored previous op. This may or may not be correct so to ensure we don't overwrite the TLS write space hook pass this field to the ULP and have it fixup the ctx.
This completes a previous fix that pushed the ops through to the ULP but at the time missed doing this for write_space, presumably because write_space TLS hook was added around the same time.
--- include/linux/skmsg.h | 12 ++++++++---- include/net/tcp.h | 6 ++++-- net/ipv4/tcp_ulp.c | 6 ++++-- net/tls/tls_main.c | 10 +++++++--- 4 files changed, 23 insertions(+), 11 deletions(-)
include/linux/skmsg.h +8 -4
@@ -355,17 +355,21 @@ static inline void sk_psock_restore_prot struct sk_psock *psock) { sk->sk_prot->unhash = psock->saved_unhash; - sk->sk_write_space = psock->saved_write_space;if (psock->sk_proto) {struct inet_connection_sock *icsk =inet_csk (sk);bool has_ulp = !!icsk->icsk_ulp_data; -if (has_ulp) -tcp_update_ulp (sk, psock->sk_proto); -else +if (has_ulp) { +tcp_update_ulp (sk, psock->sk_proto, + psock->saved_write_space); + }else { sk->sk_prot = psock->sk_proto; + sk->sk_write_space = psock->saved_write_space; + } psock->sk_proto =NULL ; + }else { + sk->sk_write_space = psock->saved_write_space; } }
include/net/tcp.h +4 -2
@@ -2132,7 +2132,8 @@ struct tcp_ulp_ops {/* initialize ulp */ int (*init)(struct sock *sk);/* update ulp */ -void (*update)(struct sock *sk,struct proto *p); +void (*update)(struct sock *sk,struct proto *p, +void (*write_space)(struct sock *sk));/* cleanup ulp */ void (*release)(struct sock *sk);/* diagnostic */
@@ -2147,7 +2148,8 @@ void tcp_unregister_ulp(struct tcp_ulp_oint tcp_set_ulp (struct sock *sk,const char *name);void tcp_get_available_ulp (char *buf,size_t len);void tcp_cleanup_ulp (struct sock *sk); -void tcp_update_ulp (struct sock *sk,struct proto *p); +void tcp_update_ulp (struct sock *sk,struct proto *p, +void (*write_space)(struct sock *sk));#define MODULE_ALIAS_TCP_ULP (name) \ __MODULE_INFO(alias, alias_userspace, name); \
net/ipv4/tcp_ulp.c +4 -2
@@ -96,17 +96,19 @@ void tcp_get_available_ulp(char *buf, sircu_read_unlock (); } -void tcp_update_ulp (struct sock *sk,struct proto *proto) +void tcp_update_ulp (struct sock *sk,struct proto *proto, +void (*write_space)(struct sock *sk)) {struct inet_connection_sock *icsk =inet_csk (sk);if (!icsk->icsk_ulp_ops) { + sk->sk_write_space = write_space; sk->sk_prot = proto;return ; }if (icsk->icsk_ulp_ops->update) - icsk->icsk_ulp_ops->update (sk, proto); + icsk->icsk_ulp_ops->update (sk, proto, write_space); }void tcp_cleanup_ulp (struct sock *sk)
net/tls/tls_main.c +7 -3
@@ -798,15 +798,19 @@ out:return rc; } -static void tls_update (struct sock *sk,struct proto *p) +static void tls_update (struct sock *sk,struct proto *p, +void (*write_space)(struct sock *sk)) {struct tls_context *ctx; ctx =tls_get_ctx (sk); -if (likely (ctx)) +if (likely (ctx)) { + ctx->sk_write_space = write_space; ctx->sk_proto = p; -else + }else { sk->sk_prot = p; + sk->sk_write_space = write_space; + } }static int tls_get_info (const struct sock *sk,struct sk_buff *skb)
Greg Kroah-Hartman
maintainerPATCH 111/222 bpf: Sockmap, skmsg helper overestimates push, pull, and pop bounds
In reply to Greg Kroah-HartmanFrom: John Fastabend <[email protected]>
commit 6562e29cf6f0ddd368657d97a8d484ffc30df5ef upstream.
In the push, pull, and pop helpers operating on skmsg objects to make data writable or insert/remove data we use this bounds check to ensure specified data is valid,
/* Bounds checks: start and pop must be inside message */ if (start >= offset + l || last >= msg->sg.size)
return -EINVAL;
The problem here is offset has already included the length of the current element the 'l' above. So start could be past the end of the scatterlist element in the case where start also points into an offset on the last skmsg element.
To fix do the accounting slightly different by adding the length of the previous entry to offset at the start of the iteration. And ensure its initialized to zero so that the first iteration does nothing.
--- net/core/filter.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
net/core/filter.c +5 -5
@@ -2231,10 +2231,10 @@ BPF_CALL_4(bpf_msg_pull_data, struct sk_/* First find the starting scatterlist element */ i = msg->sg.start;do { + offset += len; len =sk_msg_elem (msg, i)->length;if (start < offset + len)break ; - offset += len;sk_msg_iter_var_next (i); }while (i != msg->sg.end);
@@ -2346,7 +2346,7 @@ BPF_CALL_4(bpf_msg_push_data, struct sk_ u32, len, u64, flags) {struct scatterlist sge, nsge, nnsge, rsge = {0 }, *psge; -u32 new, i =0 , l, space, copy =0 , offset =0 ; +u32 new, i =0 , l =0 , space, copy =0 , offset =0 ;u8 *raw, *to, *from;struct page *page;
@@ -2356,11 +2356,11 @@ BPF_CALL_4(bpf_msg_push_data, struct sk_/* First find the starting scatterlist element */ i = msg->sg.start;do { + offset += l; l =sk_msg_elem (msg, i)->length;if (start < offset + l)break ; - offset += l;sk_msg_iter_var_next (i); }while (i != msg->sg.end);
@@ -2506,7 +2506,7 @@ static void sk_msg_shift_right(struct sk BPF_CALL_4(bpf_msg_pop_data, struct sk_msg *, msg, u32, start, u32, len, u64, flags) { -u32 i =0 , l, space, offset =0 ; +u32 i =0 , l =0 , space, offset =0 ;u64 last = start + len;int pop;
@@ -2516,11 +2516,11 @@ BPF_CALL_4(bpf_msg_pop_data, struct sk_m/* First find the starting scatterlist element */ i = msg->sg.start;do { + offset += l; l =sk_msg_elem (msg, i)->length;if (start < offset + l)break ; - offset += l;sk_msg_iter_var_next (i); }while (i != msg->sg.end);
Greg Kroah-Hartman
maintainerPATCH 112/222 bpf: Sockmap/tls, msg_push_data may leave end mark in place
In reply to Greg Kroah-HartmanFrom: John Fastabend <[email protected]>
commit cf21e9ba1eb86c9333ca5b05b2f1cc94021bcaef upstream.
Leaving an incorrect end mark in place when passing to crypto layer will cause crypto layer to stop processing data before all data is encrypted. To fix clear the end mark on push data instead of expecting users of the helper to clear the mark value after the fact.
This happens when we push data into the middle of a skmsg and have room for it so we don't do a set of copies that already clear the end flag.
--- net/core/filter.c | 1 + 1 file changed, 1 insertion(+)
net/core/filter.c +1 -0
@@ -2415,6 +2415,7 @@ BPF_CALL_4(bpf_msg_push_data, struct sk_sk_msg_iter_var_next (i);sg_unmark_end (psge); +sg_unmark_end (&rsge);sk_msg_iter_next (msg, end); }
Greg Kroah-Hartman
maintainerPATCH 113/222 bpf: Sockmap/tls, tls_sw can create a plaintext buf > encrypt buf
In reply to Greg Kroah-HartmanFrom: John Fastabend <[email protected]>
commit d468e4775c1c351616947ba0cccc43273963b9b5 upstream.
It is possible to build a plaintext buffer using push helper that is larger than the allocated encrypt buffer. When this record is pushed to crypto layers this can result in a NULL pointer dereference because the crypto API expects the encrypt buffer is large enough to fit the plaintext buffer. Kernel splat below.
To resolve catch the cases this can happen and split the buffer into two records to send individually. Unfortunately, there is still one case to handle where the split creates a zero sized buffer. In this case we merge the buffers and unmark the split. This happens when apply is zero and user pushed data beyond encrypt buffer. This fixes the original case as well because the split allocated an encrypt buffer larger than the plaintext buffer and the merge simply moves the pointers around so we now have a reference to the new (larger) encrypt buffer.
Perhaps its not ideal but it seems the best solution for a fixes branch and avoids handling these two cases, (a) apply that needs split and (b) non apply case. The are edge cases anyways so optimizing them seems not necessary unless someone wants later in next branches.
[ 306.719107] BUG: kernel NULL pointer dereference, address: 0000000000000008 [...] [ 306.747260] RIP: 0010:scatterwalk_copychunks+0x12f/0x1b0 [...] [ 306.770350] Call Trace: [ 306.770956] scatterwalk_map_and_copy+0x6c/0x80 [ 306.772026] gcm_enc_copy_hash+0x4b/0x50 [ 306.772925] gcm_hash_crypt_remain_continue+0xef/0x110 [ 306.774138] gcm_hash_crypt_continue+0xa1/0xb0 [ 306.775103] ? gcm_hash_crypt_continue+0xa1/0xb0 [ 306.776103] gcm_hash_assoc_remain_continue+0x94/0xa0 [ 306.777170] gcm_hash_assoc_continue+0x9d/0xb0 [ 306.778239] gcm_hash_init_continue+0x8f/0xa0 [ 306.779121] gcm_hash+0x73/0x80 [ 306.779762] gcm_encrypt_continue+0x6d/0x80 [ 306.780582] crypto_gcm_encrypt+0xcb/0xe0 [ 306.781474] crypto_aead_encrypt+0x1f/0x30 [ 306.782353] tls_push_record+0x3b9/0xb20 [tls] [ 306.783314] ? sk_psock_msg_verdict+0x199/0x300 [ 306.784287] bpf_exec_tx_verdict+0x3f2/0x680 [tls] [ 306.785357] tls_sw_sendmsg+0x4a3/0x6a0 [tls]
test_sockmap test signature to trigger bug,
[TEST]: (1, 1, 1, sendmsg, pass,redir,start 1,end 2,pop (1,2),ktls,):
--- net/tls/tls_sw.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)
net/tls/tls_sw.c +20 -0
@@ -677,12 +677,32 @@ static int tls_push_record(struct sock * split_point = msg_pl->apply_bytes; split = split_point && split_point < msg_pl->sg.size; +if (unlikely ((!split && + msg_pl->sg.size + + prot->overhead_size > msg_en->sg.size) || + (split && + split_point + + prot->overhead_size > msg_en->sg.size))) { + split = true; + split_point = msg_en->sg.size; + }if (split) { rc =tls_split_open_record (sk, rec, &tmp, msg_pl, msg_en, split_point, prot->overhead_size, &orig_end);if (rc <0 )return rc; +/* This can happen if above tls_split_open_record allocates +* a single large encryption buffer instead of two smaller +* ones. In this case adjust pointers and continue without +* split. +*/ +if (!msg_pl->sg.size) { +tls_merge_open_record (sk, rec, tmp, orig_end); + msg_pl = &rec->msg_plaintext; + msg_en = &rec->msg_encrypted; + split = false; + }sk_msg_trim (sk, msg_en, msg_pl->sg.size + prot->overhead_size); }
Greg Kroah-Hartman
maintainerPATCH 114/222 bpf: Sockmap/tls, skmsg can have wrapped skmsg that needs extra chaining
In reply to Greg Kroah-HartmanFrom: John Fastabend <[email protected]>
commit 9aaaa56845a06aeabdd597cbe19492dc01f281ec upstream.
Its possible through a set of push, pop, apply helper calls to construct a skmsg, which is just a ring of scatterlist elements, with the start value larger than the end value. For example,
end start
|_0_|_1_| ... |_n_|_n+1_|
Where end points at 1 and start points and n so that valid elements is the set {n, n+1, 0, 1}.
Currently, because we don't build the correct chain only {n, n+1} will be sent. This adds a check and sg_chain call to correctly submit the above to the crypto and tls send path.
--- net/tls/tls_sw.c | 6 ++++++ 1 file changed, 6 insertions(+)
net/tls/tls_sw.c +6 -0
@@ -724,6 +724,12 @@ static int tls_push_record(struct sock *sg_mark_end (sk_msg_elem (msg_pl, i)); } +if (msg_pl->sg.end < msg_pl->sg.start) { +sg_chain (&msg_pl->sg.data[msg_pl->sg.start], +MAX_SKB_FRAGS - msg_pl->sg.start +1 , + msg_pl->sg.data); + } + i = msg_pl->sg.start;sg_chain (rec->sg_aead_in,2 , &msg_pl->sg.data[i]);
Greg Kroah-Hartman
maintainerPATCH 115/222 bpf: Sockmap/tls, fix pop data with SK_DROP return code
In reply to Greg Kroah-HartmanFrom: John Fastabend <[email protected]>
commit 7361d44896ff20d48bdd502d1a0cd66308055d45 upstream.
When user returns SK_DROP we need to reset the number of copied bytes to indicate to the user the bytes were dropped and not sent. If we don't reset the copied arg sendmsg will return as if those bytes were copied giving the user a positive return value.
This works as expected today except in the case where the user also pops bytes. In the pop case the sg.size is reduced but we don't correctly account for this when copied bytes is reset. The popped bytes are not accounted for and we return a small positive value potentially confusing the user.
The reason this happens is due to a typo where we do the wrong comparison when accounting for pop bytes. In this fix notice the if/else is not needed and that we have a similar problem if we push data except its not visible to the user because if delta is larger the sg.size we return a negative value so it appears as an error regardless.
--- net/ipv4/tcp_bpf.c | 5 +---- net/tls/tls_sw.c | 5 +---- 2 files changed, 2 insertions(+), 8 deletions(-)
net/ipv4/tcp_bpf.c +1 -4
@@ -315,10 +315,7 @@ more_data:*/ delta = msg->sg.size; psock->eval =sk_psock_msg_verdict (sk, psock, msg); -if (msg->sg.size < delta) - delta -= msg->sg.size; -else - delta =0 ; + delta -= msg->sg.size; } if (msg->cork_bytes &&
net/tls/tls_sw.c +1 -4
@@ -804,10 +804,7 @@ more_data:if (psock->eval == __SK_NONE) { delta = msg->sg.size; psock->eval =sk_psock_msg_verdict (sk, psock, msg); -if (delta < msg->sg.size) - delta -= msg->sg.size; -else - delta =0 ; + delta -= msg->sg.size; }if (msg->cork_bytes && msg->cork_bytes > msg->sg.size && !enospc && !full_record) {
Greg Kroah-Hartman
maintainerPATCH 116/222 i2c: tegra: Fix suspending in active runtime PM state
In reply to Greg Kroah-HartmanFrom: Dmitry Osipenko <[email protected]>
commit 9f42de8d4ec2304f10bbc51dc0484f3503d61196 upstream.
I noticed that sometime I2C clock is kept enabled during suspend-resume. This happens because runtime PM defers dynamic suspension and thus it may happen that runtime PM is in active state when system enters into suspend. In particular I2C controller that is used for CPU's DVFS is often kept ON during suspend because CPU's voltage scaling happens quite often.
--- drivers/i2c/busses/i2c-tegra.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/i2c/busses/i2c-tegra.c +9 -0
@@ -1710,9 +1710,14 @@ static int tegra_i2c_remove(struct platfstatic int __maybe_unused tegra_i2c_suspend (struct device *dev) {struct tegra_i2c_dev *i2c_dev =dev_get_drvdata (dev); +int err;i2c_mark_adapter_suspended (&i2c_dev->adapter); + err =pm_runtime_force_suspend (dev); +if (err <0 ) +return err; +return 0 ; }
@@ -1733,6 +1738,10 @@ static int __maybe_unused tegra_i2c_resuif (err)return err; + err =pm_runtime_force_resume (dev); +if (err <0 ) +return err; +i2c_mark_adapter_resumed (&i2c_dev->adapter);return 0 ;
Greg Kroah-Hartman
maintainerPATCH 117/222 i2c: tegra: Properly disable runtime PM on drivers probe error
In reply to Greg Kroah-HartmanFrom: Dmitry Osipenko <[email protected]>
commit 24a49678f5e20f18006e71b90ac1531876b27eb1 upstream.
One of the recent Tegra I2C commits made a change that resumes runtime PM during driver's probe, but it missed to put the RPM in a case of error. Note that it's not correct to use pm_runtime_status_suspended because it breaks RPM refcounting.
--- drivers/i2c/busses/i2c-tegra.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-)
drivers/i2c/busses/i2c-tegra.c +19 -10
@@ -1608,14 +1608,18 @@ static int tegra_i2c_probe(struct platfo }pm_runtime_enable (&pdev->dev); -if (!pm_runtime_enabled (&pdev->dev)) +if (!pm_runtime_enabled (&pdev->dev)) { ret =tegra_i2c_runtime_resume (&pdev->dev); -else +if (ret <0 ) { +dev_err (&pdev->dev,"runtime resume failed\n" ); + goto unprepare_div_clk; + } + }else { ret =pm_runtime_get_sync (i2c_dev->dev); - -if (ret <0 ) { -dev_err (&pdev->dev,"runtime resume failed\n" ); - goto unprepare_div_clk; +if (ret <0 ) { +dev_err (&pdev->dev,"runtime resume failed\n" ); + goto disable_rpm; + } }if (i2c_dev->is_multimaster_mode) {
@@ -1623,7 +1627,7 @@ static int tegra_i2c_probe(struct platfoif (ret <0 ) {dev_err (i2c_dev->dev,"div_clk enable failed %d\n" , ret); - goto disable_rpm; + goto put_rpm; } }
@@ -1671,11 +1675,16 @@ disable_div_clk:if (i2c_dev->is_multimaster_mode)clk_disable (i2c_dev->div_clk); -disable_rpm: -pm_runtime_disable (&pdev->dev); -if (!pm_runtime_status_suspended (&pdev->dev)) +put_rpm: +if (pm_runtime_enabled (&pdev->dev)) +pm_runtime_put_sync (&pdev->dev); +else tegra_i2c_runtime_suspend (&pdev->dev); +disable_rpm: +if (pm_runtime_enabled (&pdev->dev)) +pm_runtime_disable (&pdev->dev); + unprepare_div_clk:clk_unprepare (i2c_dev->div_clk);
Greg Kroah-Hartman
maintainerPATCH 118/222 cfg80211: fix deadlocks in autodisconnect work
In reply to Greg Kroah-HartmanFrom: Markus Theil <[email protected]>
commit 5a128a088a2ab0b5190eeb232b5aa0b1017a0317 upstream.
Use methods which do not try to acquire the wdev lock themselves.
--- net/wireless/sme.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
net/wireless/sme.c +3 -3
@@ -1307,14 +1307,14 @@ void cfg80211_autodisconnect_wk(struct wif (wdev->conn_owner_nlportid) {switch (wdev->iftype) {case NL80211_IFTYPE_ADHOC : -cfg80211_leave_ibss (rdev, wdev->netdev, false); +__cfg80211_leave_ibss (rdev, wdev->netdev, false);break ;case NL80211_IFTYPE_AP :case NL80211_IFTYPE_P2P_GO : -cfg80211_stop_ap (rdev, wdev->netdev, false); +__cfg80211_stop_ap (rdev, wdev->netdev, false);break ;case NL80211_IFTYPE_MESH_POINT : -cfg80211_leave_mesh (rdev, wdev->netdev); +__cfg80211_leave_mesh (rdev, wdev->netdev);break ;case NL80211_IFTYPE_STATION :case NL80211_IFTYPE_P2P_CLIENT :
Greg Kroah-Hartman
maintainerPATCH 119/222 cfg80211: fix memory leak in nl80211_probe_mesh_link
In reply to Greg Kroah-HartmanFrom: Felix Fietkau <[email protected]>
commit 2a279b34169e9bbf7c240691466420aba75b4175 upstream.
The per-tid statistics need to be released after the call to rdev_get_station
--- net/wireless/nl80211.c | 2 ++ 1 file changed, 2 insertions(+)
net/wireless/nl80211.c +2 -0
@@ -13787,6 +13787,8 @@ static int nl80211_probe_mesh_link(strucif (err)return err; +cfg80211_sinfo_release_content (&sinfo); +return rdev_probe_mesh_link (rdev, dev, dest, buf, len); }
Greg Kroah-Hartman
maintainerPATCH 120/222 cfg80211: fix memory leak in cfg80211_cqm_rssi_update
In reply to Greg Kroah-HartmanFrom: Felix Fietkau <[email protected]>
commit df16737d438f534d0cc9948c7c5158f1986c5c87 upstream.
The per-tid statistics need to be released after the call to rdev_get_station
--- net/wireless/nl80211.c | 1 + 1 file changed, 1 insertion(+)
net/wireless/nl80211.c +1 -0
@@ -10834,6 +10834,7 @@ static int cfg80211_cqm_rssi_update(struif (err)return err; +cfg80211_sinfo_release_content (&sinfo);if (sinfo.filled &BIT_ULL (NL80211_STA_INFO_BEACON_SIGNAL_AVG )) wdev->cqm_config->last_rssi_event_value = (s8 ) sinfo.rx_beacon_signal_avg;
Greg Kroah-Hartman
maintainerPATCH 121/222 cfg80211: fix page refcount issue in A-MSDU decap
In reply to Greg Kroah-HartmanFrom: Felix Fietkau <[email protected]>
commit 81c044fc3bdc5b7be967cd3682528ea94b58c06a upstream.
The fragments attached to a skb can be part of a compound page. In that case, page_ref_inc will increment the refcount for the wrong page. Fix this by using get_page instead, which calls page_ref_inc on the compound head and also checks for overflow.
--- net/wireless/util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/wireless/util.c +1 -1
@@ -564,7 +564,7 @@ __frame_add_frag(struct sk_buff *skb, ststruct skb_shared_info *sh =skb_shinfo (skb);int page_offset; -page_ref_inc (page); +get_page (page); page_offset = ptr -page_address (page);skb_add_rx_frag (skb, sh->nr_frags, page, page_offset, len, size); }
Greg Kroah-Hartman
maintainerPATCH 122/222 bpf/sockmap: Read psock ingress_msg before sk_receive_queue
In reply to Greg Kroah-HartmanFrom: Lingpeng Chen <[email protected]>
commit e7a5f1f1cd0008e5ad379270a8657e121eedb669 upstream.
Right now in tcp_bpf_recvmsg, sock read data first from sk_receive_queue if not empty than psock->ingress_msg otherwise. If a FIN packet arrives and there's also some data in psock->ingress_msg, the data in psock->ingress_msg will be purged. It is always happen when request to a HTTP1.0 server like python SimpleHTTPServer since the server send FIN packet after data is sent out.
--- net/ipv4/tcp_bpf.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
net/ipv4/tcp_bpf.c +6 -6
@@ -121,14 +121,14 @@ int tcp_bpf_recvmsg(struct sock *sk, strstruct sk_psock *psock;int copied, ret; -if (unlikely (flags &MSG_ERRQUEUE )) -return inet_recv_error (sk, msg, len, addr_len); -if (!skb_queue_empty (&sk->sk_receive_queue)) -return tcp_recvmsg (sk, msg, len, nonblock, flags, addr_len); - psock =sk_psock_get (sk);if (unlikely (!psock))return tcp_recvmsg (sk, msg, len, nonblock, flags, addr_len); +if (unlikely (flags &MSG_ERRQUEUE )) +return inet_recv_error (sk, msg, len, addr_len); +if (!skb_queue_empty (&sk->sk_receive_queue) && +sk_psock_queue_empty (psock)) +return tcp_recvmsg (sk, msg, len, nonblock, flags, addr_len);lock_sock (sk); msg_bytes_ready: copied =__tcp_bpf_recvmsg (sk, psock, msg, len, flags);
@@ -139,7 +139,7 @@ msg_bytes_ready: timeo =sock_rcvtimeo (sk, nonblock); data =tcp_bpf_wait_data (sk, psock, flags, timeo, &err);if (data) { -if (skb_queue_empty (&sk->sk_receive_queue)) +if (!sk_psock_queue_empty (psock)) goto msg_bytes_ready;release_sock (sk);sk_psock_put (sk, psock);
Greg Kroah-Hartman
maintainerPATCH 123/222 i2c: iop3xx: Fix memory leak in probe error path
In reply to Greg Kroah-HartmanFrom: Krzysztof Kozlowski <[email protected]>
commit e64175776d06a8ceebbfd349d7e66a4a46ca39ef upstream.
When handling devm_gpiod_get_optional() errors, free the memory already allocated. This fixes Smatch warnings:
drivers/i2c/busses/i2c-iop3xx.c:437 iop3xx_i2c_probe() warn: possible memory leak of 'new_adapter' drivers/i2c/busses/i2c-iop3xx.c:442 iop3xx_i2c_probe() warn: possible memory leak of 'new_adapter'
--- drivers/i2c/busses/i2c-iop3xx.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
drivers/i2c/busses/i2c-iop3xx.c +8 -4
@@ -433,13 +433,17 @@ iop3xx_i2c_probe(struct platform_device adapter_data->gpio_scl =devm_gpiod_get_optional (&pdev->dev,"scl" ,GPIOD_ASIS ); -if (IS_ERR (adapter_data->gpio_scl)) -return PTR_ERR (adapter_data->gpio_scl); +if (IS_ERR (adapter_data->gpio_scl)) { + ret =PTR_ERR (adapter_data->gpio_scl); + goto free_both; + } adapter_data->gpio_sda =devm_gpiod_get_optional (&pdev->dev,"sda" ,GPIOD_ASIS ); -if (IS_ERR (adapter_data->gpio_sda)) -return PTR_ERR (adapter_data->gpio_sda); +if (IS_ERR (adapter_data->gpio_sda)) { + ret =PTR_ERR (adapter_data->gpio_sda); + goto free_both; + } res =platform_get_resource (pdev,IORESOURCE_MEM ,0 );if (!res) {
Greg Kroah-Hartman
maintainerPATCH 124/222 netfilter: fix a use-after-free in mtype_destroy()
In reply to Greg Kroah-HartmanFrom: Cong Wang <[email protected]>
commit c120959387efa51479056fd01dc90adfba7a590c upstream.
map->members is freed by ip_set_free() right before using it in mtype_ext_cleanup() again. So we just have to move it down.
--- net/netfilter/ipset/ip_set_bitmap_gen.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/netfilter/ipset/ip_set_bitmap_gen.h +1 -1
@@ -60,9 +60,9 @@ mtype_destroy(struct ip_set *set)if (SET_WITH_TIMEOUT (set))del_timer_sync (&map->gc); -ip_set_free (map->members);if (set->dsize && set->extensions &IPSET_EXT_DESTROY )mtype_ext_cleanup (set); +ip_set_free (map->members);ip_set_free (map); set->data =NULL ;
Greg Kroah-Hartman
maintainerPATCH 125/222 netfilter: arp_tables: init netns pointer in xt_tgdtor_param struct
In reply to Greg Kroah-HartmanFrom: Florian Westphal <[email protected]>
commit 212e7f56605ef9688d0846db60c6c6ec06544095 upstream.
An earlier commit (1b789577f655060d98d20e,
"netfilter: arp_tables: init netns pointer in xt_tgchk_param struct") fixed missing net initialization for arptables, but turns out it was incomplete. We can get a very similar struct net NULL deref during error unwinding:
general protection fault: 0000 [#1] PREEMPT SMP KASAN RIP: 0010:xt_rateest_put+0xa1/0x440 net/netfilter/xt_RATEEST.c:77 xt_rateest_tg_destroy+0x72/0xa0 net/netfilter/xt_RATEEST.c:175 cleanup_entry net/ipv4/netfilter/arp_tables.c:509 [inline] translate_table+0x11f4/0x1d80 net/ipv4/netfilter/arp_tables.c:587 do_replace net/ipv4/netfilter/arp_tables.c:981 [inline] do_arpt_set_ctl+0x317/0x650 net/ipv4/netfilter/arp_tables.c:1461
Also init the netns pointer in xt_tgdtor_param struct.
--- net/ipv4/netfilter/arp_tables.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-)
net/ipv4/netfilter/arp_tables.c +10 -9
@@ -496,12 +496,13 @@ static inline int check_entry_size_and_hreturn 0 ; } -static inline void cleanup_entry (struct arpt_entry *e) +static void cleanup_entry (struct arpt_entry *e,struct net *net) {struct xt_tgdtor_param par;struct xt_entry_target *t; t =arpt_get_target (e); + par.net = net; par.target = t->u.kernel.target; par.targinfo = t->data; par.family =NFPROTO_ARP ;
@@ -584,7 +585,7 @@ static int translate_table(struct net *n xt_entry_foreach(iter, entry0, newinfo->size) {if (i-- ==0 )break ; -cleanup_entry (iter); +cleanup_entry (iter, net); }return ret; }
@@ -927,7 +928,7 @@ static int __do_replace(struct net *net,/* Decrease module usage counts and free resource */ loc_cpu_old_entry = oldinfo->entries; xt_entry_foreach(iter, loc_cpu_old_entry, oldinfo->size) -cleanup_entry (iter); +cleanup_entry (iter, net);xt_free_table_info (oldinfo); if (copy_to_user(counters_ptr, counters,
@@ -990,7 +991,7 @@ static int do_replace(struct net *net, c free_newinfo_untrans: xt_entry_foreach(iter, loc_cpu_entry, newinfo->size) -cleanup_entry (iter); +cleanup_entry (iter, net); free_newinfo:xt_free_table_info (newinfo);return ret;
@@ -1287,7 +1288,7 @@ static int compat_do_replace(struct net free_newinfo_untrans: xt_entry_foreach(iter, loc_cpu_entry, newinfo->size) -cleanup_entry (iter); +cleanup_entry (iter, net); free_newinfo:xt_free_table_info (newinfo);return ret;
@@ -1514,7 +1515,7 @@ static int do_arpt_get_ctl(struct sock *return ret; } -static void __arpt_unregister_table (struct xt_table *table) +static void __arpt_unregister_table (struct net *net,struct xt_table *table) {struct xt_table_info *private;void *loc_cpu_entry;
@@ -1526,7 +1527,7 @@ static void __arpt_unregister_table(stru/* Decrease module usage counts and free resources */ loc_cpu_entry = private->entries; xt_entry_foreach(iter, loc_cpu_entry, private->size) -cleanup_entry (iter); +cleanup_entry (iter, net);if (private->number > private->initial_entries)module_put (table_owner);xt_free_table_info (private);
@@ -1566,7 +1567,7 @@ int arpt_register_table(struct net *net, ret =nf_register_net_hooks (net, ops,hweight32 (table->valid_hooks));if (ret !=0 ) { -__arpt_unregister_table (new_table); +__arpt_unregister_table (net, new_table); *res =NULL ; }
@@ -1581,7 +1582,7 @@ void arpt_unregister_table(struct net *n const struct nf_hook_ops *ops) {nf_unregister_net_hooks (net, ops,hweight32 (table->valid_hooks)); -__arpt_unregister_table (table); +__arpt_unregister_table (net, table); }/* The built-in targets: standard (NULL) and error. */
Greg Kroah-Hartman
maintainerPATCH 126/222 netfilter: nat: fix ICMP header corruption on ICMP errors
In reply to Greg Kroah-HartmanFrom: Eyal Birger <[email protected]>
commit 61177e911dad660df86a4553eb01c95ece2f6a82 upstream.
Commit 8303b7e8f018 ("netfilter: nat: fix spurious connection timeouts") made nf_nat_icmp_reply_translation() use icmp_manip_pkt() as the l4 manipulation function for the outer packet on ICMP errors.
However, icmp_manip_pkt() assumes the packet has an 'id' field which is not correct for all types of ICMP messages.
This is not correct for ICMP error packets, and leads to bogus bytes being written the ICMP header, which can be wrongfully regarded as 'length' bytes by RFC 4884 compliant receivers.
Fix by assigning the 'id' field only for ICMP messages that have this semantic.
--- net/netfilter/nf_nat_proto.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
net/netfilter/nf_nat_proto.c +13 -0
@@ -233,6 +233,19 @@ icmp_manip_pkt(struct sk_buff *skb,return false; hdr = (struct icmphdr *)(skb->data + hdroff); +switch (hdr->type) { +case ICMP_ECHO : +case ICMP_ECHOREPLY : +case ICMP_TIMESTAMP : +case ICMP_TIMESTAMPREPLY : +case ICMP_INFO_REQUEST : +case ICMP_INFO_REPLY : +case ICMP_ADDRESS : +case ICMP_ADDRESSREPLY : +break ; +default : +return true; + }inet_proto_csum_replace2 (&hdr->checksum, skb, hdr->un.echo.id, tuple->src.u.icmp.id, false); hdr->un.echo.id = tuple->src.u.icmp.id;
Greg Kroah-Hartman
maintainerPATCH 127/222 netfilter: nft_tunnel: fix null-attribute check
In reply to Greg Kroah-HartmanFrom: Florian Westphal <[email protected]>
commit 1c702bf902bd37349f6d91cd7f4b372b1e46d0ed upstream.
else we get null deref when one of the attributes is missing, both must be non-null.
--- net/netfilter/nft_tunnel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/netfilter/nft_tunnel.c +1 -1
@@ -76,7 +76,7 @@ static int nft_tunnel_get_init(const strstruct nft_tunnel *priv =nft_expr_priv (expr);u32 len; -if (!tb[NFTA_TUNNEL_KEY ] && +if (!tb[NFTA_TUNNEL_KEY ] || !tb[NFTA_TUNNEL_DREG ])return -EINVAL ;
Greg Kroah-Hartman
maintainerPATCH 128/222 netfilter: nft_tunnel: ERSPAN_VERSION must not be null
In reply to Greg Kroah-HartmanFrom: Florian Westphal <[email protected]>
commit 9ec22d7c6c69146180577f3ad5fdf504beeaee62 upstream.
--- net/netfilter/nft_tunnel.c | 3 +++ 1 file changed, 3 insertions(+)
net/netfilter/nft_tunnel.c +3 -0
@@ -266,6 +266,9 @@ static int nft_tunnel_obj_erspan_init(coif (err <0 )return err; +if (!tb[NFTA_TUNNEL_KEY_ERSPAN_VERSION ]) +return -EINVAL ; + version =ntohl (nla_get_be32 (tb[NFTA_TUNNEL_KEY_ERSPAN_VERSION ]));switch (version) {case ERSPAN_VERSION :
Greg Kroah-Hartman
maintainerPATCH 129/222 netfilter: nf_tables: remove WARN and add NLA_STRING upper limits
In reply to Greg Kroah-HartmanFrom: Florian Westphal <[email protected]>
commit 9332d27d7918182add34e8043f6a754530fdd022 upstream.
This WARN can trigger because some of the names fed to the module autoload function can be of arbitrary length.
Remove the WARN and add limits for all NLA_STRING attributes.
--- net/netfilter/nf_tables_api.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
net/netfilter/nf_tables_api.c +9 -4
@@ -22,6 +22,8 @@#include <net/net_namespace.h> #include <net/sock.h> +#define NFT_MODULE_AUTOLOAD_LIMIT (MODULE_NAME_LEN - sizeof("nft-expr-255-")) +static LIST_HEAD (nf_tables_expressions);static LIST_HEAD (nf_tables_objects);static LIST_HEAD (nf_tables_flowtables);
@@ -521,7 +523,7 @@ static void nft_request_module(struct neva_start (args, fmt); ret =vsnprintf (module_name,MODULE_NAME_LEN , fmt, args);va_end (args); -if (WARN (ret >=MODULE_NAME_LEN ,"truncated: '%s' (len %d)" , module_name, ret)) +if (ret >=MODULE_NAME_LEN )return ;mutex_unlock (&net->nft.commit_mutex);
@@ -1174,7 +1176,8 @@ static const struct nla_policy nft_chain .len = NFT_CHAIN_MAXNAMELEN - 1 }, [NFTA_CHAIN_HOOK] = { .type = NLA_NESTED }, [NFTA_CHAIN_POLICY] = { .type = NLA_U32 }, - [NFTA_CHAIN_TYPE] = { .type = NLA_STRING }, + [NFTA_CHAIN_TYPE] = { .type = NLA_STRING, + .len = NFT_MODULE_AUTOLOAD_LIMIT }, [NFTA_CHAIN_COUNTERS] = { .type = NLA_NESTED }, [NFTA_CHAIN_FLAGS] = { .type = NLA_U32 }, };
@@ -2088,7 +2091,8 @@ static const struct nft_expr_type *nft_e }static const struct nla_policy nft_expr_policy[NFTA_EXPR_MAX +1 ] = { - [NFTA_EXPR_NAME ] = { .type =NLA_STRING }, + [NFTA_EXPR_NAME ] = { .type =NLA_STRING , + .len =NFT_MODULE_AUTOLOAD_LIMIT }, [NFTA_EXPR_DATA ] = { .type =NLA_NESTED }, };
@@ -3931,7 +3935,8 @@ static const struct nla_policy nft_set_e [NFTA_SET_ELEM_USERDATA ] = { .type =NLA_BINARY , .len = NFT_USERDATA_MAXLEN }, [NFTA_SET_ELEM_EXPR] = { .type = NLA_NESTED }, - [NFTA_SET_ELEM_OBJREF] = { .type = NLA_STRING }, + [NFTA_SET_ELEM_OBJREF ] = { .type =NLA_STRING , + .len = NFT_OBJ_MAXNAMELEN - 1 }, };static const struct nla_policy nft_set_elem_list_policy[NFTA_SET_ELEM_LIST_MAX +1 ] = {
Greg Kroah-Hartman
maintainerPATCH 130/222 netfilter: nf_tables: store transaction list locally while requesting module
In reply to Greg Kroah-HartmanFrom: Pablo Neira Ayuso <[email protected]>
commit ec7470b834fe7b5d7eff11b6677f5d7fdf5e9a91 upstream.
This patch fixes a WARN_ON in nft_set_destroy() due to missing set reference count drop from the preparation phase. This is triggered by the module autoload path. Do not exercise the abort path from nft_request_module() while preparation phase cleaning up is still pending.
WARNING: CPU: 3 PID: 3456 at net/netfilter/nf_tables_api.c:3740 nft_set_destroy+0x45/0x50 [nf_tables] [...] CPU: 3 PID: 3456 Comm: nft Not tainted 5.4.6-arch3-1 #1 RIP: 0010:nft_set_destroy+0x45/0x50 [nf_tables] Code: e8 30 eb 83 c6 48 8b 85 80 00 00 00 48 8b b8 90 00 00 00 e8 dd 6b d7 c5 48 8b 7d 30 e8 24 dd eb c5 48 89 ef 5d e9 6b c6 e5 c5 <0f> 0b c3 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 8b 7f 10 e9 52 RSP: 0018:ffffac4f43e53700 EFLAGS: 00010202 RAX: 0000000000000001 RBX: ffff99d63a154d80 RCX: 0000000001f88e03 RDX: 0000000001f88c03 RSI: ffff99d6560ef0c0 RDI: ffff99d63a101200 RBP: ffff99d617721de0 R08: 0000000000000000 R09: 0000000000000318 R10: 00000000f0000000 R11: 0000000000000001 R12: ffffffff880fabf0 R13: dead000000000122 R14: dead000000000100 R15: ffff99d63a154d80 FS: 00007ff3dbd5b740(0000) GS:ffff99d6560c0000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00001cb5de6a9000 CR3: 000000016eb6a004 CR4: 00000000001606e0 Call Trace: __nf_tables_abort+0x3e3/0x6d0 [nf_tables] nft_request_module+0x6f/0x110 [nf_tables] nft_expr_type_request_module+0x28/0x50 [nf_tables] nf_tables_expr_parse+0x198/0x1f0 [nf_tables] nft_expr_init+0x3b/0xf0 [nf_tables] nft_dynset_init+0x1e2/0x410 [nf_tables] nf_tables_newrule+0x30a/0x930 [nf_tables] nfnetlink_rcv_batch+0x2a0/0x640 [nfnetlink] nfnetlink_rcv+0x125/0x171 [nfnetlink] netlink_unicast+0x179/0x210 netlink_sendmsg+0x208/0x3d0 sock_sendmsg+0x5e/0x60 ____sys_sendmsg+0x21b/0x290
Update comment on the code to describe the new behaviour.
--- net/netfilter/nf_tables_api.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-)
net/netfilter/nf_tables_api.c +10 -9
@@ -502,23 +502,21 @@ __nf_tables_chain_type_lookup(const stru }/* -* Loading a module requires dropping mutex that guards the -* transaction. -* We first need to abort any pending transactions as once -* mutex is unlocked a different client could start a new -* transaction. It must not see any 'future generation' -* changes * as these changes will never happen. +* Loading a module requires dropping mutex that guards the transaction. +* A different client might race to start a new transaction meanwhile. Zap the +* list of pending transaction and then restore it once the mutex is grabbed +* again. Users of this function return EAGAIN which implicitly triggers the +* transaction abort path to clean up the list of pending transactions. */ #ifdef CONFIG_MODULES -static int __nf_tables_abort (struct net *net); -static void nft_request_module (struct net *net,const char *fmt, ...) {char module_name[MODULE_NAME_LEN ]; +LIST_HEAD (commit_list);va_list args;int ret; -__nf_tables_abort (net); +list_splice_init (&net->nft.commit_list, &commit_list);va_start (args, fmt); ret =vsnprintf (module_name,MODULE_NAME_LEN , fmt, args);
@@ -529,6 +527,9 @@ static void nft_request_module(struct nemutex_unlock (&net->nft.commit_mutex);request_module ("%s" , module_name);mutex_lock (&net->nft.commit_mutex); + +WARN_ON_ONCE (!list_empty (&net->nft.commit_list)); + list_splice(&commit_list, &net->nft.commit_list); }#endif
Greg Kroah-Hartman
maintainerPATCH 131/222 netfilter: nf_tables: fix flowtable list del corruption
In reply to Greg Kroah-HartmanFrom: Florian Westphal <[email protected]>
commit 335178d5429c4cee61b58f4ac80688f556630818 upstream.
syzbot reported following crash:
list_del corruption, ffff88808c9bb000->prev is LIST_POISON2 (dead000000000122) [..]
Call Trace: __list_del_entry include/linux/list.h:131 [inline] list_del_rcu include/linux/rculist.h:148 [inline] nf_tables_commit+0x1068/0x3b30 net/netfilter/nf_tables_api.c:7183 [..]
The commit transaction list has:
NFT_MSG_NEWTABLENFT_MSG_NEWFLOWTABLENFT_MSG_DELFLOWTABLENFT_MSG_DELTABLE
A missing generation check during DELTABLE processing causes it to queue the DELFLOWTABLE operation a second time, so we corrupt the list here:
case NFT_MSG_DELFLOWTABLE:
list_del_rcu(&nft_trans_flowtable(trans)->list);
nf_tables_flowtable_notify(&trans->ctx,because we have two different DELFLOWTABLE transactions for the same flowtable. We then call list_del_rcu() twice for the same flowtable->list.
The object handling seems to suffer from the same bug so add a generation check too and only queue delete transactions for flowtables/objects that are still active in the next generation.
--- net/netfilter/nf_tables_api.c | 6 ++++++ 1 file changed, 6 insertions(+)
net/netfilter/nf_tables_api.c +6 -0
@@ -981,12 +981,18 @@ static int nft_flush_table(struct nft_ct }list_for_each_entry_safe (flowtable, nft, &ctx->table->flowtables, list) { +if (!nft_is_active_next (ctx->net, flowtable)) +continue ; + err =nft_delflowtable (ctx, flowtable);if (err <0 ) goto out; }list_for_each_entry_safe (obj, ne, &ctx->table->objects, list) { +if (!nft_is_active_next (ctx->net, obj)) +continue ; + err =nft_delobj (ctx, obj);if (err <0 ) goto out;
Greg Kroah-Hartman
maintainerPATCH 132/222 NFC: pn533: fix bulk-message timeout
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
commit a112adafcb47760feff959ee1ecd10b74d2c5467 upstream.
The driver was doing a synchronous uninterruptible bulk-transfer without using a timeout. This could lead to the driver hanging on probe due to a malfunctioning (or malicious) device until the device is physically disconnected. While sleeping in probe the driver prevents other devices connected to the same hub from being added to (or removed from) the bus.
An arbitrary limit of five seconds should be more than enough.
--- drivers/nfc/pn533/usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/nfc/pn533/usb.c +1 -1
@@ -391,7 +391,7 @@ static int pn533_acr122_poweron_rdr(stru cmd, sizeof(cmd), false); rc =usb_bulk_msg (phy->udev, phy->out_urb->pipe, buffer,sizeof (cmd), - &transferred,0 ); + &transferred,5000 );kfree (buffer);if (rc || (transferred !=sizeof (cmd))) { nfc_err(&phy->udev->dev,
Greg Kroah-Hartman
maintainerPATCH 133/222 net: bpf: Dont leak time wait and request sockets
In reply to Greg Kroah-HartmanFrom: Lorenz Bauer <[email protected]>
commit 2e012c74823629d9db27963c79caa3f5b2010746 upstream.
It's possible to leak time wait and request sockets via the following BPF pseudo code:
sk = bpf_skc_lookup_tcp(...)
if (sk)
bpf_sk_release(sk)
If sk->sk_state is TCP_NEW_SYN_RECV or TCP_TIME_WAIT the refcount taken by bpf_skc_lookup_tcp is not undone by bpf_sk_release. This is because sk_flags is re-used for other data in both kinds of sockets. The check
!sock_flag(sk, SOCK_RCU_FREE)
therefore returns a bogus result. Check that sk_flags is valid by calling sk_fullsock. Skip checking SOCK_RCU_FREE if we already know that sk is not a full socket.
--- net/core/filter.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
net/core/filter.c +4 -5
@@ -5306,8 +5306,7 @@ __bpf_sk_lookup(struct sk_buff *skb, strif (sk) { sk =sk_to_full_sk (sk);if (!sk_fullsock (sk)) { -if (!sock_flag (sk,SOCK_RCU_FREE )) -sock_gen_put (sk); +sock_gen_put (sk);return NULL ; } }
@@ -5344,8 +5343,7 @@ bpf_sk_lookup(struct sk_buff *skb, strucif (sk) { sk =sk_to_full_sk (sk);if (!sk_fullsock (sk)) { -if (!sock_flag (sk,SOCK_RCU_FREE )) -sock_gen_put (sk); +sock_gen_put (sk);return NULL ; } }
@@ -5412,7 +5410,8 @@ static const struct bpf_func_proto bpf_s BPF_CALL_1(bpf_sk_release, struct sock *, sk) { -if (!sock_flag (sk,SOCK_RCU_FREE )) +/* Only full sockets have sk->sk_flags. */ +if (!sk_fullsock (sk) || !sock_flag (sk,SOCK_RCU_FREE ))sock_gen_put (sk);return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 134/222 bpftool: Fix printing incorrect pointer in btf_dump_ptr
In reply to Greg Kroah-HartmanFrom: Martin KaFai Lau <[email protected]>
commit 555089fdfc37ad65e0ee9b42ca40c238ff546f83 upstream.
For plain text output, it incorrectly prints the pointer value "void *data". The "void *data" is actually pointing to memory that contains a bpf-map's value. The intention is to print the content of the bpf-map's value instead of printing the pointer pointing to the bpf-map's value.
In this case, a member of the bpf-map's value is a pointer type. Thus, it should print the "*(void **)data".
--- tools/bpf/bpftool/btf_dumper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/bpf/bpftool/btf_dumper.c +1 -1
@@ -26,7 +26,7 @@ static void btf_dumper_ptr(const void *d bool is_plain_text) {if (is_plain_text) -jsonw_printf (jw,"%p" , data); +jsonw_printf (jw,"%p" , *(void **)data);else jsonw_printf (jw,"%lu" , *(unsigned long *)data); }
Greg Kroah-Hartman
maintainerPATCH 135/222 batman-adv: Fix DAT candidate selection on little endian systems
In reply to Greg Kroah-HartmanFrom: Sven Eckelmann <[email protected]>
commit 4cc4a1708903f404d2ca0dfde30e71e052c6cbc9 upstream.
The distributed arp table is using a DHT to store and retrieve MAC address information for an IP address. This is done using unicast messages to selected peers. The potential peers are looked up using the IP address and the VID.
While the IP address is always stored in big endian byte order, this is not the case of the VID. It can (depending on the host system) either be big endian or little endian. The host must therefore always convert it to big endian to ensure that all devices calculate the same peers for the same lookup data.
--- net/batman-adv/distributed-arp-table.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
net/batman-adv/distributed-arp-table.c +3 -1
@@ -285,6 +285,7 @@ static u32 batadv_hash_dat(const void *du32 hash =0 ;const struct batadv_dat_entry *dat = data;const unsigned char *key; +__be16 vid;u32 i; key = (const unsigned char *)&dat->ip;
@@ -294,7 +295,8 @@ static u32 batadv_hash_dat(const void *d hash ^= (hash >>6 ); } - key = (const unsigned char *)&dat->vid; + vid =htons (dat->vid); + key = (__force const unsigned char *)&vid;for (i =0 ; i <sizeof (dat->vid); i++) { hash += key[i]; hash += (hash <<10 );
Greg Kroah-Hartman
maintainerPATCH 136/222 macvlan: use skb_reset_mac_header() in macvlan_queue_xmit()
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit 1712b2fff8c682d145c7889d2290696647d82dab ]
I missed the fact that macvlan_broadcast() can be used both in RX and TX.
skb_eth_hdr() makes only sense in TX paths, so we can not use it blindly in macvlan_broadcast()
--- drivers/net/macvlan.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/net/macvlan.c +3 -2
@@ -259,7 +259,7 @@ static void macvlan_broadcast(struct sk_buff *skb, struct net_device *src, enum macvlan_mode mode) { -const struct ethhdr *eth =skb_eth_hdr (skb); +const struct ethhdr *eth =eth_hdr (skb);const struct macvlan_dev *vlan;struct sk_buff *nskb;unsigned int i;
@@ -513,10 +513,11 @@ static int macvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev)const struct macvlan_dev *dest;if (vlan->mode ==MACVLAN_MODE_BRIDGE ) { -const struct ethhdr *eth = (void *)skb->data; +const struct ethhdr *eth =skb_eth_hdr (skb);/* send to other bridge ports directly */ if (is_multicast_ether_addr (eth->h_dest)) { +skb_reset_mac_header (skb);macvlan_broadcast (skb, port, dev,MACVLAN_MODE_BRIDGE ); goto xmit_world; }
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 137/222 hv_netvsc: Fix memory leak when removing rndis device
In reply to Greg Kroah-HartmanFrom: Mohammed Gamal <[email protected]>
[ Upstream commit 536dc5df2808efbefc5acee334d3c4f701790ec0 ]
kmemleak detects the following memory leak when hot removing a network device:
unreferenced object 0xffff888083f63600 (size 256):
comm "kworker/0:1", pid 12, jiffies 4294831717 (age 1113.676s) hex dump (first 32 bytes):
00 40 c7 33 80 88 ff ff 00 00 00 00 10 00 00 00 [email protected]............ 00 00 00 00 ad 4e ad de ff ff ff ff 00 00 00 00 .....N.......... backtrace: [<00000000d4a8f5be>] rndis_filter_device_add+0x117/0x11c0 [hv_netvsc] [<000000009c02d75b>] netvsc_probe+0x5e7/0xbf0 [hv_netvsc] [<00000000ddafce23>] vmbus_probe+0x74/0x170 [hv_vmbus] [<00000000046e64f1>] really_probe+0x22f/0xb50 [<000000005cc35eb7>] driver_probe_device+0x25e/0x370 [<0000000043c642b2>] bus_for_each_drv+0x11f/0x1b0 [<000000005e3d09f0>] __device_attach+0x1c6/0x2f0 [<00000000a72c362f>] bus_probe_device+0x1a6/0x260 [<0000000008478399>] device_add+0x10a3/0x18e0 [<00000000cf07b48c>] vmbus_device_register+0xe7/0x1e0 [hv_vmbus] [<00000000d46cf032>] vmbus_add_channel_work+0x8ab/0x1770 [hv_vmbus] [<000000002c94bb64>] process_one_work+0x919/0x17d0 [<0000000096de6781>] worker_thread+0x87/0xb40 [<00000000fbe7397e>] kthread+0x333/0x3f0 [<000000004f844269>] ret_from_fork+0x3a/0x50
rndis_filter_device_add() allocates an instance of struct rndis_device which never gets deallocated as rndis_filter_device_remove() sets net_device->extension which points to the rndis_device struct to NULL, leaving the rndis_device dangling.
Since net_device->extension is eventually freed in free_netvsc_device(), we refrain from setting it to NULL inside rndis_filter_device_remove()
--- drivers/net/hyperv/rndis_filter.c | 2 -- 1 file changed, 2 deletions(-)
drivers/net/hyperv/rndis_filter.c +0 -2
@@ -1436,8 +1436,6 @@ void rndis_filter_device_remove(struct h/* Halt and release the rndis device */ rndis_filter_halt_device (net_dev, rndis_dev); - net_dev->extension =NULL ; -netvsc_device_remove (dev); }
Greg Kroah-Hartman
maintainerPATCH 138/222 net: avoid updating qdisc_xmit_lock_key in netdev_update_lockdep_key()
In reply to Greg Kroah-HartmanFrom: Cong Wang <[email protected]>
[ Upstream commit 53d374979ef147ab51f5d632dfe20b14aebeccd0 ]
syzbot reported some bogus lockdep warnings, for example bad unlock balance in sch_direct_xmit(). They are due to a race condition between slow path and fast path, that is qdisc_xmit_lock_key gets re-registered in netdev_update_lockdep_key() on slow path, while we could still acquire the queue->_xmit_lock on fast path in this small window:
CPU A CPU B
__netif_tx_lock(); lockdep_unregister_key(qdisc_xmit_lock_key); __netif_tx_unlock();
lockdep_register_key(qdisc_xmit_lock_key);
In fact, unlike the addr_list_lock which has to be reordered when the master/slave device relationship changes, queue->_xmit_lock is only acquired on fast path and only when NETIF_F_LLTX is not set, so there is likely no nested locking for it.
Therefore, we can just get rid of re-registration of qdisc_xmit_lock_key.
--- net/core/dev.c | 12 ------------ 1 file changed, 12 deletions(-)
net/core/dev.c +0 -12
@@ -8953,22 +8953,10 @@ static void netdev_unregister_lockdep_kevoid netdev_update_lockdep_key (struct net_device *dev) { -struct netdev_queue *queue; -int i; - -lockdep_unregister_key (&dev->qdisc_xmit_lock_key);lockdep_unregister_key (&dev->addr_list_lock_key); - -lockdep_register_key (&dev->qdisc_xmit_lock_key);lockdep_register_key (&dev->addr_list_lock_key);lockdep_set_class (&dev->addr_list_lock, &dev->addr_list_lock_key); -for (i =0 ; i < dev->num_tx_queues; i++) { - queue =netdev_get_tx_queue (dev, i); - -lockdep_set_class (&queue->_xmit_lock, - &dev->qdisc_xmit_lock_key); - } }EXPORT_SYMBOL (netdev_update_lockdep_key);
Greg Kroah-Hartman
maintainerPATCH 139/222 net: dsa: tag_qca: fix doubled Tx statistics
In reply to Greg Kroah-HartmanFrom: Alexander Lobakin <[email protected]>
[ Upstream commit bd5874da57edd001b35cf28ae737779498c16a56 ]
DSA subsystem takes care of netdev statistics since commit 4ed70ce9f01c ("net: dsa: Refactor transmit path to eliminate duplication"), so any accounting inside tagger callbacks is redundant and can lead to messing up the stats.
This bug is present in Qualcomm tagger since day 0.
--- net/dsa/tag_qca.c | 3 --- 1 file changed, 3 deletions(-)
net/dsa/tag_qca.c +0 -3
@@ -33,9 +33,6 @@ static struct sk_buff *qca_tag_xmit(strustruct dsa_port *dp =dsa_slave_to_port (dev);u16 *phdr, hdr; - dev->stats.tx_packets++; - dev->stats.tx_bytes += skb->len; -if (skb_cow_head (skb,0 ) <0 )return NULL ;
Greg Kroah-Hartman
maintainerPATCH 140/222 net: hns3: pad the short frame before sending to the hardware
In reply to Greg Kroah-HartmanFrom: Yunsheng Lin <[email protected]>
[ Upstream commit 36c67349a1a1c88b9cf11d7ca7762ababdb38867 ]
The hardware can not handle short frames below or equal to 32 bytes according to the hardware user manual, and it will trigger a RAS error when the frame's length is below 33 bytes.
This patch pads the SKB when skb->len is below 33 bytes before sending it to hardware.
--- drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +6 -0
@@ -54,6 +54,8 @@ MODULE_PARM_DESC(debug, " Network interf#define HNS3_INNER_VLAN_TAG 1#define HNS3_OUTER_VLAN_TAG 2 +#define HNS3_MIN_TX_LEN 33U +/* hns3_pci_tbl - PCI Device ID Table * * Last entry must be all 0s
@@ -1329,6 +1331,10 @@ netdev_tx_t hns3_nic_net_xmit(struct sk_int ret;int i; +/* Hardware can only handle short frames above 32 bytes */ +if (skb_put_padto (skb,HNS3_MIN_TX_LEN )) +return NETDEV_TX_OK ; +/* Prefetch the data used later */ prefetch (skb->data);
Greg Kroah-Hartman
maintainerPATCH 141/222 net: hns: fix soft lockup when there is not enough memory
In reply to Greg Kroah-HartmanFrom: Yonglong Liu <[email protected]>
[ Upstream commit 49edd6a2c456150870ddcef5b7ed11b21d849e13 ]
When there is not enough memory and napi_alloc_skb() return NULL, the HNS driver will print error message, and than try again, if the memory is not enough for a while, huge error message and the retry operation will cause soft lockup.
When napi_alloc_skb() return NULL because of no memory, we can get a warn_alloc() call trace, so this patch deletes the error message. We already use polling mode to handle irq, but the retry operation will render the polling weight inactive, this patch just return budget when the rx is not completed to avoid dead loop.
--- drivers/net/ethernet/hisilicon/hns/hns_enet.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/net/ethernet/hisilicon/hns/hns_enet.c +1 -3
@@ -565,7 +565,6 @@ static int hns_nic_poll_rx_skb(struct hn skb = *out_skb =napi_alloc_skb (&ring_data->napi,HNS_RX_HEAD_SIZE );if (unlikely (!skb)) { -netdev_err (ndev,"alloc rx skb fail\n" ); ring->stats.sw_err_cnt++;return -ENOMEM ; }
@@ -1056,7 +1055,6 @@ static int hns_nic_common_poll(struct na container_of(napi, struct hns_nic_ring_data, napi);struct hnae_ring *ring = ring_data->ring; -try_again: clean_complete += ring_data->poll_one ( ring_data, budget - clean_complete, ring_data->ex_process);
@@ -1066,7 +1064,7 @@ try_again:napi_complete (napi); ring->q->handle->dev->ops->toggle_ring_irq (ring,0 ); }else { - goto try_again; +return budget; } }
Greg Kroah-Hartman
maintainerPATCH 142/222 net: phy: dp83867: Set FORCE_LINK_GOOD to default after reset
In reply to Greg Kroah-HartmanFrom: Michael Grzeschik <[email protected]>
[ Upstream commit 86ffe920e669ec73035e84553e18edf17d16317c ]
According to the Datasheet this bit should be 0 (Normal operation) in default. With the FORCE_LINK_GOOD bit set, it is not possible to get a link. This patch sets FORCE_LINK_GOOD to the default value after resetting the phy.
--- drivers/net/phy/dp83867.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/net/phy/dp83867.c +7 -1
@@ -80,6 +80,7 @@#define DP83867_PHYCR_FIFO_DEPTH_MAX 0x03#define DP83867_PHYCR_FIFO_DEPTH_MASK GENMASK(15, 14)#define DP83867_PHYCR_RESERVED_MASK BIT(11) +#define DP83867_PHYCR_FORCE_LINK_GOOD BIT(10)/* RGMIIDCTL bits */ #define DP83867_RGMII_TX_CLK_DELAY_MAX 0xf
@@ -454,7 +455,12 @@ static int dp83867_phy_reset(struct phy_usleep_range (10 ,20 ); -return 0 ; +/* After reset FORCE_LINK_GOOD bit is set. Although the +* default value should be unset. Disable FORCE_LINK_GOOD +* for the phy to work properly. +*/ +return phy_modify (phydev,MII_DP83867_PHYCTRL , +DP83867_PHYCR_FORCE_LINK_GOOD ,0 ); }static struct phy_driver dp83867_driver[] = {
Greg Kroah-Hartman
maintainerPATCH 143/222 net/sched: act_ife: initalize ife->metalist earlier
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit 44c23d71599f81a1c7fe8389e0319822dd50c37c ]
It seems better to init ife->metalist earlier in tcf_ife_init() to avoid the following crash :
kasan: CONFIG_KASAN_INLINE enabled
kasan: GPF could be caused by NULL-ptr deref or user memory access
general protection fault: 0000 [#1] PREEMPT SMP KASAN CPU: 0 PID: 10483 Comm: syz-executor216 Not tainted 5.5.0-rc5-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 RIP: 0010:_tcf_ife_cleanup net/sched/act_ife.c:412 [inline] RIP: 0010:tcf_ife_cleanup+0x6e/0x400 net/sched/act_ife.c:431 Code: 48 c1 ea 03 80 3c 02 00 0f 85 94 03 00 00 49 8b bd f8 00 00 00 48 b8 00 00 00 00 00 fc ff df 4c 8d 67 e8 48 89 fa 48 c1 ea 03 <80> 3c 02 00 0f 85 5c 03 00 00 48 bb 00 00 00 00 00 fc ff df 48 8b RSP: 0018:ffffc90001dc6d00 EFLAGS: 00010246 RAX: dffffc0000000000 RBX: ffffffff864619c0 RCX: ffffffff815bfa09 RDX: 0000000000000000 RSI: 0000000000000004 RDI: 0000000000000000 RBP: ffffc90001dc6d50 R08: 0000000000000004 R09: fffff520003b8d8e R10: fffff520003b8d8d R11: 0000000000000003 R12: ffffffffffffffe8 R13: ffff8880a79fc000 R14: ffff88809aba0e00 R15: 0000000000000000 FS: 0000000001b51880(0000) GS:ffff8880ae800000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000563f52cce140 CR3: 0000000093541000 CR4: 00000000001406f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: tcf_action_cleanup+0x62/0x1b0 net/sched/act_api.c:119 __tcf_action_put+0xfa/0x130 net/sched/act_api.c:135 __tcf_idr_release net/sched/act_api.c:165 [inline] __tcf_idr_release+0x59/0xf0 net/sched/act_api.c:145 tcf_idr_release include/net/act_api.h:171 [inline] tcf_ife_init+0x97c/0x1870 net/sched/act_ife.c:616 tcf_action_init_1+0x6b6/0xa40 net/sched/act_api.c:944 tcf_action_init+0x21a/0x330 net/sched/act_api.c:1000 tcf_action_add+0xf5/0x3b0 net/sched/act_api.c:1410 tc_ctl_action+0x390/0x488 net/sched/act_api.c:1465 rtnetlink_rcv_msg+0x45e/0xaf0 net/core/rtnetlink.c:5424 netlink_rcv_skb+0x177/0x450 net/netlink/af_netlink.c:2477 rtnetlink_rcv+0x1d/0x30 net/core/rtnetlink.c:5442 netlink_unicast_kernel net/netlink/af_netlink.c:1302 [inline] netlink_unicast+0x58c/0x7d0 net/netlink/af_netlink.c:1328 netlink_sendmsg+0x91c/0xea0 net/netlink/af_netlink.c:1917 sock_sendmsg_nosec net/socket.c:639 [inline] sock_sendmsg+0xd7/0x130 net/socket.c:659 ____sys_sendmsg+0x753/0x880 net/socket.c:2330 ___sys_sendmsg+0x100/0x170 net/socket.c:2384 __sys_sendmsg+0x105/0x1d0 net/socket.c:2417 __do_sys_sendmsg net/socket.c:2426 [inline] __se_sys_sendmsg net/socket.c:2424 [inline] __x64_sys_sendmsg+0x78/0xb0 net/socket.c:2424 do_syscall_64+0xfa/0x790 arch/x86/entry/common.c:294 entry_SYSCALL_64_after_hwframe+0x49/0xbe
--- net/sched/act_ife.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
net/sched/act_ife.c +3 -4
@@ -536,6 +536,9 @@ static int tcf_ife_init(struct net *net, } ife =to_ife (*a); +if (ret ==ACT_P_CREATED ) +INIT_LIST_HEAD (&ife->metalist); + err =tcf_action_check_ctrlact (parm->action, tp, &goto_ch, extack);if (err <0 ) goto release_idr;
@@ -565,10 +568,6 @@ static int tcf_ife_init(struct net *net, p->eth_type = ife_type; } - -if (ret ==ACT_P_CREATED ) -INIT_LIST_HEAD (&ife->metalist); -if (tb[TCA_IFE_METALST ]) { err = nla_parse_nested_deprecated(tb2, IFE_META_MAX, tb[TCA_IFE_METALST], NULL,
Greg Kroah-Hartman
maintainerPATCH 144/222 net: usb: lan78xx: limit size of local TSO packets
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit f8d7408a4d7f60f8b2df0f81decdc882dd9c20dc ]
lan78xx_tx_bh() makes sure to not exceed MAX_SINGLE_PACKET_SIZE bytes in the aggregated packets it builds, but does nothing to prevent large GSO packets being submitted.
Pierre-Francois reported various hangs when/if TSO is enabled.
For localy generated packets, we can use netif_set_gso_max_size() to limit the size of TSO packets.
Note that forwarded packets could still hit the issue, so a complete fix might require implementing .ndo_features_check for this driver, forcing a software segmentation if the size of the TSO packet exceeds MAX_SINGLE_PACKET_SIZE.
--- drivers/net/usb/lan78xx.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/usb/lan78xx.c +1 -0
@@ -3750,6 +3750,7 @@ static int lan78xx_probe(struct usb_inte/* MTU range: 68 - 9000 */ netdev->max_mtu =MAX_SINGLE_PACKET_SIZE ; +netif_set_gso_max_size (netdev,MAX_SINGLE_PACKET_SIZE -MAX_HEADER ); dev->ep_blkin = (intf->cur_altsetting)->endpoint +0 ; dev->ep_blkout = (intf->cur_altsetting)->endpoint +1 ;
Greg Kroah-Hartman
maintainerPATCH 145/222 net/wan/fsl_ucc_hdlc: fix out of bounds write on array utdm_info
In reply to Greg Kroah-HartmanFrom: Colin Ian King <[email protected]>
[ Upstream commit ddf420390526ede3b9ff559ac89f58cb59d9db2f ]
Array utdm_info is declared as an array of MAX_HDLC_NUM (4) elements however up to UCC_MAX_NUM (8) elements are potentially being written to it. Currently we have an array out-of-bounds write error on the last 4 elements. Fix this by making utdm_info UCC_MAX_NUM elements in size.
Addresses-Coverity: ("Out-of-bounds write")
--- drivers/net/wan/fsl_ucc_hdlc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wan/fsl_ucc_hdlc.c +1 -1
@@ -73,7 +73,7 @@ static struct ucc_tdm_info utdm_primary_ }, }; -static struct ucc_tdm_info utdm_info[MAX_HDLC_NUM ]; +static struct ucc_tdm_info utdm_info[UCC_MAX_NUM ];static int uhdlc_init (struct ucc_hdlc_private *priv) {
Greg Kroah-Hartman
maintainerPATCH 146/222 ptp: free ptp device pin descriptors properly
In reply to Greg Kroah-HartmanFrom: Vladis Dronov <[email protected]>
[ Upstream commit 75718584cb3c64e6269109d4d54f888ac5a5fd15 ]
There is a bug in ptp_clock_unregister(), where ptp_cleanup_pin_groups() first frees ptp->pin_{,dev_}attr, but then posix_clock_unregister() needs them to destroy a related sysfs device.
These functions can not be just swapped, as posix_clock_unregister() frees ptp which is needed in the ptp_cleanup_pin_groups(). Fix this by calling ptp_cleanup_pin_groups() in ptp_clock_release(), right before ptp is freed.
This makes this patch fix an UAF bug in a patch which fixes an UAF bug.
--- drivers/ptp/ptp_clock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/ptp/ptp_clock.c +2 -2
@@ -170,6 +170,7 @@ static void ptp_clock_release(struct dev { struct ptp_clock *ptp = container_of(dev, struct ptp_clock, dev); +ptp_cleanup_pin_groups (ptp);mutex_destroy (&ptp->tsevq_mux);mutex_destroy (&ptp->pincfg_mux);ida_simple_remove (&ptp_clocks_map, ptp->index);
@@ -302,9 +303,8 @@ int ptp_clock_unregister(struct ptp_clocif (ptp->pps_source)pps_unregister_source (ptp->pps_source); -ptp_cleanup_pin_groups (ptp); -posix_clock_unregister (&ptp->clock); +return 0 ; }EXPORT_SYMBOL (ptp_clock_unregister);
Greg Kroah-Hartman
maintainerPATCH 147/222 r8152: add missing endpoint sanity check
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
[ Upstream commit 86f3f4cd53707ceeec079b83205c8d3c756eca93 ]
Add missing endpoint sanity check to probe in order to prevent a NULL-pointer dereference (or slab out-of-bounds access) when retrieving the interrupt-endpoint bInterval on ndo_open() in case a device lacks the expected endpoints.
--- drivers/net/usb/r8152.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/usb/r8152.c +3 -0
@@ -5587,6 +5587,9 @@ static int rtl8152_probe(struct usb_intereturn -ENODEV ; } +if (intf->cur_altsetting->desc.bNumEndpoints <3 ) +return -ENODEV ; +usb_reset_device (udev); netdev =alloc_etherdev (sizeof (struct r8152 ));if (!netdev) {
Greg Kroah-Hartman
maintainerPATCH 148/222 tcp: fix marked lost packets not being retransmitted
In reply to Greg Kroah-HartmanFrom: Pengcheng Yang <[email protected]>
[ Upstream commit e176b1ba476cf36f723cfcc7a9e57f3cb47dec70 ]
When the packet pointed to by retransmit_skb_hint is unlinked by ACK, retransmit_skb_hint will be set to NULL in tcp_clean_rtx_queue(). If packet loss is detected at this time, retransmit_skb_hint will be set to point to the current packet loss in tcp_verify_retransmit_hint(), then the packets that were previously marked lost but not retransmitted due to the restriction of cwnd will be skipped and cannot be retransmitted.
To fix this, when retransmit_skb_hint is NULL, retransmit_skb_hint can be reset only after all marked lost packets are retransmitted (retrans_out >= lost_out), otherwise we need to traverse from tcp_rtx_queue_head in tcp_xmit_retransmit_queue().
Packetdrill to demonstrate:
// Disable RACK and set max_reordering to keep things simple
0 `sysctl -q net.ipv4.tcp_recovery=0`
+0 sysctl -q net.ipv4.tcp_max_reordering=3
// Establish a connection
+0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 +0 bind(3, ..., ...) = 0
+0 listen(3, 1) = 0
+.1 < S 0:0(0) win 32792 <mss 1000,sackOK,nop,nop,nop,wscale 7>
+0 > S. 0:0(0) ack 1 <...>
+.01 < . 1:1(0) ack 1 win 257
+0 accept(3, ..., ...) = 4
// Send 8 data segments
+0 write(4, ..., 8000) = 8000
+0 > P. 1:8001(8000) ack 1
// Enter recovery and 1:3001 is marked lost
+.01 < . 1:1(0) ack 1 win 257 <sack 3001:4001,nop,nop>
+0 < . 1:1(0) ack 1 win 257 <sack 5001:6001 3001:4001,nop,nop> +0 < . 1:1(0) ack 1 win 257 <sack 5001:7001 3001:4001,nop,nop>
// Retransmit 1:1001, now retransmit_skb_hint points to 1001:2001
+0 > . 1:1001(1000) ack 1
// 1001:2001 was ACKed causing retransmit_skb_hint to be set to NULL
+.01 < . 1:1(0) ack 2001 win 257 <sack 5001:8001 3001:4001,nop,nop>
// Now retransmit_skb_hint points to 4001:5001 which is now marked lost
// BUG: 2001:3001 was not retransmitted
+0 > . 2001:3001(1000) ack 1
--- net/ipv4/tcp_input.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
net/ipv4/tcp_input.c +4 -3
@@ -915,9 +915,10 @@ static void tcp_check_sack_reordering(st/* This must be called before lost_out is incremented */ static void tcp_verify_retransmit_hint (struct tcp_sock *tp,struct sk_buff *skb) { -if (!tp->retransmit_skb_hint || -before (TCP_SKB_CB (skb)->seq, -TCP_SKB_CB (tp->retransmit_skb_hint)->seq)) +if ((!tp->retransmit_skb_hint && tp->retrans_out >= tp->lost_out) || + (tp->retransmit_skb_hint && +before (TCP_SKB_CB (skb)->seq, +TCP_SKB_CB (tp->retransmit_skb_hint)->seq))) tp->retransmit_skb_hint = skb; }
Greg Kroah-Hartman
maintainerPATCH 149/222 bnxt_en: Fix NTUPLE firmware command failures.
In reply to Greg Kroah-HartmanFrom: Michael Chan <[email protected]>
[ Upstream commit ceb3284c588eee5ea256c70e4d8d7cf399b8134e ]
The NTUPLE related firmware commands are sent to the wrong firmware channel, causing all these commands to fail on new firmware that supports the new firmware channel. Fix it by excluding the 3 NTUPLE firmware commands from the list for the new firmware channel.
--- drivers/net/ethernet/broadcom/bnxt/bnxt.h | 3 --- 1 file changed, 3 deletions(-)
drivers/net/ethernet/broadcom/bnxt/bnxt.h +0 -3
@@ -1904,9 +1904,6 @@ static inline bool bnxt_cfa_hwrm_messagecase HWRM_CFA_ENCAP_RECORD_FREE :case HWRM_CFA_DECAP_FILTER_ALLOC :case HWRM_CFA_DECAP_FILTER_FREE : -case HWRM_CFA_NTUPLE_FILTER_ALLOC : -case HWRM_CFA_NTUPLE_FILTER_FREE : -case HWRM_CFA_NTUPLE_FILTER_CFG :case HWRM_CFA_EM_FLOW_ALLOC :case HWRM_CFA_EM_FLOW_FREE :case HWRM_CFA_EM_FLOW_CFG :
Greg Kroah-Hartman
maintainerPATCH 150/222 bnxt_en: Fix ipv6 RFS filter matching logic.
In reply to Greg Kroah-HartmanFrom: Michael Chan <[email protected]>
[ Upstream commit 6fc7caa84e713f7627e171ab1e7c4b5be0dc9b3d ]
Fix bnxt_fltr_match() to match ipv6 source and destination addresses. The function currently only checks ipv4 addresses and will not work corrently on ipv6 filters.
--- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-)
drivers/net/ethernet/broadcom/bnxt/bnxt.c +17 -5
@@ -10991,11 +10991,23 @@ static bool bnxt_fltr_match(struct bnxt_struct flow_keys *keys1 = &f1->fkeys;struct flow_keys *keys2 = &f2->fkeys; -if (keys1->addrs.v4addrs.src == keys2->addrs.v4addrs.src && - keys1->addrs.v4addrs.dst == keys2->addrs.v4addrs.dst && - keys1->ports.ports == keys2->ports.ports && - keys1->basic.ip_proto == keys2->basic.ip_proto && - keys1->basic.n_proto == keys2->basic.n_proto && +if (keys1->basic.n_proto != keys2->basic.n_proto || + keys1->basic.ip_proto != keys2->basic.ip_proto) +return false; + +if (keys1->basic.n_proto ==htons (ETH_P_IP )) { +if (keys1->addrs.v4addrs.src != keys2->addrs.v4addrs.src || + keys1->addrs.v4addrs.dst != keys2->addrs.v4addrs.dst) +return false; + }else { +if (memcmp (&keys1->addrs.v6addrs.src, &keys2->addrs.v6addrs.src, +sizeof (keys1->addrs.v6addrs.src)) || +memcmp (&keys1->addrs.v6addrs.dst, &keys2->addrs.v6addrs.dst, +sizeof (keys1->addrs.v6addrs.dst))) +return false; + } + +if (keys1->ports.ports == keys2->ports.ports && keys1->control.flags == keys2->control.flags &ðer_addr_equal (f1->src_mac_addr, f2->src_mac_addr) &ðer_addr_equal (f1->dst_mac_addr, f2->dst_mac_addr))