This is the start of the stable review cycle for the 4.14.158 release. There are 209 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, 06 Dec 2019 17:50:10 +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/v4.x/stable-review/patch-4.14.158-rc... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.14.y and the diffstat can be found below.
thanks,
greg k-h
------------- Pseudo-Shortlog of commits:
Greg Kroah-Hartman gregkh@linuxfoundation.org Linux 4.14.158-rc1
Chuhong Yuan hslester96@gmail.com net: fec: fix clock count mis-match
Hans de Goede hdegoede@redhat.com platform/x86: hp-wmi: Fix ACPI errors caused by passing 0 as input size
Hans de Goede hdegoede@redhat.com platform/x86: hp-wmi: Fix ACPI errors caused by too small buffer
Olivier Moysan olivier.moysan@st.com ASoC: stm32: i2s: fix IRQ clearing
Olivier Moysan olivier.moysan@st.com ASoC: stm32: i2s: fix 16 bit format support
Olivier Moysan olivier.moysan@st.com ASoC: stm32: i2s: fix dma configuration
Alexandre Torgue alexandre.torgue@st.com pinctrl: stm32: fix memory leak issue
Fabien Dessenne fabien.dessenne@st.com mailbox: mailbox-test: fix null pointer if no mmio
Lionel Debieve lionel.debieve@st.com hwrng: stm32 - fix unbalanced pm_runtime_enable
Hugues Fruchet hugues.fruchet@st.com media: stm32-dcmi: fix DMA corruption when stopping streaming
Lionel Debieve lionel.debieve@st.com crypto: stm32/hash - Fix hmac issue more than 256 bytes
Candle Sun candle.sun@unisoc.com HID: core: check whether Usage Page item is after Usage ID items
Thomas Gleixner tglx@linutronix.de futex: Prevent exit livelock
Thomas Gleixner tglx@linutronix.de futex: Provide distinct return value when owner is exiting
Thomas Gleixner tglx@linutronix.de futex: Add mutex around futex exit
Thomas Gleixner tglx@linutronix.de futex: Provide state handling for exec() as well
Thomas Gleixner tglx@linutronix.de futex: Sanitize exit state handling
Thomas Gleixner tglx@linutronix.de futex: Mark the begin of futex exit explicitly
Thomas Gleixner tglx@linutronix.de futex: Set task::futex_state to DEAD right after handling futex exit
Thomas Gleixner tglx@linutronix.de futex: Split futex_mm_release() for exit/exec
Thomas Gleixner tglx@linutronix.de exit/exec: Seperate mm_release()
Thomas Gleixner tglx@linutronix.de futex: Replace PF_EXITPIDONE with a state
Thomas Gleixner tglx@linutronix.de futex: Move futex exit handling into futex code
Yang Tao yang.tao172@zte.com.cn futex: Prevent robust futex exit race
Arnd Bergmann arnd@arndb.de y2038: futex: Move compat implementation into futex.c
huijin.park huijin.park@samsung.com mtd: spi-nor: cast to u64 to avoid uint overflows
Wen Yang yellowriver2010@hotmail.com mtd: rawnand: atmel: fix possible object reference leak
Miquel Raynal miquel.raynal@bootlin.com mtd: rawnand: atmel: Fix spelling mistake in error message
Paul Thomas pthomas8589@gmail.com net: macb driver, check for SKBTX_HW_TSTAMP
Harini Katakam harini.katakam@xilinx.com net: macb: Fix SUBNS increment and increase resolution
Eugen Hristev eugen.hristev@microchip.com watchdog: sama5d4: fix WDD value to be always set to max
Theodore Ts'o tytso@mit.edu ext4: add more paranoia checking in ext4_expand_extra_isize handling
Dust Li dust.li@linux.alibaba.com net: sched: fix `tc -s class show` no bstats on class with nolock subqueues
Xin Long lucien.xin@gmail.com sctp: cache netns in sctp_ep_common
John Rutherford john.rutherford@dektech.com.au tipc: fix link name length check
Paolo Abeni pabeni@redhat.com openvswitch: remove another BUG_ON()
Paolo Abeni pabeni@redhat.com openvswitch: drop unneeded BUG_ON() in ovs_flow_cmd_build_info()
Jouni Hogander jouni.hogander@unikie.com slip: Fix use-after-free Read in slip_open
Paolo Abeni pabeni@redhat.com openvswitch: fix flow command message size
Nikolay Aleksandrov nikolay@cumulusnetworks.com net: psample: fix skb_over_panic
Menglong Dong dong.menglong@zte.com.cn macvlan: schedule bc_work even if error
Eugen Hristev eugen.hristev@microchip.com media: atmel: atmel-isc: fix INIT_WORK misplacement
Eugen Hristev eugen.hristev@microchip.com media: atmel: atmel-isc: fix asd memory allocation
Uwe Kleine-König u.kleine-koenig@pengutronix.de pwm: Clear chip_data in pwm_put()
Luca Ceresoli luca@lucaceresoli.net net: macb: fix error format in dev_err()
Eugen Hristev eugen.hristev@microchip.com media: v4l2-ctrl: fix flags for DO_WHITE_BALANCE
Steffen Klassert steffen.klassert@secunet.com xfrm: Fix memleak on xfrm state destroy
Alexander Usyskin alexander.usyskin@intel.com mei: bus: prefix device names on bus with the bus name
Fabio D'Urso fabiodurso@hotmail.it USB: serial: ftdi_sio: add device IDs for U-Blox C099-F9P
Hans de Goede hdegoede@redhat.com staging: rtl8723bs: Add 024c:0525 to the list of SDIO device-ids
Hans de Goede hdegoede@redhat.com staging: rtl8723bs: Drop ACPI device ids
Pan Bian bianpan2016@163.com staging: rtl8192e: fix potential use after free
Alexandre Belloni alexandre.belloni@bootlin.com clk: at91: generated: set audio_pll_allowed in at91_clk_register_generated()
Eugen Hristev eugen.hristev@microchip.com clk: at91: fix update bit maps on CFG_MOR write
Vlastimil Babka vbabka@suse.cz mm, gup: add missing refcount overflow checks on s390
Boris Brezillon bbrezillon@kernel.org mtd: Remove a debug trace in mtdpart.c
Gen Zhang blackgod016574@gmail.com powerpc/pseries/dlpar: Fix a missing check in dlpar_parse_cc_property()
John Garry john.garry@huawei.com scsi: libsas: Check SMP PHY control function result
James Morse james.morse@arm.com ACPI / APEI: Switch estatus pool to use vmalloc memory
James Morse james.morse@arm.com ACPI / APEI: Don't wait to serialise with oops messages when panic()ing
John Garry john.garry@huawei.com scsi: libsas: Support SATA PHY connection rate unmatch fixing during discovery
Chris Coulson chris.coulson@canonical.com apparmor: delete the dentry in aafs_remove() to avoid a leak
Aaron Ma aaron.ma@canonical.com iommu/amd: Fix NULL dereference bug in match_hid_uid
Yunsheng Lin linyunsheng@huawei.com net: hns3: Change fw error code NOT_EXEC to NOT_SUPPORTED
Peng Sun sironhide0null@gmail.com bpf: drop refcount if bpf_map_new_fd() fails in map_create()
Greg Kroah-Hartman gregkh@linuxfoundation.org kvm: properly check debugfs dentry before using it
Andy Shevchenko andriy.shevchenko@linux.intel.com net: dev: Use unsigned integer as an argument to left-shift
Peng Sun sironhide0null@gmail.com bpf: decrease usercnt if bpf_map_new_fd() fails in bpf_map_get_fd_by_id()
Maciej Kwiecien maciej.kwiecien@nokia.com sctp: don't compare hb_timer expire date before starting it
Eric Dumazet edumazet@google.com net: fix possible overflow in __sk_mem_raise_allocated()
Bert Kenward bkenward@solarflare.com sfc: initialise found bitmap in efx_ef10_mtd_probe
Hoang Le hoang.h.le@dektech.com.au tipc: fix skb may be leaky in tipc_link_input
Jan Kara jack@suse.cz blktrace: Show requests without sector
Karsten Graul kgraul@linux.ibm.com net/smc: prevent races between smc_lgr_terminate() and smc_conn_free()
Johannes Berg johannes.berg@intel.com decnet: fix DN_IFREQ_SIZE
wenxu wenxu@ucloud.cn ip_tunnel: Make none-tunnel-dst tunnel port work with lwtunnel
Edward Cree ecree@solarflare.com sfc: suppress duplicate nvmem partition types in efx_ef10_mtd_probe
Lucas Stach l.stach@pengutronix.de gpu: ipu-v3: pre: don't trigger update if buffer address doesn't change
He Zhe zhe.he@windriver.com serial: 8250: Fix serial8250 initialization crash
Konstantin Khlebnikov khlebnikov@yandex-team.ru net/core/neighbour: fix kmemleak minimal reference count for hash tables
Ming Lei ming.lei@redhat.com PCI/MSI: Return -ENOSPC from pci_alloc_irq_vectors_affinity()
Konstantin Khlebnikov khlebnikov@yandex-team.ru net/core/neighbour: tell kmemleak about hash tables
Gustavo A. R. Silva gustavo@embeddedor.com tipc: fix memory leak in tipc_nl_compat_publ_dump
Boris Brezillon bbrezillon@kernel.org mtd: Check add_mtd_device() ret code
Olof Johansson olof@lixom.net lib/genalloc.c: include vmalloc.h
Qian Cai cai@gmx.us drivers/base/platform.c: kmemleak ignore a known leak
Yi Wang wang.yi59@zte.com.cn fork: fix some -Wmissing-prototypes warnings
Huang Shijie sjhuang@iluvatar.ai lib/genalloc.c: use vzalloc_node() to allocate the bitmap
Alexey Skidanov alexey.skidanov@intel.com lib/genalloc.c: fix allocation of aligned buffer from non-aligned chunk
Wei Yang richard.weiyang@gmail.com vmscan: return NODE_RECLAIM_NOSCAN in node_reclaim() when CONFIG_NUMA is n
Junxiao Bi junxiao.bi@oracle.com ocfs2: clear journal dirty flag after shutdown journal
Wen Yang wen.yang99@zte.com.cn net/wan/fsl_ucc_hdlc: Avoid double free in ucc_hdlc_probe()
Kangjie Lu kjlu@umn.edu tipc: fix a missing check of genlmsg_put
Kangjie Lu kjlu@umn.edu atl1e: checking the status of atl1e_write_phy_reg
Kangjie Lu kjlu@umn.edu net: dsa: bcm_sf2: Propagate error value from mdio_write
Kangjie Lu kjlu@umn.edu net: stmicro: fix a missing check of clk_prepare
Kangjie Lu kjlu@umn.edu net: (cpts) fix a missing check of clk_prepare
Richard Weinberger richard@nod.at um: Make GCOV depend on !KCOV
Chao Yu yuchao0@huawei.com f2fs: fix to dirty inode synchronously
Aditya Pakki pakki001@umn.edu net/net_namespace: Check the return value of register_pernet_subsys()
Aditya Pakki pakki001@umn.edu net/netlink_compat: Fix a missing check of nla_parse_nested
Alexander Shiyan shc_work@mail.ru pwm: clps711x: Fix period calculation
Fabio Estevam festevam@gmail.com crypto: mxc-scc - fix build warnings on ARM64
Michael Ellerman mpe@ellerman.id.au powerpc/pseries: Fix node leak in update_lmb_associativity_index()
Christophe Leroy christophe.leroy@c-s.fr powerpc/83xx: handle machine check caused by watchdog timer
Kangjie Lu kjlu@umn.edu regulator: tps65910: fix a missing check of return value
Parav Pandit parav@mellanox.com IB/rxe: Make counters thread safe
Luc Van Oostenryck luc.vanoostenryck@gmail.com drbd: fix print_st_err()'s prototype to match the definition
Lars Ellenberg lars.ellenberg@linbit.com drbd: do not block when adjusting "disk-options" while IO is frozen
Lars Ellenberg lars.ellenberg@linbit.com drbd: reject attach of unsuitable uuids even if connected
Lars Ellenberg lars.ellenberg@linbit.com drbd: ignore "all zero" peer volume sizes in handshake
Alexey Kardashevskiy aik@ozlabs.ru powerpc/powernv/eeh/npu: Fix uninitialized variables in opal_pci_eeh_freeze_status
Alexey Kardashevskiy aik@ozlabs.ru vfio/spapr_tce: Get rid of possible infinite loop
Benjamin Herrenschmidt benh@kernel.crashing.org powerpc/44x/bamboo: Fix PCI range
Christophe Leroy christophe.leroy@c-s.fr powerpc/mm: Make NULL pointer deferences explicit on bad page faults.
Christophe Leroy christophe.leroy@c-s.fr powerpc/prom: fix early DEBUG messages
Madhavan Srinivasan maddy@linux.vnet.ibm.com powerpc/perf: Fix unit_sel/cache_sel checks
Kyle Roeschley kyle.roeschley@ni.com ath6kl: Fix off by one error in scan completion
Kyle Roeschley kyle.roeschley@ni.com ath6kl: Only use match sets when firmware supports it
Varun Prakash varun@chelsio.com scsi: csiostor: fix incorrect dma device in case of vport
Anatoliy Glagolev glagolig@gmail.com scsi: qla2xxx: deadlock by configfs_depend_item
Bart Van Assche bvanassche@acm.org RDMA/srp: Propagate ib_post_send() failures to the SCSI mid-layer
Geert Uytterhoeven geert@linux-m68k.org openrisc: Fix broken paths to arch/or32
Alexander Shiyan shc_work@mail.ru serial: max310x: Fix tx_empty() callback
Jonathan Bakker xc-racer2@live.ca Bluetooth: hci_bcm: Handle specific unknown packets after firmware loading
Kangjie Lu kjlu@umn.edu drivers/regulator: fix a missing check of return value
Christophe Leroy christophe.leroy@c-s.fr powerpc/xmon: fix dump_segments()
Christophe Leroy christophe.leroy@c-s.fr powerpc/book3s/32: fix number of bats in p/v_block_mapped()
Petr Machata petrm@mellanox.com vxlan: Fix error path in __vxlan_dev_create()
Tao Ren taoren@fb.com clocksource/drivers/fttmr010: Fix invalid interrupt register access
Dan Carpenter dan.carpenter@oracle.com IB/qib: Fix an error code in qib_sdma_verbs_send()
Nick Bowler nbowler@draconx.ca xfs: Fix bulkstat compat ioctls on x32 userspace.
Nick Bowler nbowler@draconx.ca xfs: Align compat attrlist_by_handle with native implementation.
Bob Peterson rpeterso@redhat.com gfs2: take jdata unstuff into account in do_grow
Sweet Tea sweettea@redhat.com dm flakey: Properly corrupt multi-page bios.
Peter Hutterer peter.hutterer@who-t.net HID: doc: fix wrong data structure reference for UHID_OUTPUT
Geert Uytterhoeven geert+renesas@glider.be pinctrl: sh-pfc: sh7734: Fix shifted values in IPSR10
Geert Uytterhoeven geert+renesas@glider.be pinctrl: sh-pfc: sh7264: Fix PFCR3 and PFCR0 register configuration
Michael Mueller mimu@linux.ibm.com KVM: s390: unregister debug feature on failing arch init
Vasundhara Volam vasundhara-v.volam@broadcom.com bnxt_en: query force speeds before disabling autoneg mode.
Vasundhara Volam vasundhara-v.volam@broadcom.com bnxt_en: Return linux standard errors in bnxt_ethtool.c
Al Viro viro@zeniv.linux.org.uk exofs_mount(): fix leaks on failure exits
Leon Romanovsky leonro@mellanox.com net/mlx5: Continue driver initialization despite debugfs failure
Martin Schiller ms@dev.tdt.de pinctrl: xway: fix gpio-hog related boot issues
Nathan Chancellor natechancellor@gmail.com vfio-mdev/samples: Use u8 instead of char for handle functions
Ross Lagerwall ross.lagerwall@citrix.com xen/pciback: Check dev_data before using it
Andrea Righi righi.andrea@gmail.com kprobes/x86/xen: blacklist non-attachable xen interrupt functions
Darwin Dingel darwin.dingel@alliedtelesis.co.nz serial: 8250: Rate limit serial port rx interrupts during input overruns
Pan Bian bianpan2016@163.com HID: intel-ish-hid: fixes incorrect error handling
Josef Bacik jbacik@fb.com btrfs: only track ref_heads in delayed_ref_updates
Boris Brezillon boris.brezillon@bootlin.com mtd: rawnand: sunxi: Write pageprog related opcodes to WCMD_SET
Jerome Brunet jbrunet@baylibre.com mmc: meson-gx: make sure the descriptor is stopped on errors
Lepton Wu ytht.net@gmail.com VSOCK: bind to random port for VMADDR_PORT_ANY
Jim Mattson jmattson@google.com kvm: vmx: Set IA32_TSC_AUX for legacy mode guests
Krzysztof Kozlowski krzk@kernel.org gpiolib: Fix return value of gpio_to_desc() stub if !GPIOLIB
Luca Coelho luciano.coelho@intel.com iwlwifi: move iwl_nvm_check_version() into dvm
Masahiro Yamada yamada.masahiro@socionext.com microblaze: move "... is ready" messages to arch/microblaze/Makefile
Masahiro Yamada yamada.masahiro@socionext.com microblaze: adjust the help to the real behavior
Pan Bian bianpan2016@163.com ubi: Do not drop UBI device reference before using
Pan Bian bianpan2016@163.com ubi: Put MTD device after it is not used
Darrick J. Wong darrick.wong@oracle.com xfs: require both realtime inodes to mount
Pan Bian bianpan2016@163.com rtl818x: fix potential use after free
Brian Norris briannorris@chromium.org mwifiex: debugfs: correct histogram spacing, formatting
Pan Bian bianpan2016@163.com mwifiex: fix potential NULL dereference and use after free
Eric Biggers ebiggers@google.com crypto: user - support incremental algorithm dumps
James Smart jsmart2021@gmail.com scsi: lpfc: Enable Management features for IF_TYPE=6
Hans de Goede hdegoede@redhat.com ACPI / LPSS: Ignore acpi_device_fix_up_power() return value
Arnd Bergmann arnd@arndb.de ARM: ks8695: fix section mismatch warning
Thomas Meyer thomas@m3y3r.de PM / AVS: SmartReflex: NULL check before some freeing functions is not needed
Gal Pressman galpress@amazon.com RDMA/vmw_pvrdma: Use atomic memory allocation in create AH
Aaro Koskinen aaro.koskinen@iki.fi ARM: OMAP1: fix USB configuration for device-only setups
Suzuki K Poulose Suzuki.Poulose@arm.com arm64: smp: Handle errors reported by the firmware
Steve Capper steve.capper@arm.com arm64: mm: Prevent mismatched 52-bit VA support
Helge Deller deller@gmx.de parisc: Fix HP SDC hpa address output
Helge Deller deller@gmx.de parisc: Fix serio address output
Fabio Estevam festevam@gmail.com ARM: dts: imx53-voipac-dmm-668: Fix memory node duplication
Uwe Kleine-König u.kleine-koenig@pengutronix.de ARM: debug-imx: only define DEBUG_IMX_UART_PORT if needed
Linus Walleij linus.walleij@linaro.org ARM: dts: Fix up SQ201 flash access
James Smart jsmart2021@gmail.com scsi: lpfc: Fix dif and first burst use in write commands
James Smart jsmart2021@gmail.com scsi: lpfc: Fix kernel Oops due to null pring pointers
Uwe Kleine-König u.kleine-koenig@pengutronix.de pwm: bcm-iproc: Prevent unloading the driver module while in use
Dan Carpenter dan.carpenter@oracle.com block: drbd: remove a stray unlock in __drbd_send_protocol()
Ahmed Zaki anzaki@gmail.com mac80211: fix station inactive_time shortly after boot
Jeff Layton jlayton@kernel.org ceph: return -EINVAL if given fsc mount option on kernel w/o support
Doug Berger opendmb@gmail.com net: bcmgenet: reapply manual settings to the PHY
Ilya Leoshkevich iii@linux.ibm.com scripts/gdb: fix debugging modules compiled with hot/cold partitioning
Xingyu Chen xingyu.chen@amlogic.com watchdog: meson: Fix the wrong value of left time
Marc Kleine-Budde mkl@pengutronix.de can: rx-offload: can_rx_offload_irq_offload_fifo(): continue on error
Jeroen Hofstee jhofstee@victronenergy.com can: rx-offload: can_rx_offload_irq_offload_timestamp(): continue on error
Marc Kleine-Budde mkl@pengutronix.de can: rx-offload: can_rx_offload_offload_one(): use ERR_PTR() to propagate error value in case of errors
Marc Kleine-Budde mkl@pengutronix.de can: rx-offload: can_rx_offload_offload_one(): increment rx_fifo_errors on queue overflow or OOM
Marc Kleine-Budde mkl@pengutronix.de can: rx-offload: can_rx_offload_offload_one(): do not increase the skb_queue beyond skb_queue_len_max
Marc Kleine-Budde mkl@pengutronix.de can: rx-offload: can_rx_offload_queue_tail(): fix error handling, avoid skb mem leak
Jeroen Hofstee jhofstee@victronenergy.com can: c_can: D_CAN: c_can_chip_config(): perform a sofware reset on open
Jeroen Hofstee jhofstee@victronenergy.com can: peak_usb: report bus recovery as well
Florian Westphal fw@strlen.de bridge: ebtables: don't crash when using dnat target in output chains
Chuhong Yuan hslester96@gmail.com net: fec: add missed clk_disable_unprepare in remove
Peter Ujfalusi peter.ujfalusi@ti.com clk: ti: dra7-atl-clock: Remove ti_clk_add_alias call
Xiaochen Shen xiaochen.shen@intel.com x86/resctrl: Prevent NULL pointer dereference when reading mondata
Matthew Wilcox (Oracle) willy@infradead.org idr: Fix idr_alloc_u32 on 32-bit systems
Colin Ian King colin.king@canonical.com clk: sunxi-ng: a80: fix the zero'ing of bits 16 and 18
Alexandre Belloni alexandre.belloni@bootlin.com clk: at91: avoid sleeping early
Randy Dunlap rdunlap@infradead.org reset: fix reset_control_ops kerneldoc comment
Marek Szyprowski m.szyprowski@samsung.com clk: samsung: exynos5420: Preserve PLL configuration during suspend/resume
Russell King rmk+kernel@armlinux.org.uk ASoC: kirkwood: fix external clock probe defer
Kishon Vijay Abraham I kishon@ti.com reset: Fix memory leak in reset_control_array_put()
Xiaojun Sang xsang@codeaurora.org ASoC: compress: fix unsigned integer overflow check
Stephan Gerhold stephan@gerhold.net ASoC: msm8916-wcd-analog: Fix RX1 selection in RDAC2 MUX
Martin Blumenstingl martin.blumenstingl@googlemail.com clk: meson: gxbb: let sar_adc_clk_div set the parent clock rate
-------------
Diffstat:
Documentation/hid/uhid.txt | 2 +- Makefile | 4 +- arch/arm/Kconfig.debug | 28 +- arch/arm/boot/dts/gemini-sq201.dts | 37 +- arch/arm/boot/dts/imx53-voipac-dmm-668.dtsi | 8 +- arch/arm/mach-ks8695/board-acs5k.c | 2 +- arch/arm/mach-omap1/Makefile | 2 +- arch/arm/mach-omap1/include/mach/usb.h | 2 +- arch/arm64/kernel/head.S | 26 ++ arch/arm64/kernel/smp.c | 6 + arch/microblaze/Makefile | 12 +- arch/microblaze/boot/Makefile | 4 - arch/openrisc/kernel/entry.S | 2 +- arch/openrisc/kernel/head.S | 2 +- arch/powerpc/boot/dts/bamboo.dts | 4 +- arch/powerpc/include/asm/cputable.h | 1 + arch/powerpc/include/asm/reg.h | 2 + arch/powerpc/kernel/cputable.c | 10 +- arch/powerpc/kernel/prom.c | 6 +- arch/powerpc/mm/fault.c | 17 +- arch/powerpc/mm/ppc_mmu_32.c | 4 +- arch/powerpc/perf/isa207-common.c | 25 +- arch/powerpc/perf/isa207-common.h | 4 +- arch/powerpc/platforms/83xx/misc.c | 17 + arch/powerpc/platforms/powernv/eeh-powernv.c | 8 +- arch/powerpc/platforms/powernv/pci-ioda.c | 4 +- arch/powerpc/platforms/powernv/pci.c | 4 +- arch/powerpc/platforms/pseries/dlpar.c | 4 + arch/powerpc/platforms/pseries/hotplug-memory.c | 1 + arch/powerpc/xmon/xmon.c | 2 +- arch/s390/kvm/kvm-s390.c | 17 +- arch/s390/mm/gup.c | 9 +- arch/um/Kconfig.debug | 1 + arch/x86/kernel/cpu/intel_rdt_ctrlmondata.c | 4 + arch/x86/kvm/vmx.c | 6 +- arch/x86/xen/xen-asm_64.S | 2 + crypto/crypto_user.c | 37 +- drivers/acpi/acpi_lpss.c | 7 +- drivers/acpi/apei/ghes.c | 32 +- drivers/base/platform.c | 3 + drivers/block/drbd/drbd_main.c | 1 - drivers/block/drbd/drbd_nl.c | 43 +- drivers/block/drbd/drbd_receiver.c | 52 ++- drivers/block/drbd/drbd_state.h | 2 +- drivers/bluetooth/hci_bcm.c | 22 + drivers/char/hw_random/stm32-rng.c | 8 + drivers/clk/at91/clk-generated.c | 28 +- drivers/clk/at91/clk-main.c | 7 +- drivers/clk/at91/sckc.c | 20 +- drivers/clk/meson/gxbb.c | 1 + drivers/clk/samsung/clk-exynos5420.c | 6 + drivers/clk/sunxi-ng/ccu-sun9i-a80.c | 2 +- drivers/clk/ti/clk-dra7-atl.c | 6 - drivers/clocksource/timer-fttmr010.c | 73 +-- drivers/crypto/mxc-scc.c | 12 +- drivers/crypto/stm32/stm32-hash.c | 2 +- drivers/gpu/ipu-v3/ipu-pre.c | 6 + drivers/hid/hid-core.c | 51 +- drivers/hid/intel-ish-hid/ishtp-hid.c | 2 +- drivers/infiniband/hw/qib/qib_sdma.c | 4 +- drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c | 2 +- drivers/infiniband/sw/rxe/rxe_hw_counters.c | 2 +- drivers/infiniband/sw/rxe/rxe_verbs.h | 6 +- drivers/infiniband/ulp/srp/ib_srp.c | 1 + drivers/input/serio/gscps2.c | 4 +- drivers/input/serio/hp_sdc.c | 4 +- drivers/iommu/amd_iommu.c | 8 +- drivers/mailbox/mailbox-test.c | 14 +- drivers/md/dm-flakey.c | 33 +- drivers/media/platform/atmel/atmel-isc.c | 12 +- drivers/media/platform/stm32/stm32-dcmi.c | 17 + drivers/media/v4l2-core/v4l2-ctrls.c | 1 + drivers/misc/mei/bus.c | 9 +- drivers/mmc/host/meson-gx-mmc.c | 73 ++- drivers/mtd/mtdcore.h | 2 +- drivers/mtd/mtdpart.c | 35 +- drivers/mtd/nand/atmel/nand-controller.c | 2 +- drivers/mtd/nand/atmel/pmecc.c | 21 +- drivers/mtd/nand/sunxi_nand.c | 2 +- drivers/mtd/spi-nor/spi-nor.c | 2 +- drivers/mtd/ubi/build.c | 2 +- drivers/mtd/ubi/kapi.c | 2 +- drivers/net/can/c_can/c_can.c | 26 ++ drivers/net/can/rx-offload.c | 96 +++- drivers/net/can/usb/peak_usb/pcan_usb.c | 15 +- drivers/net/dsa/bcm_sf2.c | 7 +- drivers/net/ethernet/atheros/atl1e/atl1e_main.c | 4 +- drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 78 +++- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 5 +- drivers/net/ethernet/cadence/macb.h | 6 +- drivers/net/ethernet/cadence/macb_main.c | 18 +- drivers/net/ethernet/cadence/macb_ptp.c | 5 +- drivers/net/ethernet/freescale/fec_main.c | 13 +- .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c | 2 + .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h | 2 +- drivers/net/ethernet/mellanox/mlx5/core/main.c | 8 +- drivers/net/ethernet/sfc/ef10.c | 29 +- drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c | 4 +- drivers/net/ethernet/ti/cpts.c | 4 +- drivers/net/macvlan.c | 3 +- drivers/net/slip/slip.c | 1 + drivers/net/vxlan.c | 13 +- drivers/net/wan/fsl_ucc_hdlc.c | 1 - drivers/net/wireless/ath/ath6kl/cfg80211.c | 4 +- drivers/net/wireless/intel/iwlwifi/dvm/main.c | 17 + .../net/wireless/intel/iwlwifi/iwl-eeprom-parse.c | 19 - .../net/wireless/intel/iwlwifi/iwl-eeprom-parse.h | 5 +- drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 4 +- drivers/net/wireless/marvell/mwifiex/debugfs.c | 14 +- drivers/net/wireless/marvell/mwifiex/scan.c | 18 +- drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c | 3 +- drivers/pci/msi.c | 22 +- drivers/pinctrl/pinctrl-xway.c | 39 +- drivers/pinctrl/sh-pfc/pfc-sh7264.c | 9 +- drivers/pinctrl/sh-pfc/pfc-sh7734.c | 16 +- drivers/pinctrl/stm32/pinctrl-stm32.c | 26 +- drivers/platform/x86/hp-wmi.c | 10 +- drivers/power/avs/smartreflex.c | 3 +- drivers/pwm/core.c | 1 + drivers/pwm/pwm-bcm-iproc.c | 1 + drivers/pwm/pwm-berlin.c | 1 - drivers/pwm/pwm-clps711x.c | 4 +- drivers/pwm/pwm-pca9685.c | 1 - drivers/pwm/pwm-samsung.c | 1 - drivers/regulator/palmas-regulator.c | 5 +- drivers/regulator/tps65910-regulator.c | 4 +- drivers/reset/core.c | 1 + drivers/scsi/csiostor/csio_init.c | 2 +- drivers/scsi/libsas/sas_expander.c | 29 +- drivers/scsi/lpfc/lpfc.h | 6 + drivers/scsi/lpfc/lpfc_attr.c | 4 +- drivers/scsi/lpfc/lpfc_bsg.c | 6 +- drivers/scsi/lpfc/lpfc_els.c | 4 +- drivers/scsi/lpfc/lpfc_hbadisc.c | 2 +- drivers/scsi/lpfc/lpfc_init.c | 7 +- drivers/scsi/lpfc/lpfc_scsi.c | 18 + drivers/scsi/lpfc/lpfc_sli.c | 2 + drivers/scsi/qla2xxx/tcm_qla2xxx.c | 48 +- drivers/scsi/qla2xxx/tcm_qla2xxx.h | 3 - drivers/staging/rtl8192e/rtl8192e/rtl_core.c | 5 +- drivers/staging/rtl8723bs/os_dep/sdio_intf.c | 7 +- drivers/tty/serial/8250/8250_core.c | 26 ++ drivers/tty/serial/8250/8250_fsl.c | 23 +- drivers/tty/serial/8250/8250_of.c | 5 + drivers/tty/serial/max310x.c | 7 +- drivers/usb/serial/ftdi_sio.c | 3 + drivers/usb/serial/ftdi_sio_ids.h | 7 + drivers/vfio/vfio_iommu_spapr_tce.c | 10 +- drivers/watchdog/meson_gxbb_wdt.c | 4 +- drivers/watchdog/sama5d4_wdt.c | 4 +- drivers/xen/xen-pciback/pci_stub.c | 3 +- fs/btrfs/delayed-ref.c | 3 - fs/ceph/super.c | 11 +- fs/exec.c | 2 +- fs/exofs/super.c | 37 +- fs/ext4/inode.c | 15 + fs/ext4/super.c | 21 +- fs/f2fs/file.c | 2 +- fs/gfs2/bmap.c | 2 + fs/ocfs2/journal.c | 6 +- fs/xfs/xfs_ioctl32.c | 40 +- fs/xfs/xfs_rtalloc.c | 4 +- include/linux/blktrace_api.h | 8 +- include/linux/compat.h | 2 - include/linux/futex.h | 44 +- include/linux/genalloc.h | 13 +- include/linux/gpio/consumer.h | 2 +- include/linux/netdevice.h | 2 +- include/linux/reset-controller.h | 2 +- include/linux/sched.h | 3 +- include/linux/sched/mm.h | 6 +- include/linux/sched/task.h | 2 + include/linux/serial_8250.h | 4 + include/linux/swap.h | 6 - include/net/sctp/structs.h | 3 + include/net/sock.h | 2 +- init/main.c | 1 - kernel/Makefile | 3 - kernel/bpf/syscall.c | 6 +- kernel/exit.c | 30 +- kernel/fork.c | 45 +- kernel/futex.c | 511 +++++++++++++++++++-- kernel/futex_compat.c | 202 -------- lib/genalloc.c | 25 +- lib/radix-tree.c | 2 +- mm/internal.h | 10 + net/bridge/netfilter/ebt_dnat.c | 19 +- net/core/neighbour.c | 13 +- net/core/net_namespace.c | 3 +- net/core/sock.c | 2 +- net/decnet/dn_dev.c | 2 +- net/ipv4/ip_tunnel.c | 8 +- net/mac80211/sta_info.c | 3 +- net/openvswitch/datapath.c | 17 +- net/psample/psample.c | 2 +- net/sched/sch_mq.c | 3 +- net/sched/sch_mqprio.c | 4 +- net/sched/sch_multiq.c | 2 +- net/sched/sch_prio.c | 2 +- net/sctp/associola.c | 1 + net/sctp/endpointola.c | 1 + net/sctp/input.c | 4 +- net/sctp/transport.c | 3 +- net/smc/smc_core.c | 4 + net/tipc/link.c | 2 +- net/tipc/netlink_compat.c | 15 +- net/vmw_vsock/af_vsock.c | 7 +- net/xfrm/xfrm_state.c | 2 + samples/vfio-mdev/mtty.c | 26 +- scripts/gdb/linux/symbols.py | 3 +- security/apparmor/apparmorfs.c | 1 + sound/core/compress_offload.c | 2 +- sound/soc/codecs/msm8916-wcd-analog.c | 4 +- sound/soc/kirkwood/kirkwood-i2s.c | 8 +- sound/soc/stm/stm32_i2s.c | 29 +- virt/kvm/kvm_main.c | 2 +- 216 files changed, 2019 insertions(+), 1025 deletions(-)
From: Martin Blumenstingl martin.blumenstingl@googlemail.com
[ Upstream commit 44b09b11b813b8550e6b976ea51593bc23bba8d1 ]
The meson-saradc driver manually sets the input clock for sar_adc_clk_sel. Update the GXBB clock driver (which is used on GXBB, GXL and GXM) so the rate settings on sar_adc_clk_div are propagated up to sar_adc_clk_sel which will let the common clock framework select the best matching parent clock if we want that.
This makes sar_adc_clk_div consistent with the axg-aoclk and g12a-aoclk drivers, which both also specify CLK_SET_RATE_PARENT.
Fixes: 33d0fcdfe0e870 ("clk: gxbb: add the SAR ADC clocks and expose them") Signed-off-by: Martin Blumenstingl martin.blumenstingl@googlemail.com Signed-off-by: Jerome Brunet jbrunet@baylibre.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/meson/gxbb.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c index 92168348ffa6e..f2d27addf485c 100644 --- a/drivers/clk/meson/gxbb.c +++ b/drivers/clk/meson/gxbb.c @@ -687,6 +687,7 @@ static struct clk_divider gxbb_sar_adc_clk_div = { .ops = &clk_divider_ops, .parent_names = (const char *[]){ "sar_adc_clk_sel" }, .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, }, };
From: Stephan Gerhold stephan@gerhold.net
[ Upstream commit 9110d1b0e229cebb1ffce0c04db2b22beffd513d ]
According to the PM8916 Hardware Register Description, CDC_D_CDC_CONN_HPHR_DAC_CTL has only a single bit (RX_SEL) to switch between RX1 (0) and RX2 (1). It is not possible to disable it entirely to achieve the "ZERO" state.
However, at the moment the "RDAC2 MUX" mixer defines three possible values ("ZERO", "RX2" and "RX1"). Setting the mixer to "ZERO" actually configures it to RX1. Setting the mixer to "RX1" has (seemingly) no effect.
Remove "ZERO" and replace it with "RX1" to fix this.
Fixes: 585e881e5b9e ("ASoC: codecs: Add msm8916-wcd analog codec") Signed-off-by: Stephan Gerhold stephan@gerhold.net Acked-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org Link: https://lore.kernel.org/r/20191020153007.206070-1-stephan@gerhold.net Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/msm8916-wcd-analog.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sound/soc/codecs/msm8916-wcd-analog.c b/sound/soc/codecs/msm8916-wcd-analog.c index 0b9b014b4bb6c..969283737787f 100644 --- a/sound/soc/codecs/msm8916-wcd-analog.c +++ b/sound/soc/codecs/msm8916-wcd-analog.c @@ -303,7 +303,7 @@ struct pm8916_wcd_analog_priv { };
static const char *const adc2_mux_text[] = { "ZERO", "INP2", "INP3" }; -static const char *const rdac2_mux_text[] = { "ZERO", "RX2", "RX1" }; +static const char *const rdac2_mux_text[] = { "RX1", "RX2" }; static const char *const hph_text[] = { "ZERO", "Switch", };
static const struct soc_enum hph_enum = SOC_ENUM_SINGLE_VIRT( @@ -318,7 +318,7 @@ static const struct soc_enum adc2_enum = SOC_ENUM_SINGLE_VIRT(
/* RDAC2 MUX */ static const struct soc_enum rdac2_mux_enum = SOC_ENUM_SINGLE( - CDC_D_CDC_CONN_HPHR_DAC_CTL, 0, 3, rdac2_mux_text); + CDC_D_CDC_CONN_HPHR_DAC_CTL, 0, 2, rdac2_mux_text);
static const struct snd_kcontrol_new spkr_switch[] = { SOC_DAPM_SINGLE("Switch", CDC_A_SPKR_DAC_CTL, 7, 1, 0)
From: Xiaojun Sang xsang@codeaurora.org
[ Upstream commit d3645b055399538415586ebaacaedebc1e5899b0 ]
Parameter fragments and fragment_size are type of u32. U32_MAX is the correct check.
Signed-off-by: Xiaojun Sang xsang@codeaurora.org Signed-off-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org Acked-by: Vinod Koul vkoul@kernel.org Link: https://lore.kernel.org/r/20191021095432.5639-1-srinivas.kandagatla@linaro.o... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/core/compress_offload.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c index 2e2d184684911..7ae8e24dc1e61 100644 --- a/sound/core/compress_offload.c +++ b/sound/core/compress_offload.c @@ -529,7 +529,7 @@ static int snd_compress_check_input(struct snd_compr_params *params) { /* first let's check the buffer parameter's */ if (params->buffer.fragment_size == 0 || - params->buffer.fragments > INT_MAX / params->buffer.fragment_size || + params->buffer.fragments > U32_MAX / params->buffer.fragment_size || params->buffer.fragments == 0) return -EINVAL;
From: Kishon Vijay Abraham I kishon@ti.com
[ Upstream commit 532f9cd6ee994ed10403e856ca27501428048597 ]
Memory allocated for 'struct reset_control_array' in of_reset_control_array_get() is never freed in reset_control_array_put() resulting in kmemleak showing the following backtrace.
backtrace: [<00000000c5f17595>] __kmalloc+0x1b0/0x2b0 [<00000000bd499e13>] of_reset_control_array_get+0xa4/0x180 [<000000004cc02754>] 0xffff800008c669e4 [<0000000050a83b24>] platform_drv_probe+0x50/0xa0 [<00000000d3a0b0bc>] really_probe+0x108/0x348 [<000000005aa458ac>] driver_probe_device+0x58/0x100 [<000000008853626c>] device_driver_attach+0x6c/0x90 [<0000000085308d19>] __driver_attach+0x84/0xc8 [<00000000080d35f2>] bus_for_each_dev+0x74/0xc8 [<00000000dd7f015b>] driver_attach+0x20/0x28 [<00000000923ba6e6>] bus_add_driver+0x148/0x1f0 [<0000000061473b66>] driver_register+0x60/0x110 [<00000000c5bec167>] __platform_driver_register+0x40/0x48 [<000000007c764b4f>] 0xffff800008c6c020 [<0000000047ec2e8c>] do_one_initcall+0x5c/0x1b0 [<0000000093d4b50d>] do_init_module+0x54/0x1d0
Fixes: 17c82e206d2a ("reset: Add APIs to manage array of resets") Signed-off-by: Kishon Vijay Abraham I kishon@ti.com Signed-off-by: Philipp Zabel p.zabel@pengutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/reset/core.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/reset/core.c b/drivers/reset/core.c index 72b96b5c75a8f..7e0a14211c88a 100644 --- a/drivers/reset/core.c +++ b/drivers/reset/core.c @@ -513,6 +513,7 @@ static void reset_control_array_put(struct reset_control_array *resets) for (i = 0; i < resets->num_rstcs; i++) __reset_control_put_internal(resets->rstc[i]); mutex_unlock(&reset_list_mutex); + kfree(resets); }
/**
From: Russell King rmk+kernel@armlinux.org.uk
[ Upstream commit 4523817d51bc3b2ef38da768d004fda2c8bc41de ]
When our call to get the external clock fails, we forget to clean up the enabled internal clock correctly. Enable the clock after we have obtained all our resources.
Fixes: 84aac6c79bfd ("ASoC: kirkwood: fix loss of external clock at probe time") Signed-off-by: Russell King rmk+kernel@armlinux.org.uk Link: https://lore.kernel.org/r/E1iNGyK-0004oF-6A@rmk-PC.armlinux.org.uk Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/kirkwood/kirkwood-i2s.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c index 105a73cc51585..149b7cba10fb7 100644 --- a/sound/soc/kirkwood/kirkwood-i2s.c +++ b/sound/soc/kirkwood/kirkwood-i2s.c @@ -569,10 +569,6 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev) return PTR_ERR(priv->clk); }
- err = clk_prepare_enable(priv->clk); - if (err < 0) - return err; - priv->extclk = devm_clk_get(&pdev->dev, "extclk"); if (IS_ERR(priv->extclk)) { if (PTR_ERR(priv->extclk) == -EPROBE_DEFER) @@ -588,6 +584,10 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev) } }
+ err = clk_prepare_enable(priv->clk); + if (err < 0) + return err; + /* Some sensible defaults - this reflects the powerup values */ priv->ctl_play = KIRKWOOD_PLAYCTL_SIZE_24; priv->ctl_rec = KIRKWOOD_RECCTL_SIZE_24;
From: Marek Szyprowski m.szyprowski@samsung.com
[ Upstream commit e9323b664ce29547d996195e8a6129a351c39108 ]
Properly save and restore all top PLL related configuration registers during suspend/resume cycle. So far driver only handled EPLL and RPLL clocks, all other were reset to default values after suspend/resume cycle. This caused for example lower G3D (MALI Panfrost) performance after system resume, even if performance governor has been selected.
Reported-by: Reported-by: Marian Mihailescu mihailescu2m@gmail.com Fixes: 773424326b51 ("clk: samsung: exynos5420: add more registers to restore list") Signed-off-by: Marek Szyprowski m.szyprowski@samsung.com Signed-off-by: Sylwester Nawrocki s.nawrocki@samsung.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/samsung/clk-exynos5420.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index a882f7038bcec..47a14f93f8693 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -170,12 +170,18 @@ static const unsigned long exynos5x_clk_regs[] __initconst = { GATE_BUS_CPU, GATE_SCLK_CPU, CLKOUT_CMU_CPU, + CPLL_CON0, + DPLL_CON0, EPLL_CON0, EPLL_CON1, EPLL_CON2, RPLL_CON0, RPLL_CON1, RPLL_CON2, + IPLL_CON0, + SPLL_CON0, + VPLL_CON0, + MPLL_CON0, SRC_TOP0, SRC_TOP1, SRC_TOP2,
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit f430c7ed8bc22992ed528b518da465b060b9223f ]
Add a missing short description to the reset_control_ops documentation.
Signed-off-by: Randy Dunlap rdunlap@infradead.org [p.zabel@pengutronix.de: rebased and updated commit message] Signed-off-by: Philipp Zabel p.zabel@pengutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/reset-controller.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/reset-controller.h b/include/linux/reset-controller.h index adb88f8cefbcd..576caaf0c9af5 100644 --- a/include/linux/reset-controller.h +++ b/include/linux/reset-controller.h @@ -7,7 +7,7 @@ struct reset_controller_dev;
/** - * struct reset_control_ops + * struct reset_control_ops - reset controller driver callbacks * * @reset: for self-deasserting resets, does all necessary * things to reset the device
From: Alexandre Belloni alexandre.belloni@bootlin.com
[ Upstream commit 658fd65cf0b0d511de1718e48d9a28844c385ae0 ]
It is not allowed to sleep to early in the boot process and this may lead to kernel issues if the bootloader didn't prepare the slow clock and main clock.
This results in the following error and dump stack on the AriettaG25: bad: scheduling from the idle thread!
Ensure it is possible to sleep, else simply have a delay.
Reported-by: Uwe Kleine-König u.kleine-koenig@pengutronix.de Signed-off-by: Alexandre Belloni alexandre.belloni@bootlin.com Link: https://lkml.kernel.org/r/20190920153906.20887-1-alexandre.belloni@bootlin.c... Fixes: 80eded6ce8bb ("clk: at91: add slow clks driver") Tested-by: Uwe Kleine-König u.kleine-koenig@pengutronix.de Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/at91/clk-main.c | 5 ++++- drivers/clk/at91/sckc.c | 20 ++++++++++++++++---- 2 files changed, 20 insertions(+), 5 deletions(-)
diff --git a/drivers/clk/at91/clk-main.c b/drivers/clk/at91/clk-main.c index 2f97a843d6d6b..fb5c14af8cc8d 100644 --- a/drivers/clk/at91/clk-main.c +++ b/drivers/clk/at91/clk-main.c @@ -354,7 +354,10 @@ static int clk_main_probe_frequency(struct regmap *regmap) regmap_read(regmap, AT91_CKGR_MCFR, &mcfr); if (mcfr & AT91_PMC_MAINRDY) return 0; - usleep_range(MAINF_LOOP_MIN_WAIT, MAINF_LOOP_MAX_WAIT); + if (system_state < SYSTEM_RUNNING) + udelay(MAINF_LOOP_MIN_WAIT); + else + usleep_range(MAINF_LOOP_MIN_WAIT, MAINF_LOOP_MAX_WAIT); } while (time_before(prep_time, timeout));
return -ETIMEDOUT; diff --git a/drivers/clk/at91/sckc.c b/drivers/clk/at91/sckc.c index ab6ecefc49ad8..43ba2a8b03faf 100644 --- a/drivers/clk/at91/sckc.c +++ b/drivers/clk/at91/sckc.c @@ -74,7 +74,10 @@ static int clk_slow_osc_prepare(struct clk_hw *hw)
writel(tmp | AT91_SCKC_OSC32EN, sckcr);
- usleep_range(osc->startup_usec, osc->startup_usec + 1); + if (system_state < SYSTEM_RUNNING) + udelay(osc->startup_usec); + else + usleep_range(osc->startup_usec, osc->startup_usec + 1);
return 0; } @@ -197,7 +200,10 @@ static int clk_slow_rc_osc_prepare(struct clk_hw *hw)
writel(readl(sckcr) | AT91_SCKC_RCEN, sckcr);
- usleep_range(osc->startup_usec, osc->startup_usec + 1); + if (system_state < SYSTEM_RUNNING) + udelay(osc->startup_usec); + else + usleep_range(osc->startup_usec, osc->startup_usec + 1);
return 0; } @@ -310,7 +316,10 @@ static int clk_sam9x5_slow_set_parent(struct clk_hw *hw, u8 index)
writel(tmp, sckcr);
- usleep_range(SLOWCK_SW_TIME_USEC, SLOWCK_SW_TIME_USEC + 1); + if (system_state < SYSTEM_RUNNING) + udelay(SLOWCK_SW_TIME_USEC); + else + usleep_range(SLOWCK_SW_TIME_USEC, SLOWCK_SW_TIME_USEC + 1);
return 0; } @@ -443,7 +452,10 @@ static int clk_sama5d4_slow_osc_prepare(struct clk_hw *hw) return 0; }
- usleep_range(osc->startup_usec, osc->startup_usec + 1); + if (system_state < SYSTEM_RUNNING) + udelay(osc->startup_usec); + else + usleep_range(osc->startup_usec, osc->startup_usec + 1); osc->prepared = true;
return 0;
From: Colin Ian King colin.king@canonical.com
[ Upstream commit cdfc2e2086bf9c465f44e2db25561373b084a113 ]
The zero'ing of bits 16 and 18 is incorrect. Currently the code is masking with the bitwise-and of BIT(16) & BIT(18) which is 0, so the updated value for val is always zero. Fix this by bitwise and-ing value with the correct mask that will zero bits 16 and 18.
Addresses-Coverity: (" Suspicious &= or |= constant expression") Fixes: b8eb71dcdd08 ("clk: sunxi-ng: Add A80 CCU") Signed-off-by: Colin Ian King colin.king@canonical.com Signed-off-by: Maxime Ripard mripard@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/sunxi-ng/ccu-sun9i-a80.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/clk/sunxi-ng/ccu-sun9i-a80.c b/drivers/clk/sunxi-ng/ccu-sun9i-a80.c index 8936ef87652c0..c14bf782b2b33 100644 --- a/drivers/clk/sunxi-ng/ccu-sun9i-a80.c +++ b/drivers/clk/sunxi-ng/ccu-sun9i-a80.c @@ -1231,7 +1231,7 @@ static int sun9i_a80_ccu_probe(struct platform_device *pdev)
/* Enforce d1 = 0, d2 = 0 for Audio PLL */ val = readl(reg + SUN9I_A80_PLL_AUDIO_REG); - val &= (BIT(16) & BIT(18)); + val &= ~(BIT(16) | BIT(18)); writel(val, reg + SUN9I_A80_PLL_AUDIO_REG);
/* Enforce P = 1 for both CPU cluster PLLs */
From: Matthew Wilcox (Oracle) willy@infradead.org
[ Upstream commit b7e9728f3d7fc5c5c8508d99f1675212af5cfd49 ]
Attempting to allocate an entry at 0xffffffff when one is already present would succeed in allocating one at 2^32, which would confuse everything. Return -ENOSPC in this case, as expected.
Signed-off-by: Matthew Wilcox (Oracle) willy@infradead.org Signed-off-by: Sasha Levin sashal@kernel.org --- lib/radix-tree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/radix-tree.c b/lib/radix-tree.c index d172f0341b807..ff00c816266b1 100644 --- a/lib/radix-tree.c +++ b/lib/radix-tree.c @@ -2184,7 +2184,7 @@ void __rcu **idr_get_free_cmn(struct radix_tree_root *root, offset = radix_tree_find_next_bit(node, IDR_FREE, offset + 1); start = next_index(start, node, offset); - if (start > max) + if (start > max || start == 0) return ERR_PTR(-ENOSPC); while (offset == RADIX_TREE_MAP_SIZE) { offset = node->offset + 1;
From: Xiaochen Shen xiaochen.shen@intel.com
[ Upstream commit 26467b0f8407cbd628fa5b7bcfd156e772004155 ]
When a mon group is being deleted, rdtgrp->flags is set to RDT_DELETED in rdtgroup_rmdir_mon() firstly. The structure of rdtgrp will be freed until rdtgrp->waitcount is dropped to 0 in rdtgroup_kn_unlock() later.
During the window of deleting a mon group, if an application calls rdtgroup_mondata_show() to read mondata under this mon group, 'rdtgrp' returned from rdtgroup_kn_lock_live() is a NULL pointer when rdtgrp->flags is RDT_DELETED. And then 'rdtgrp' is passed in this path: rdtgroup_mondata_show() --> mon_event_read() --> mon_event_count(). Thus it results in NULL pointer dereference in mon_event_count().
Check 'rdtgrp' in rdtgroup_mondata_show(), and return -ENOENT immediately when reading mondata during the window of deleting a mon group.
Fixes: d89b7379015f ("x86/intel_rdt/cqm: Add mon_data") Signed-off-by: Xiaochen Shen xiaochen.shen@intel.com Signed-off-by: Borislav Petkov bp@suse.de Reviewed-by: Fenghua Yu fenghua.yu@intel.com Reviewed-by: Tony Luck tony.luck@intel.com Cc: "H. Peter Anvin" hpa@zytor.com Cc: Ingo Molnar mingo@redhat.com Cc: pei.p.jia@intel.com Cc: Reinette Chatre reinette.chatre@intel.com Cc: Thomas Gleixner tglx@linutronix.de Cc: x86-ml x86@kernel.org Link: https://lkml.kernel.org/r/1572326702-27577-1-git-send-email-xiaochen.shen@in... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/kernel/cpu/intel_rdt_ctrlmondata.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/arch/x86/kernel/cpu/intel_rdt_ctrlmondata.c b/arch/x86/kernel/cpu/intel_rdt_ctrlmondata.c index f6ea94f8954a7..f892cb0b485e1 100644 --- a/arch/x86/kernel/cpu/intel_rdt_ctrlmondata.c +++ b/arch/x86/kernel/cpu/intel_rdt_ctrlmondata.c @@ -313,6 +313,10 @@ int rdtgroup_mondata_show(struct seq_file *m, void *arg) int ret = 0;
rdtgrp = rdtgroup_kn_lock_live(of->kn); + if (!rdtgrp) { + ret = -ENOENT; + goto out; + }
md.priv = of->kn->priv; resid = md.u.rid;
From: Peter Ujfalusi peter.ujfalusi@ti.com
[ Upstream commit 9982b0f69b49931b652d35f86f519be2ccfc7027 ]
ti_clk_register() calls it already so the driver should not create duplicated alias.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@ti.com Link: https://lkml.kernel.org/r/20191002083436.10194-1-peter.ujfalusi@ti.com Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/ti/clk-dra7-atl.c | 6 ------ 1 file changed, 6 deletions(-)
diff --git a/drivers/clk/ti/clk-dra7-atl.c b/drivers/clk/ti/clk-dra7-atl.c index 1488154704313..beb672a215b6c 100644 --- a/drivers/clk/ti/clk-dra7-atl.c +++ b/drivers/clk/ti/clk-dra7-atl.c @@ -174,7 +174,6 @@ static void __init of_dra7_atl_clock_setup(struct device_node *node) struct clk_init_data init = { NULL }; const char **parent_names = NULL; struct clk *clk; - int ret;
clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL); if (!clk_hw) { @@ -207,11 +206,6 @@ static void __init of_dra7_atl_clock_setup(struct device_node *node) clk = ti_clk_register(NULL, &clk_hw->hw, node->name);
if (!IS_ERR(clk)) { - ret = ti_clk_add_alias(NULL, clk, node->name); - if (ret) { - clk_unregister(clk); - goto cleanup; - } of_clk_add_provider(node, of_clk_src_simple_get, clk); kfree(parent_names); return;
From: Chuhong Yuan hslester96@gmail.com
[ Upstream commit c43eab3eddb4c6742ac20138659a9b701822b274 ]
This driver forgets to disable and unprepare clks when remove. Add calls to clk_disable_unprepare to fix it.
Signed-off-by: Chuhong Yuan hslester96@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/freescale/fec_main.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 0ae6532b02e09..0237221059bfd 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -3574,6 +3574,8 @@ fec_drv_remove(struct platform_device *pdev) regulator_disable(fep->reg_phy); pm_runtime_put(&pdev->dev); pm_runtime_disable(&pdev->dev); + clk_disable_unprepare(fep->clk_ahb); + clk_disable_unprepare(fep->clk_ipg); if (of_phy_is_fixed_link(np)) of_phy_deregister_fixed_link(np); of_node_put(fep->phy_node);
From: Florian Westphal fw@strlen.de
[ Upstream commit b23c0742c2ce7e33ed79d10e451f70fdb5ca85d1 ]
xt_in() returns NULL in the output hook, skip the pkt_type change for that case, redirection only makes sense in broute/prerouting hooks.
Reported-by: Tom Yan tom.ty89@gmail.com Cc: Linus Lüssing linus.luessing@c0d3.blue Fixes: cf3cb246e277d ("bridge: ebtables: fix reception of frames DNAT-ed to bridge device/port") Signed-off-by: Florian Westphal fw@strlen.de Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/bridge/netfilter/ebt_dnat.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/net/bridge/netfilter/ebt_dnat.c b/net/bridge/netfilter/ebt_dnat.c index dfc86a0199dab..1d8c834d90189 100644 --- a/net/bridge/netfilter/ebt_dnat.c +++ b/net/bridge/netfilter/ebt_dnat.c @@ -19,7 +19,6 @@ static unsigned int ebt_dnat_tg(struct sk_buff *skb, const struct xt_action_param *par) { const struct ebt_nat_info *info = par->targinfo; - struct net_device *dev;
if (!skb_make_writable(skb, 0)) return EBT_DROP; @@ -32,10 +31,22 @@ ebt_dnat_tg(struct sk_buff *skb, const struct xt_action_param *par) else skb->pkt_type = PACKET_MULTICAST; } else { - if (xt_hooknum(par) != NF_BR_BROUTING) - dev = br_port_get_rcu(xt_in(par))->br->dev; - else + const struct net_device *dev; + + switch (xt_hooknum(par)) { + case NF_BR_BROUTING: dev = xt_in(par); + break; + case NF_BR_PRE_ROUTING: + dev = br_port_get_rcu(xt_in(par))->br->dev; + break; + default: + dev = NULL; + break; + } + + if (!dev) /* NF_BR_LOCAL_OUT */ + return info->target;
if (ether_addr_equal(info->mac, dev->dev_addr)) skb->pkt_type = PACKET_HOST;
From: Jeroen Hofstee jhofstee@victronenergy.com
[ Upstream commit 128a1b87d3ceb2ba449d5aadb222fe22395adeb0 ]
While the state changes are reported when the error counters increase and decrease, there is no event when the bus recovers and the error counters decrease again. So add those as well.
Change the state going downward to be ERROR_PASSIVE -> ERROR_WARNING -> ERROR_ACTIVE instead of directly to ERROR_ACTIVE again.
Signed-off-by: Jeroen Hofstee jhofstee@victronenergy.com Cc: Stephane Grosjean s.grosjean@peak-system.com Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/can/usb/peak_usb/pcan_usb.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb.c b/drivers/net/can/usb/peak_usb/pcan_usb.c index e626c2afbbb11..0e1fc6c4360e7 100644 --- a/drivers/net/can/usb/peak_usb/pcan_usb.c +++ b/drivers/net/can/usb/peak_usb/pcan_usb.c @@ -441,8 +441,8 @@ static int pcan_usb_decode_error(struct pcan_usb_msg_context *mc, u8 n, } if ((n & PCAN_USB_ERROR_BUS_LIGHT) == 0) { /* no error (back to active state) */ - mc->pdev->dev.can.state = CAN_STATE_ERROR_ACTIVE; - return 0; + new_state = CAN_STATE_ERROR_ACTIVE; + break; } break;
@@ -465,9 +465,9 @@ static int pcan_usb_decode_error(struct pcan_usb_msg_context *mc, u8 n, }
if ((n & PCAN_USB_ERROR_BUS_HEAVY) == 0) { - /* no error (back to active state) */ - mc->pdev->dev.can.state = CAN_STATE_ERROR_ACTIVE; - return 0; + /* no error (back to warning state) */ + new_state = CAN_STATE_ERROR_WARNING; + break; } break;
@@ -506,6 +506,11 @@ static int pcan_usb_decode_error(struct pcan_usb_msg_context *mc, u8 n, mc->pdev->dev.can.can_stats.error_warning++; break;
+ case CAN_STATE_ERROR_ACTIVE: + cf->can_id |= CAN_ERR_CRTL; + cf->data[1] = CAN_ERR_CRTL_ACTIVE; + break; + default: /* CAN_STATE_MAX (trick to handle other errors) */ cf->can_id |= CAN_ERR_CRTL;
From: Jeroen Hofstee jhofstee@victronenergy.com
[ Upstream commit 23c5a9488f076bab336177cd1d1a366bd8ddf087 ]
When the CAN interface is closed it the hardwre is put in power down mode, but does not reset the error counters / state. Reset the D_CAN on open, so the reported state and the actual state match.
According to [1], the C_CAN module doesn't have the software reset.
[1] http://www.bosch-semiconductors.com/media/ip_modules/pdf_2/c_can_fd8/users_m...
Signed-off-by: Jeroen Hofstee jhofstee@victronenergy.com Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/can/c_can/c_can.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c index 9b61bfbea6cd1..24c6015f6c92b 100644 --- a/drivers/net/can/c_can/c_can.c +++ b/drivers/net/can/c_can/c_can.c @@ -52,6 +52,7 @@ #define CONTROL_EX_PDR BIT(8)
/* control register */ +#define CONTROL_SWR BIT(15) #define CONTROL_TEST BIT(7) #define CONTROL_CCE BIT(6) #define CONTROL_DISABLE_AR BIT(5) @@ -572,6 +573,26 @@ static void c_can_configure_msg_objects(struct net_device *dev) IF_MCONT_RCV_EOB); }
+static int c_can_software_reset(struct net_device *dev) +{ + struct c_can_priv *priv = netdev_priv(dev); + int retry = 0; + + if (priv->type != BOSCH_D_CAN) + return 0; + + priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_SWR | CONTROL_INIT); + while (priv->read_reg(priv, C_CAN_CTRL_REG) & CONTROL_SWR) { + msleep(20); + if (retry++ > 100) { + netdev_err(dev, "CCTRL: software reset failed\n"); + return -EIO; + } + } + + return 0; +} + /* * Configure C_CAN chip: * - enable/disable auto-retransmission @@ -581,6 +602,11 @@ static void c_can_configure_msg_objects(struct net_device *dev) static int c_can_chip_config(struct net_device *dev) { struct c_can_priv *priv = netdev_priv(dev); + int err; + + err = c_can_software_reset(dev); + if (err) + return err;
/* enable automatic retransmission */ priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_ENABLE_AR);
From: Marc Kleine-Budde mkl@pengutronix.de
[ Upstream commit 6caf8a6d6586d44fd72f4aa1021d14aa82affafb ]
If the rx-offload skb_queue is full can_rx_offload_queue_tail() will not queue the skb and return with an error.
This patch frees the skb in case of a full queue, which brings can_rx_offload_queue_tail() in line with the can_rx_offload_queue_sorted() function, which has been adjusted in the previous patch.
The return value is adjusted to -ENOBUFS to better reflect the actual problem.
The device stats handling is left to the caller.
Fixes: d254586c3453 ("can: rx-offload: Add support for HW fifo based irq offloading") Reported-by: Kurt Van Dijck dev.kurt@vandijck-laurijssen.be Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/can/rx-offload.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/can/rx-offload.c b/drivers/net/can/rx-offload.c index 1a7c183e66783..b26987a136203 100644 --- a/drivers/net/can/rx-offload.c +++ b/drivers/net/can/rx-offload.c @@ -261,8 +261,10 @@ int can_rx_offload_queue_tail(struct can_rx_offload *offload, struct sk_buff *skb) { if (skb_queue_len(&offload->skb_queue) > - offload->skb_queue_len_max) - return -ENOMEM; + offload->skb_queue_len_max) { + kfree_skb(skb); + return -ENOBUFS; + }
skb_queue_tail(&offload->skb_queue, skb); can_rx_offload_schedule(offload);
From: Marc Kleine-Budde mkl@pengutronix.de
[ Upstream commit a2dc3f5e1022a5ede8af9ab89a144f1e69db8636 ]
The skb_queue is a linked list, holding the skb to be processed in the next NAPI call.
Without this patch, the queue length in can_rx_offload_offload_one() is limited to skb_queue_len_max + 1. As the skb_queue is a linked list, no array or other resources are accessed out-of-bound, however this behaviour is counterintuitive.
This patch limits the rx-offload skb_queue length to skb_queue_len_max.
Fixes: d254586c3453 ("can: rx-offload: Add support for HW fifo based irq offloading") Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/can/rx-offload.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/can/rx-offload.c b/drivers/net/can/rx-offload.c index b26987a136203..c0e51a2f8e4fc 100644 --- a/drivers/net/can/rx-offload.c +++ b/drivers/net/can/rx-offload.c @@ -124,7 +124,7 @@ static struct sk_buff *can_rx_offload_offload_one(struct can_rx_offload *offload int ret;
/* If queue is full or skb not available, read to discard mailbox */ - if (likely(skb_queue_len(&offload->skb_queue) <= + if (likely(skb_queue_len(&offload->skb_queue) < offload->skb_queue_len_max)) skb = alloc_can_skb(offload->dev, &cf);
From: Marc Kleine-Budde mkl@pengutronix.de
[ Upstream commit 4e9016bee3bf0c24963097edace034ff205b565c ]
If the rx-offload skb_queue is full or the skb allocation fails (due to OOM), the mailbox contents is discarded.
This patch adds the incrementing of the rx_fifo_errors statistics counter.
Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/can/rx-offload.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/can/rx-offload.c b/drivers/net/can/rx-offload.c index c0e51a2f8e4fc..b068e2320c794 100644 --- a/drivers/net/can/rx-offload.c +++ b/drivers/net/can/rx-offload.c @@ -134,8 +134,10 @@ static struct sk_buff *can_rx_offload_offload_one(struct can_rx_offload *offload
ret = offload->mailbox_read(offload, &cf_overflow, ×tamp, n); - if (ret) + if (ret) { offload->dev->stats.rx_dropped++; + offload->dev->stats.rx_fifo_errors++; + }
return NULL; }
From: Marc Kleine-Budde mkl@pengutronix.de
[ Upstream commit d763ab3044f0bf50bd0e6179f6b2cf1c125d1d94 ]
Before this patch can_rx_offload_offload_one() returns a pointer to a skb containing the read CAN frame or a NULL pointer.
However the meaning of the NULL pointer is ambiguous, it can either mean the requested mailbox is empty or there was an error.
This patch fixes this situation by returning: - pointer to skb on success - NULL pointer if mailbox is empty - ERR_PTR() in case of an error
All users of can_rx_offload_offload_one() have been adopted, no functional change intended.
Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/can/rx-offload.c | 86 ++++++++++++++++++++++++++++++------ 1 file changed, 73 insertions(+), 13 deletions(-)
diff --git a/drivers/net/can/rx-offload.c b/drivers/net/can/rx-offload.c index b068e2320c794..840aef094f208 100644 --- a/drivers/net/can/rx-offload.c +++ b/drivers/net/can/rx-offload.c @@ -116,39 +116,95 @@ static int can_rx_offload_compare(struct sk_buff *a, struct sk_buff *b) return cb_b->timestamp - cb_a->timestamp; }
-static struct sk_buff *can_rx_offload_offload_one(struct can_rx_offload *offload, unsigned int n) +/** + * can_rx_offload_offload_one() - Read one CAN frame from HW + * @offload: pointer to rx_offload context + * @n: number of mailbox to read + * + * The task of this function is to read a CAN frame from mailbox @n + * from the device and return the mailbox's content as a struct + * sk_buff. + * + * If the struct can_rx_offload::skb_queue exceeds the maximal queue + * length (struct can_rx_offload::skb_queue_len_max) or no skb can be + * allocated, the mailbox contents is discarded by reading it into an + * overflow buffer. This way the mailbox is marked as free by the + * driver. + * + * Return: A pointer to skb containing the CAN frame on success. + * + * NULL if the mailbox @n is empty. + * + * ERR_PTR() in case of an error + */ +static struct sk_buff * +can_rx_offload_offload_one(struct can_rx_offload *offload, unsigned int n) { - struct sk_buff *skb = NULL; + struct sk_buff *skb = NULL, *skb_error = NULL; struct can_rx_offload_cb *cb; struct can_frame *cf; int ret;
- /* If queue is full or skb not available, read to discard mailbox */ if (likely(skb_queue_len(&offload->skb_queue) < - offload->skb_queue_len_max)) + offload->skb_queue_len_max)) { skb = alloc_can_skb(offload->dev, &cf); + if (unlikely(!skb)) + skb_error = ERR_PTR(-ENOMEM); /* skb alloc failed */ + } else { + skb_error = ERR_PTR(-ENOBUFS); /* skb_queue is full */ + }
- if (!skb) { + /* If queue is full or skb not available, drop by reading into + * overflow buffer. + */ + if (unlikely(skb_error)) { struct can_frame cf_overflow; u32 timestamp;
ret = offload->mailbox_read(offload, &cf_overflow, ×tamp, n); - if (ret) { - offload->dev->stats.rx_dropped++; - offload->dev->stats.rx_fifo_errors++; - }
- return NULL; + /* Mailbox was empty. */ + if (unlikely(!ret)) + return NULL; + + /* Mailbox has been read and we're dropping it or + * there was a problem reading the mailbox. + * + * Increment error counters in any case. + */ + offload->dev->stats.rx_dropped++; + offload->dev->stats.rx_fifo_errors++; + + /* There was a problem reading the mailbox, propagate + * error value. + */ + if (unlikely(ret < 0)) + return ERR_PTR(ret); + + return skb_error; }
cb = can_rx_offload_get_cb(skb); ret = offload->mailbox_read(offload, cf, &cb->timestamp, n); - if (!ret) { + + /* Mailbox was empty. */ + if (unlikely(!ret)) { kfree_skb(skb); return NULL; }
+ /* There was a problem reading the mailbox, propagate error value. */ + if (unlikely(ret < 0)) { + kfree_skb(skb); + + offload->dev->stats.rx_dropped++; + offload->dev->stats.rx_fifo_errors++; + + return ERR_PTR(ret); + } + + /* Mailbox was read. */ return skb; }
@@ -168,7 +224,7 @@ int can_rx_offload_irq_offload_timestamp(struct can_rx_offload *offload, u64 pen continue;
skb = can_rx_offload_offload_one(offload, i); - if (!skb) + if (IS_ERR_OR_NULL(skb)) break;
__skb_queue_add_sort(&skb_queue, skb, can_rx_offload_compare); @@ -199,7 +255,11 @@ int can_rx_offload_irq_offload_fifo(struct can_rx_offload *offload) struct sk_buff *skb; int received = 0;
- while ((skb = can_rx_offload_offload_one(offload, 0))) { + while (1) { + skb = can_rx_offload_offload_one(offload, 0); + if (IS_ERR_OR_NULL(skb)) + break; + skb_queue_tail(&offload->skb_queue, skb); received++; }
From: Jeroen Hofstee jhofstee@victronenergy.com
[ Upstream commit c2a9f74c9d18acfdcabd3361adc7eac82c537a66 ]
In case of a resource shortage, i.e. the rx_offload queue will overflow or a skb fails to be allocated (due to OOM), can_rx_offload_offload_one() will call mailbox_read() to discard the mailbox and return an ERR_PTR.
However can_rx_offload_irq_offload_timestamp() bails out in the error case. In case of a resource shortage all mailboxes should be discarded, to avoid an IRQ storm and give the system some time to recover.
Since can_rx_offload_irq_offload_timestamp() is typically called from a while loop, all message will eventually be discarded. So let's continue on error instead to discard them directly.
Signed-off-by: Jeroen Hofstee jhofstee@victronenergy.com Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/can/rx-offload.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/can/rx-offload.c b/drivers/net/can/rx-offload.c index 840aef094f208..fef6534f163b7 100644 --- a/drivers/net/can/rx-offload.c +++ b/drivers/net/can/rx-offload.c @@ -225,7 +225,7 @@ int can_rx_offload_irq_offload_timestamp(struct can_rx_offload *offload, u64 pen
skb = can_rx_offload_offload_one(offload, i); if (IS_ERR_OR_NULL(skb)) - break; + continue;
__skb_queue_add_sort(&skb_queue, skb, can_rx_offload_compare); }
From: Marc Kleine-Budde mkl@pengutronix.de
[ Upstream commit 1f7f504dcd9d1262437bdcf4fa071e41dec1af03 ]
In case of a resource shortage, i.e. the rx_offload queue will overflow or a skb fails to be allocated (due to OOM), can_rx_offload_offload_one() will call mailbox_read() to discard the mailbox and return an ERR_PTR.
If the hardware FIFO is empty can_rx_offload_offload_one() will return NULL.
In case a CAN frame was read from the hardware, can_rx_offload_offload_one() returns the skb containing it.
Without this patch can_rx_offload_irq_offload_fifo() bails out if no skb returned, regardless of the reason.
Similar to can_rx_offload_irq_offload_timestamp() in case of a resource shortage the whole FIFO should be discarded, to avoid an IRQ storm and give the system some time to recover. However if the FIFO is empty the loop can be left.
With this patch the loop is left in case of empty FIFO, but not on errors.
Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/can/rx-offload.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/can/rx-offload.c b/drivers/net/can/rx-offload.c index fef6534f163b7..54ffd1e91a693 100644 --- a/drivers/net/can/rx-offload.c +++ b/drivers/net/can/rx-offload.c @@ -257,7 +257,9 @@ int can_rx_offload_irq_offload_fifo(struct can_rx_offload *offload)
while (1) { skb = can_rx_offload_offload_one(offload, 0); - if (IS_ERR_OR_NULL(skb)) + if (IS_ERR(skb)) + continue; + if (!skb) break;
skb_queue_tail(&offload->skb_queue, skb);
From: Xingyu Chen xingyu.chen@amlogic.com
[ Upstream commit 2c77734642d52448aca673e889b39f981110828b ]
The left time value is wrong when we get it by sysfs. The left time value should be equal to preset timeout value minus elapsed time value. According to the Meson-GXB/GXL datasheets which can be found at [0], the timeout value is saved to BIT[0-15] of the WATCHDOG_TCNT, and elapsed time value is saved to BIT[16-31] of the WATCHDOG_TCNT.
Fixes: 683fa50f0e18 ("watchdog: Add Meson GXBB Watchdog Driver") Signed-off-by: Xingyu Chen xingyu.chen@amlogic.com Acked-by: Neil Armstrong narmstrong@baylibre.com Reviewed-by: Kevin Hilman khilman@baylibre.com Reviewed-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Wim Van Sebroeck wim@linux-watchdog.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/watchdog/meson_gxbb_wdt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/watchdog/meson_gxbb_wdt.c b/drivers/watchdog/meson_gxbb_wdt.c index 69a5a57f14462..61297a6ab43a0 100644 --- a/drivers/watchdog/meson_gxbb_wdt.c +++ b/drivers/watchdog/meson_gxbb_wdt.c @@ -137,8 +137,8 @@ static unsigned int meson_gxbb_wdt_get_timeleft(struct watchdog_device *wdt_dev)
reg = readl(data->reg_base + GXBB_WDT_TCNT_REG);
- return ((reg >> GXBB_WDT_TCNT_CNT_SHIFT) - - (reg & GXBB_WDT_TCNT_SETUP_MASK)) / 1000; + return ((reg & GXBB_WDT_TCNT_SETUP_MASK) - + (reg >> GXBB_WDT_TCNT_CNT_SHIFT)) / 1000; }
static const struct watchdog_ops meson_gxbb_wdt_ops = {
From: Ilya Leoshkevich iii@linux.ibm.com
[ Upstream commit 8731acc5068eb3f422a45c760d32198175c756f8 ]
gcc's -freorder-blocks-and-partition option makes it group frequently and infrequently used code in .text.hot and .text.unlikely sections respectively. At least when building modules on s390, this option is used by default.
gdb assumes that all code is located in .text section, and that .text section is located at module load address. With such modules this is no longer the case: there is code in .text.hot and .text.unlikely, and either of them might precede .text.
Fix by explicitly telling gdb the addresses of code sections.
It might be tempting to do this for all sections, not only the ones in the white list. Unfortunately, gdb appears to have an issue, when telling it about e.g. loadable .note.gnu.build-id section causes it to think that non-loadable .note.Linux section is loaded at address 0, which in turn causes NULL pointers to be resolved to bogus symbols. So keep using the white list approach for the time being.
Link: http://lkml.kernel.org/r/20191028152734.13065-1-iii@linux.ibm.com Signed-off-by: Ilya Leoshkevich iii@linux.ibm.com Reviewed-by: Jan Kiszka jan.kiszka@siemens.com Cc: Kieran Bingham kbingham@kernel.org Cc: Heiko Carstens heiko.carstens@de.ibm.com Cc: Vasily Gorbik gor@linux.ibm.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- scripts/gdb/linux/symbols.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/scripts/gdb/linux/symbols.py b/scripts/gdb/linux/symbols.py index 004b0ac7fa72d..4644f1a83b578 100644 --- a/scripts/gdb/linux/symbols.py +++ b/scripts/gdb/linux/symbols.py @@ -99,7 +99,8 @@ lx-symbols command.""" attrs[n]['name'].string(): attrs[n]['address'] for n in range(int(sect_attrs['nsections']))} args = [] - for section_name in [".data", ".data..read_mostly", ".rodata", ".bss"]: + for section_name in [".data", ".data..read_mostly", ".rodata", ".bss", + ".text", ".text.hot", ".text.unlikely"]: address = section_name_to_address.get(section_name) if address: args.append(" -s {name} {addr}".format(
From: Doug Berger opendmb@gmail.com
[ Upstream commit 0686bd9d5e6863f60e4bb1e78e6fe7bb217a0890 ]
The phy_init_hw() function may reset the PHY to a configuration that does not match manual network settings stored in the phydev structure. If the phy state machine is polled rather than event driven this can create a timing hazard where the phy state machine might alter the settings stored in the phydev structure from the value read from the BMCR.
This commit follows invocations of phy_init_hw() by the bcmgenet driver with invocations of the genphy_config_aneg() function to ensure that the BMCR is written to match the settings held in the phydev structure. This prevents the risk of manual settings being accidentally altered.
Fixes: 1c1008c793fa ("net: bcmgenet: add main driver file") Signed-off-by: Doug Berger opendmb@gmail.com Acked-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index b6af286fa5c7e..3e3044fe32066 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -2611,8 +2611,10 @@ static void bcmgenet_irq_task(struct work_struct *work) }
if (status & UMAC_IRQ_PHY_DET_R && - priv->dev->phydev->autoneg != AUTONEG_ENABLE) + priv->dev->phydev->autoneg != AUTONEG_ENABLE) { phy_init_hw(priv->dev->phydev); + genphy_config_aneg(priv->dev->phydev); + }
/* Link UP/DOWN event */ if (status & UMAC_IRQ_LINK_EVENT) @@ -3688,6 +3690,7 @@ static int bcmgenet_resume(struct device *d)
phy_init_hw(priv->phydev); /* Speed settings must be restored */ + genphy_config_aneg(dev->phydev); bcmgenet_mii_config(priv->dev, false);
/* disable ethernet MAC while updating its registers */
From: Jeff Layton jlayton@kernel.org
[ Upstream commit ff29fde84d1fc82f233c7da0daa3574a3942bec7 ]
If someone requests fscache on the mount, and the kernel doesn't support it, it should fail the mount.
[ Drop ceph prefix -- it's provided by pr_err. ]
Signed-off-by: Jeff Layton jlayton@kernel.org Reviewed-by: Ilya Dryomov idryomov@gmail.com Signed-off-by: Ilya Dryomov idryomov@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/ceph/super.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/fs/ceph/super.c b/fs/ceph/super.c index f0694293b31a2..088c4488b4492 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -232,6 +232,7 @@ static int parse_fsopt_token(char *c, void *private) return -ENOMEM; break; case Opt_fscache_uniq: +#ifdef CONFIG_CEPH_FSCACHE kfree(fsopt->fscache_uniq); fsopt->fscache_uniq = kstrndup(argstr[0].from, argstr[0].to-argstr[0].from, @@ -240,7 +241,10 @@ static int parse_fsopt_token(char *c, void *private) return -ENOMEM; fsopt->flags |= CEPH_MOUNT_OPT_FSCACHE; break; - /* misc */ +#else + pr_err("fscache support is disabled\n"); + return -EINVAL; +#endif case Opt_wsize: if (intval < PAGE_SIZE || intval > CEPH_MAX_WRITE_SIZE) return -EINVAL; @@ -312,8 +316,13 @@ static int parse_fsopt_token(char *c, void *private) fsopt->flags &= ~CEPH_MOUNT_OPT_INO32; break; case Opt_fscache: +#ifdef CONFIG_CEPH_FSCACHE fsopt->flags |= CEPH_MOUNT_OPT_FSCACHE; break; +#else + pr_err("fscache support is disabled\n"); + return -EINVAL; +#endif case Opt_nofscache: fsopt->flags &= ~CEPH_MOUNT_OPT_FSCACHE; break;
From: Ahmed Zaki anzaki@gmail.com
[ Upstream commit 285531f9e6774e3be71da6673d475ff1a088d675 ]
In the first 5 minutes after boot (time of INITIAL_JIFFIES), ieee80211_sta_last_active() returns zero if last_ack is zero. This leads to "inactive time" showing jiffies_to_msecs(jiffies).
# iw wlan0 station get fc:ec:da:64:a6:dd Station fc:ec:da:64:a6:dd (on wlan0) inactive time: 4294894049 ms . . connected time: 70 seconds
Fix by returning last_rx if last_ack == 0.
Signed-off-by: Ahmed Zaki anzaki@gmail.com Link: https://lore.kernel.org/r/20191031121243.27694-1-anzaki@gmail.com Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/mac80211/sta_info.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index f1b496222bda6..1a86974b02e39 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -2313,7 +2313,8 @@ unsigned long ieee80211_sta_last_active(struct sta_info *sta) { struct ieee80211_sta_rx_stats *stats = sta_get_last_rx_stats(sta);
- if (time_after(stats->last_rx, sta->status_stats.last_ack)) + if (!sta->status_stats.last_ack || + time_after(stats->last_rx, sta->status_stats.last_ack)) return stats->last_rx; return sta->status_stats.last_ack; }
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit 8e9c523016cf9983b295e4bc659183d1fa6ef8e0 ]
There are two callers of this function and they both unlock the mutex so this ends up being a double unlock.
Fixes: 44ed167da748 ("drbd: rcu_read_lock() and rcu_dereference() for tconn->net_conf") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/block/drbd/drbd_main.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 8cb3791898ae9..7ea13b5497fdc 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -795,7 +795,6 @@ int __drbd_send_protocol(struct drbd_connection *connection, enum drbd_packet cm
if (nc->tentative && connection->agreed_pro_version < 92) { rcu_read_unlock(); - mutex_unlock(&sock->mutex); drbd_err(connection, "--dry-run is not supported by peer"); return -EOPNOTSUPP; }
From: Uwe Kleine-König u.kleine-koenig@pengutronix.de
[ Upstream commit 24906a41eecb73d51974ade0847c21e429beec60 ]
The owner member of struct pwm_ops must be set to THIS_MODULE to increase the reference count of the module such that the module cannot be removed while its code is in use.
Fixes: daa5abc41c80 ("pwm: Add support for Broadcom iProc PWM controller") Signed-off-by: Uwe Kleine-König u.kleine-koenig@pengutronix.de Reviewed-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: Thierry Reding thierry.reding@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pwm/pwm-bcm-iproc.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/pwm/pwm-bcm-iproc.c b/drivers/pwm/pwm-bcm-iproc.c index d961a8207b1cb..31b01035d0ab3 100644 --- a/drivers/pwm/pwm-bcm-iproc.c +++ b/drivers/pwm/pwm-bcm-iproc.c @@ -187,6 +187,7 @@ static int iproc_pwmc_apply(struct pwm_chip *chip, struct pwm_device *pwm, static const struct pwm_ops iproc_pwm_ops = { .apply = iproc_pwmc_apply, .get_state = iproc_pwmc_get_state, + .owner = THIS_MODULE, };
static int iproc_pwmc_probe(struct platform_device *pdev)
From: James Smart jsmart2021@gmail.com
[ Upstream commit 5a9eeff57f340238c39c95d8e7e54c96fc722de7 ]
Driver is hitting null pring pointers in lpfc_do_work().
Pointer assignment occurs based on SLI-revision. If recovering after an error, its possible the sli revision for the port was cleared, making the lpfc_phba_elsring() not return a ring pointer, thus the null pointer.
Add SLI revision checking to lpfc_phba_elsring() and status checking to all callers.
Signed-off-by: Dick Kennedy dick.kennedy@broadcom.com Signed-off-by: James Smart jsmart2021@gmail.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/lpfc/lpfc.h | 6 ++++++ drivers/scsi/lpfc/lpfc_els.c | 2 ++ drivers/scsi/lpfc/lpfc_init.c | 7 ++++++- drivers/scsi/lpfc/lpfc_sli.c | 2 ++ 4 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index bc61cc8bc6f02..03e95a3216c8c 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h @@ -1239,6 +1239,12 @@ lpfc_sli_read_hs(struct lpfc_hba *phba) static inline struct lpfc_sli_ring * lpfc_phba_elsring(struct lpfc_hba *phba) { + /* Return NULL if sli_rev has become invalid due to bad fw */ + if (phba->sli_rev != LPFC_SLI_REV4 && + phba->sli_rev != LPFC_SLI_REV3 && + phba->sli_rev != LPFC_SLI_REV2) + return NULL; + if (phba->sli_rev == LPFC_SLI_REV4) { if (phba->sli4_hba.els_wq) return phba->sli4_hba.els_wq->pring; diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index e5db20e8979d5..a31f87eb1e621 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -1337,6 +1337,8 @@ lpfc_els_abort_flogi(struct lpfc_hba *phba) Fabric_DID);
pring = lpfc_phba_elsring(phba); + if (unlikely(!pring)) + return -EIO;
/* * Check the txcmplq for an iocb that matches the nport the driver is diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 15bcd00dd7a23..c69c2a2b2eadf 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -1773,7 +1773,12 @@ lpfc_sli4_port_sta_fn_reset(struct lpfc_hba *phba, int mbx_action, lpfc_offline(phba); /* release interrupt for possible resource change */ lpfc_sli4_disable_intr(phba); - lpfc_sli_brdrestart(phba); + rc = lpfc_sli_brdrestart(phba); + if (rc) { + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, + "6309 Failed to restart board\n"); + return rc; + } /* request and enable interrupt */ intr_mode = lpfc_sli4_enable_intr(phba, phba->intr_mode); if (intr_mode == LPFC_INTR_ERROR) { diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index ebf7d3cda3677..62bea4ffdc25a 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -4421,6 +4421,8 @@ lpfc_sli_brdrestart_s4(struct lpfc_hba *phba) hba_aer_enabled = phba->hba_flag & HBA_AER_ENABLED;
rc = lpfc_sli4_brdreset(phba); + if (rc) + return rc;
spin_lock_irq(&phba->hbalock); phba->pport->stopped = 0;
From: James Smart jsmart2021@gmail.com
[ Upstream commit 7c4042a4d0b7532cfbc90478fd3084b2dab5849e ]
When dif and first burst is used in a write command wqe, the driver was not properly setting fields in the io command request. This resulted in no dif bytes being sent and invalid xfer_rdy's, resulting in the io being aborted by the hardware.
Correct the wqe initializaton when both dif and first burst are used.
Signed-off-by: Dick Kennedy dick.kennedy@broadcom.com Signed-off-by: James Smart jsmart2021@gmail.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/lpfc/lpfc_scsi.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 07cb671bb8550..2eba0c39ac1c4 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -2714,6 +2714,7 @@ lpfc_bg_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, int datasegcnt, protsegcnt, datadir = scsi_cmnd->sc_data_direction; int prot_group_type = 0; int fcpdl; + struct lpfc_vport *vport = phba->pport;
/* * Start the lpfc command prep by bumping the bpl beyond fcp_cmnd @@ -2819,6 +2820,14 @@ lpfc_bg_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, */ iocb_cmd->un.fcpi.fcpi_parm = fcpdl;
+ /* + * For First burst, we may need to adjust the initial transfer + * length for DIF + */ + if (iocb_cmd->un.fcpi.fcpi_XRdy && + (fcpdl < vport->cfg_first_burst_size)) + iocb_cmd->un.fcpi.fcpi_XRdy = fcpdl; + return 0; err: if (lpfc_cmd->seg_cnt) @@ -3371,6 +3380,7 @@ lpfc_bg_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, int datasegcnt, protsegcnt, datadir = scsi_cmnd->sc_data_direction; int prot_group_type = 0; int fcpdl; + struct lpfc_vport *vport = phba->pport;
/* * Start the lpfc command prep by bumping the sgl beyond fcp_cmnd @@ -3486,6 +3496,14 @@ lpfc_bg_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, */ iocb_cmd->un.fcpi.fcpi_parm = fcpdl;
+ /* + * For First burst, we may need to adjust the initial transfer + * length for DIF + */ + if (iocb_cmd->un.fcpi.fcpi_XRdy && + (fcpdl < vport->cfg_first_burst_size)) + iocb_cmd->un.fcpi.fcpi_XRdy = fcpdl; + /* * If the OAS driver feature is enabled and the lun is enabled for * OAS, set the oas iocb related flags.
From: Linus Walleij linus.walleij@linaro.org
[ Upstream commit d88b11ef91b15d0af9c0676cbf4f441a0dff0c56 ]
This sets the partition information on the SQ201 to be read out from the RedBoot partition table, removes the static partition table and sets our boot options to mount root from /dev/mtdblock2 where the squashfs+JFFS2 resides.
Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/gemini-sq201.dts | 37 ++++-------------------------- 1 file changed, 5 insertions(+), 32 deletions(-)
diff --git a/arch/arm/boot/dts/gemini-sq201.dts b/arch/arm/boot/dts/gemini-sq201.dts index 63c02ca9513c4..e9e2f6ff0c583 100644 --- a/arch/arm/boot/dts/gemini-sq201.dts +++ b/arch/arm/boot/dts/gemini-sq201.dts @@ -20,7 +20,7 @@ };
chosen { - bootargs = "console=ttyS0,115200n8"; + bootargs = "console=ttyS0,115200n8 root=/dev/mtdblock2 rw rootfstype=squashfs,jffs2 rootwait"; stdout-path = &uart0; };
@@ -71,37 +71,10 @@ /* 16MB of flash */ reg = <0x30000000 0x01000000>;
- partition@0 { - label = "RedBoot"; - reg = <0x00000000 0x00120000>; - read-only; - }; - partition@120000 { - label = "Kernel"; - reg = <0x00120000 0x00200000>; - }; - partition@320000 { - label = "Ramdisk"; - reg = <0x00320000 0x00600000>; - }; - partition@920000 { - label = "Application"; - reg = <0x00920000 0x00600000>; - }; - partition@f20000 { - label = "VCTL"; - reg = <0x00f20000 0x00020000>; - read-only; - }; - partition@f40000 { - label = "CurConf"; - reg = <0x00f40000 0x000a0000>; - read-only; - }; - partition@fe0000 { - label = "FIS directory"; - reg = <0x00fe0000 0x00020000>; - read-only; + partitions { + compatible = "redboot-fis"; + /* Eraseblock at 0xfe0000 */ + fis-index-block = <0x1fc>; }; };
From: Uwe Kleine-König u.kleine-koenig@pengutronix.de
[ Upstream commit 7c41ea57beb2aee96fa63091a457b1a2826f3c42 ]
If debugging on i.MX is enabled DEBUG_IMX_UART_PORT defines which UART is used for the debug output. If however debugging is off don't only hide the then unused config item but drop it completely by using a dependency instead of a conditional prompt.
This fixes DEBUG_IMX_UART_PORT being present in the kernel config even if DEBUG_LL is disabled.
Signed-off-by: Uwe Kleine-König u.kleine-koenig@pengutronix.de Signed-off-by: Shawn Guo shawnguo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/Kconfig.debug | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 954ba8b810521..fd4b679945d3a 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -1376,21 +1376,21 @@ config DEBUG_OMAP2PLUS_UART depends on ARCH_OMAP2PLUS
config DEBUG_IMX_UART_PORT - int "i.MX Debug UART Port Selection" if DEBUG_IMX1_UART || \ - DEBUG_IMX25_UART || \ - DEBUG_IMX21_IMX27_UART || \ - DEBUG_IMX31_UART || \ - DEBUG_IMX35_UART || \ - DEBUG_IMX50_UART || \ - DEBUG_IMX51_UART || \ - DEBUG_IMX53_UART || \ - DEBUG_IMX6Q_UART || \ - DEBUG_IMX6SL_UART || \ - DEBUG_IMX6SX_UART || \ - DEBUG_IMX6UL_UART || \ - DEBUG_IMX7D_UART + int "i.MX Debug UART Port Selection" + depends on DEBUG_IMX1_UART || \ + DEBUG_IMX25_UART || \ + DEBUG_IMX21_IMX27_UART || \ + DEBUG_IMX31_UART || \ + DEBUG_IMX35_UART || \ + DEBUG_IMX50_UART || \ + DEBUG_IMX51_UART || \ + DEBUG_IMX53_UART || \ + DEBUG_IMX6Q_UART || \ + DEBUG_IMX6SL_UART || \ + DEBUG_IMX6SX_UART || \ + DEBUG_IMX6UL_UART || \ + DEBUG_IMX7D_UART default 1 - depends on ARCH_MXC help Choose UART port on which kernel low-level debug messages should be output.
From: Fabio Estevam festevam@gmail.com
[ Upstream commit 998a84c27a7f3f9133d32af64e19c05cec161a1a ]
imx53-voipac-dmm-668 has two memory nodes, but the correct representation would be to use a single one with two reg entries - one for each RAM chip select, so fix it accordingly.
Reported-by: Marco Franchi marco.franchi@nxp.com Signed-off-by: Fabio Estevam festevam@gmail.com Signed-off-by: Marco Franchi marco.franchi@nxp.com Signed-off-by: Shawn Guo shawnguo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/imx53-voipac-dmm-668.dtsi | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/arch/arm/boot/dts/imx53-voipac-dmm-668.dtsi b/arch/arm/boot/dts/imx53-voipac-dmm-668.dtsi index df8dafe2564dd..2297ed90ee895 100644 --- a/arch/arm/boot/dts/imx53-voipac-dmm-668.dtsi +++ b/arch/arm/boot/dts/imx53-voipac-dmm-668.dtsi @@ -17,12 +17,8 @@
memory@70000000 { device_type = "memory"; - reg = <0x70000000 0x20000000>; - }; - - memory@b0000000 { - device_type = "memory"; - reg = <0xb0000000 0x20000000>; + reg = <0x70000000 0x20000000>, + <0xb0000000 0x20000000>; };
regulators {
From: Helge Deller deller@gmx.de
[ Upstream commit 785145171d17af2554128becd6a7c8f89e101141 ]
We want the hpa addresses printed in the serio modules, not some virtual ioremap()ed address, e.g.:
serio: gsc-ps2-keyboard port at 0xf0108000 irq 22 @ 2:0:11 serio: gsc-ps2-mouse port at 0xf0108100 irq 22 @ 2:0:12
Signed-off-by: Helge Deller deller@gmx.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/input/serio/gscps2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c index aa9f29b875dea..d84e3b70215ad 100644 --- a/drivers/input/serio/gscps2.c +++ b/drivers/input/serio/gscps2.c @@ -382,9 +382,9 @@ static int __init gscps2_probe(struct parisc_device *dev) goto fail; #endif
- printk(KERN_INFO "serio: %s port at 0x%p irq %d @ %s\n", + pr_info("serio: %s port at 0x%08lx irq %d @ %s\n", ps2port->port->name, - ps2port->addr, + hpa, ps2port->padev->irq, ps2port->port->phys);
From: Helge Deller deller@gmx.de
[ Upstream commit c4bff35ca1bfba886da6223c9fed76a2b1382b8e ]
Show the hpa address of the HP SDC instead of a hashed value, e.g.: HP SDC: HP SDC at 0xf0201000, IRQ 23 (NMI IRQ 24)
Signed-off-by: Helge Deller deller@gmx.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/input/serio/hp_sdc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/input/serio/hp_sdc.c b/drivers/input/serio/hp_sdc.c index 8eef6849d0660..5585823ced19d 100644 --- a/drivers/input/serio/hp_sdc.c +++ b/drivers/input/serio/hp_sdc.c @@ -887,8 +887,8 @@ static int __init hp_sdc_init(void) "HP SDC NMI", &hp_sdc)) goto err2;
- printk(KERN_INFO PREFIX "HP SDC at 0x%p, IRQ %d (NMI IRQ %d)\n", - (void *)hp_sdc.base_io, hp_sdc.irq, hp_sdc.nmi); + pr_info(PREFIX "HP SDC at 0x%08lx, IRQ %d (NMI IRQ %d)\n", + hp_sdc.base_io, hp_sdc.irq, hp_sdc.nmi);
hp_sdc_status_in8(); hp_sdc_data_in8();
From: Steve Capper steve.capper@arm.com
[ Upstream commit a96a33b1ca57dbea4285893dedf290aeb8eb090b ]
For cases where there is a mismatch in ARMv8.2-LVA support between CPUs we have to be careful in allowing secondary CPUs to boot if 52-bit virtual addresses have already been enabled on the boot CPU.
This patch adds code to the secondary startup path. If the boot CPU has enabled 52-bit VAs then ID_AA64MMFR2_EL1 is checked to see if the secondary can also enable 52-bit support. If not, the secondary is prevented from booting and an error message is displayed indicating why.
Technically this patch could be implemented using the cpufeature code when considering 52-bit userspace support. However, we employ low level checks here as the cpufeature code won't be able to run if we have mismatched 52-bit kernel va support.
Signed-off-by: Steve Capper steve.capper@arm.com Signed-off-by: Will Deacon will.deacon@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/kernel/head.S | 26 ++++++++++++++++++++++++++ arch/arm64/kernel/smp.c | 5 +++++ 2 files changed, 31 insertions(+)
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index 92cc7b51f1002..9c00fd2acc2a4 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S @@ -594,6 +594,7 @@ secondary_startup: /* * Common entry point for secondary CPUs. */ + bl __cpu_secondary_check52bitva bl __cpu_setup // initialise processor bl __enable_mmu ldr x8, =__secondary_switched @@ -668,6 +669,31 @@ ENTRY(__enable_mmu) ret ENDPROC(__enable_mmu)
+ENTRY(__cpu_secondary_check52bitva) +#ifdef CONFIG_ARM64_52BIT_VA + ldr_l x0, vabits_user + cmp x0, #52 + b.ne 2f + + mrs_s x0, SYS_ID_AA64MMFR2_EL1 + and x0, x0, #(0xf << ID_AA64MMFR2_LVA_SHIFT) + cbnz x0, 2f + + adr_l x0, va52mismatch + mov w1, #1 + strb w1, [x0] + dmb sy + dc ivac, x0 // Invalidate potentially stale cache line + + update_early_cpu_boot_status CPU_STUCK_IN_KERNEL, x0, x1 +1: wfe + wfi + b 1b + +#endif +2: ret +ENDPROC(__cpu_secondary_check52bitva) + __no_granule_support: /* Indicate that this CPU can't boot and is stuck in the kernel */ update_early_cpu_boot_status CPU_STUCK_IN_KERNEL, x1, x2 diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index a683cd4995157..0881dfab10f8f 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -106,6 +106,7 @@ static int boot_secondary(unsigned int cpu, struct task_struct *idle) }
static DECLARE_COMPLETION(cpu_running); +bool va52mismatch __ro_after_init;
int __cpu_up(unsigned int cpu, struct task_struct *idle) { @@ -135,6 +136,10 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
if (!cpu_online(cpu)) { pr_crit("CPU%u: failed to come online\n", cpu); + + if (IS_ENABLED(CONFIG_ARM64_52BIT_VA) && va52mismatch) + pr_crit("CPU%u: does not support 52-bit VAs\n", cpu); + ret = -EIO; } } else {
From: Suzuki K Poulose Suzuki.Poulose@arm.com
[ Upstream commit f357b3a7e17af7736d67d8267edc1ed3d1dd9391 ]
The __cpu_up() routine ignores the errors reported by the firmware for a CPU bringup operation and looks for the error status set by the booting CPU. If the CPU never entered the kernel, we could end up in assuming stale error status, which otherwise would have been set/cleared appropriately by the booting CPU.
Reported-by: Steve Capper steve.capper@arm.com Cc: Will Deacon will.deacon@arm.com Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com Signed-off-by: Will Deacon will.deacon@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/kernel/smp.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index 0881dfab10f8f..909bf3926fd23 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -144,6 +144,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle) } } else { pr_err("CPU%u: failed to boot: %d\n", cpu, ret); + return ret; }
secondary_data.task = NULL;
From: Aaro Koskinen aaro.koskinen@iki.fi
[ Upstream commit c7b7b5cbd0c859b1546a5a3455d457708bdadf4c ]
Currently we do USB configuration only if the host mode (CONFIG_USB) is enabled. But it should be done also in the case of device-only setups, so change the condition to CONFIG_USB_SUPPORT. This allows to use omap_udc on Palm Tungsten E.
Signed-off-by: Aaro Koskinen aaro.koskinen@iki.fi Signed-off-by: Tony Lindgren tony@atomide.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/mach-omap1/Makefile | 2 +- arch/arm/mach-omap1/include/mach/usb.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile index e8ccf51c6f292..ec0235899de20 100644 --- a/arch/arm/mach-omap1/Makefile +++ b/arch/arm/mach-omap1/Makefile @@ -25,7 +25,7 @@ obj-y += $(i2c-omap-m) $(i2c-omap-y)
led-y := leds.o
-usb-fs-$(CONFIG_USB) := usb.o +usb-fs-$(CONFIG_USB_SUPPORT) := usb.o obj-y += $(usb-fs-m) $(usb-fs-y)
# Specific board support diff --git a/arch/arm/mach-omap1/include/mach/usb.h b/arch/arm/mach-omap1/include/mach/usb.h index 77867778d4ec7..5429d86c7190d 100644 --- a/arch/arm/mach-omap1/include/mach/usb.h +++ b/arch/arm/mach-omap1/include/mach/usb.h @@ -11,7 +11,7 @@
#include <linux/platform_data/usb-omap1.h>
-#if IS_ENABLED(CONFIG_USB) +#if IS_ENABLED(CONFIG_USB_SUPPORT) void omap1_usb_init(struct omap_usb_config *pdata); #else static inline void omap1_usb_init(struct omap_usb_config *pdata)
From: Gal Pressman galpress@amazon.com
[ Upstream commit a276a4d93bf1580d737f38d1810e5f4b166f3edd ]
Create address handle callback should not sleep, use GFP_ATOMIC instead of GFP_KERNEL for memory allocation.
Fixes: 29c8d9eba550 ("IB: Add vmw_pvrdma driver") Cc: Adit Ranadive aditr@vmware.com Signed-off-by: Gal Pressman galpress@amazon.com Reviewed-by: Yuval Shaia yuval.shaia@oracle.com Signed-off-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c index aa533f08e0171..5c7aa6ff15382 100644 --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c @@ -550,7 +550,7 @@ struct ib_ah *pvrdma_create_ah(struct ib_pd *pd, struct rdma_ah_attr *ah_attr, if (!atomic_add_unless(&dev->num_ahs, 1, dev->dsr->caps.max_ah)) return ERR_PTR(-ENOMEM);
- ah = kzalloc(sizeof(*ah), GFP_KERNEL); + ah = kzalloc(sizeof(*ah), GFP_ATOMIC); if (!ah) { atomic_dec(&dev->num_ahs); return ERR_PTR(-ENOMEM);
From: Thomas Meyer thomas@m3y3r.de
[ Upstream commit 14d338a857f05f894ba3badd9e6d3039c68b8180 ]
NULL check before some freeing functions is not needed.
Signed-off-by: Thomas Meyer thomas@m3y3r.de Reviewed-by: Kevin Hilman khilman@baylibre.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/power/avs/smartreflex.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/power/avs/smartreflex.c b/drivers/power/avs/smartreflex.c index 974fd684bab2c..4b6fddc183948 100644 --- a/drivers/power/avs/smartreflex.c +++ b/drivers/power/avs/smartreflex.c @@ -994,8 +994,7 @@ static int omap_sr_remove(struct platform_device *pdev)
if (sr_info->autocomp_active) sr_stop_vddautocomp(sr_info); - if (sr_info->dbg_dir) - debugfs_remove_recursive(sr_info->dbg_dir); + debugfs_remove_recursive(sr_info->dbg_dir);
pm_runtime_disable(&pdev->dev); list_del(&sr_info->node);
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit 4aa64677330beeeed721b4b122884dabad845d66 ]
WARNING: vmlinux.o(.text+0x13250): Section mismatch in reference from the function acs5k_i2c_init() to the (unknown reference) .init.data:(unknown) The function acs5k_i2c_init() references the (unknown reference) __initdata (unknown). This is often because acs5k_i2c_init lacks a __initdata annotation or the annotation of (unknown) is wrong.
Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Olof Johansson olof@lixom.net Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/mach-ks8695/board-acs5k.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/mach-ks8695/board-acs5k.c b/arch/arm/mach-ks8695/board-acs5k.c index e4d709c8ed32f..76d3083f1f634 100644 --- a/arch/arm/mach-ks8695/board-acs5k.c +++ b/arch/arm/mach-ks8695/board-acs5k.c @@ -92,7 +92,7 @@ static struct i2c_board_info acs5k_i2c_devs[] __initdata = { }, };
-static void acs5k_i2c_init(void) +static void __init acs5k_i2c_init(void) { /* The gpio interface */ platform_device_register(&acs5k_i2c_device);
From: Hans de Goede hdegoede@redhat.com
[ Upstream commit 1a2fa02f7489dc4d746f2a15fb77b3ce1affade8 ]
Ignore acpi_device_fix_up_power() return value. If we return an error we end up with acpi_default_enumeration() still creating a platform- device for the device and we end up with the device still being used but without the special LPSS related handling which is not useful.
Specicifically ignoring the error fixes the touchscreen no longer working after a suspend/resume on a Prowise PT301 tablet.
This tablet has a broken _PS0 method on the touchscreen's I2C controller, causing acpi_device_fix_up_power() to fail, causing fallback to standard platform-dev handling and specifically causing acpi_lpss_save/restore_ctx to not run.
The I2C controllers _PS0 method does actually turn on the device, but then does some more nonsense which fails when run during early boot trying to use I2C opregion handling on another not-yet registered I2C controller.
Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/acpi/acpi_lpss.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c index 1ab8d7223b252..84b1d30f699cf 100644 --- a/drivers/acpi/acpi_lpss.c +++ b/drivers/acpi/acpi_lpss.c @@ -518,12 +518,7 @@ static int acpi_lpss_create_device(struct acpi_device *adev, * have _PS0 and _PS3 without _PSC (and no power resources), so * acpi_bus_init_power() will assume that the BIOS has put them into D0. */ - ret = acpi_device_fix_up_power(adev); - if (ret) { - /* Skip the device, but continue the namespace scan. */ - ret = 0; - goto err_out; - } + acpi_device_fix_up_power(adev);
adev->driver_data = pdata; pdev = acpi_create_platform_device(adev, dev_desc->properties);
From: James Smart jsmart2021@gmail.com
[ Upstream commit 719162bd5bb968203397b9b1d0dd30a9797bbd09 ]
Addition of support for if_type=6 missed several checks for interface type, resulting in the failure of several key management features such as firmware dump and loopback testing.
Correct the checks on the if_type so that both SLI4 IF_TYPE's 2 and 6 are supported.
Signed-off-by: Dick Kennedy dick.kennedy@broadcom.com Signed-off-by: James Smart jsmart2021@gmail.com Reviewed-by: Ewan D. Milne emilne@redhat.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/lpfc/lpfc_attr.c | 4 ++-- drivers/scsi/lpfc/lpfc_bsg.c | 6 +++--- drivers/scsi/lpfc/lpfc_els.c | 2 +- drivers/scsi/lpfc/lpfc_hbadisc.c | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 3da242201cb45..82ce5d1930189 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -1178,7 +1178,7 @@ lpfc_sli4_pdev_reg_request(struct lpfc_hba *phba, uint32_t opcode) return -EACCES;
if ((phba->sli_rev < LPFC_SLI_REV4) || - (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) != + (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) < LPFC_SLI_INTF_IF_TYPE_2)) return -EPERM;
@@ -4056,7 +4056,7 @@ lpfc_link_speed_store(struct device *dev, struct device_attribute *attr, uint32_t prev_val, if_type;
if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf); - if (if_type == LPFC_SLI_INTF_IF_TYPE_2 && + if (if_type >= LPFC_SLI_INTF_IF_TYPE_2 && phba->hba_flag & HBA_FORCED_LINK_SPEED) return -EPERM;
diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c index d89816222b230..6dde21dc82a3c 100644 --- a/drivers/scsi/lpfc/lpfc_bsg.c +++ b/drivers/scsi/lpfc/lpfc_bsg.c @@ -2221,7 +2221,7 @@ lpfc_bsg_diag_loopback_mode(struct bsg_job *job)
if (phba->sli_rev < LPFC_SLI_REV4) rc = lpfc_sli3_bsg_diag_loopback_mode(phba, job); - else if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) == + else if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) >= LPFC_SLI_INTF_IF_TYPE_2) rc = lpfc_sli4_bsg_diag_loopback_mode(phba, job); else @@ -2261,7 +2261,7 @@ lpfc_sli4_bsg_diag_mode_end(struct bsg_job *job)
if (phba->sli_rev < LPFC_SLI_REV4) return -ENODEV; - if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) != + if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) < LPFC_SLI_INTF_IF_TYPE_2) return -ENODEV;
@@ -2353,7 +2353,7 @@ lpfc_sli4_bsg_link_diag_test(struct bsg_job *job) rc = -ENODEV; goto job_error; } - if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) != + if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) < LPFC_SLI_INTF_IF_TYPE_2) { rc = -ENODEV; goto job_error; diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index a31f87eb1e621..c851fd14ff3e9 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -5550,7 +5550,7 @@ lpfc_els_rcv_rdp(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, struct ls_rjt stat;
if (phba->sli_rev < LPFC_SLI_REV4 || - bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) != + bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) < LPFC_SLI_INTF_IF_TYPE_2) { rjt_err = LSRJT_UNABLE_TPC; rjt_expl = LSEXP_REQ_UNSUPPORTED; diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index d850077c5e226..3f88f3d796227 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -4769,7 +4769,7 @@ lpfc_unreg_rpi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) if (phba->sli_rev == LPFC_SLI_REV4 && (!(vport->load_flag & FC_UNLOADING)) && (bf_get(lpfc_sli_intf_if_type, - &phba->sli4_hba.sli_intf) == + &phba->sli4_hba.sli_intf) >= LPFC_SLI_INTF_IF_TYPE_2) && (kref_read(&ndlp->kref) > 0)) { mbox->context1 = lpfc_nlp_get(ndlp);
From: Eric Biggers ebiggers@google.com
[ Upstream commit 0ac6b8fb23c724b015d9ca70a89126e8d1563166 ]
CRYPTO_MSG_GETALG in NLM_F_DUMP mode sometimes doesn't return all registered crypto algorithms, because it doesn't support incremental dumps. crypto_dump_report() only permits itself to be called once, yet the netlink subsystem allocates at most ~64 KiB for the skb being dumped to. Thus only the first recvmsg() returns data, and it may only include a subset of the crypto algorithms even if the user buffer passed to recvmsg() is large enough to hold all of them.
Fix this by using one of the arguments in the netlink_callback structure to keep track of the current position in the algorithm list. Then userspace can do multiple recvmsg() on the socket after sending the dump request. This is the way netlink dumps work elsewhere in the kernel; it's unclear why this was different (probably just an oversight).
Also fix an integer overflow when calculating the dump buffer size hint.
Fixes: a38f7907b926 ("crypto: Add userspace configuration API") Signed-off-by: Eric Biggers ebiggers@google.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- crypto/crypto_user.c | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-)
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c index 2b8fb8f1391e0..5e457a7dd1c92 100644 --- a/crypto/crypto_user.c +++ b/crypto/crypto_user.c @@ -296,30 +296,33 @@ drop_alg:
static int crypto_dump_report(struct sk_buff *skb, struct netlink_callback *cb) { - struct crypto_alg *alg; + const size_t start_pos = cb->args[0]; + size_t pos = 0; struct crypto_dump_info info; - int err; - - if (cb->args[0]) - goto out; - - cb->args[0] = 1; + struct crypto_alg *alg; + int res;
info.in_skb = cb->skb; info.out_skb = skb; info.nlmsg_seq = cb->nlh->nlmsg_seq; info.nlmsg_flags = NLM_F_MULTI;
+ down_read(&crypto_alg_sem); list_for_each_entry(alg, &crypto_alg_list, cra_list) { - err = crypto_report_alg(alg, &info); - if (err) - goto out_err; + if (pos >= start_pos) { + res = crypto_report_alg(alg, &info); + if (res == -EMSGSIZE) + break; + if (res) + goto out; + } + pos++; } - + cb->args[0] = pos; + res = skb->len; out: - return skb->len; -out_err: - return err; + up_read(&crypto_alg_sem); + return res; }
static int crypto_dump_report_done(struct netlink_callback *cb) @@ -503,7 +506,7 @@ static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, if ((type == (CRYPTO_MSG_GETALG - CRYPTO_MSG_BASE) && (nlh->nlmsg_flags & NLM_F_DUMP))) { struct crypto_alg *alg; - u16 dump_alloc = 0; + unsigned long dump_alloc = 0;
if (link->dump == NULL) return -EINVAL; @@ -511,16 +514,16 @@ static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, down_read(&crypto_alg_sem); list_for_each_entry(alg, &crypto_alg_list, cra_list) dump_alloc += CRYPTO_REPORT_MAXSIZE; + up_read(&crypto_alg_sem);
{ struct netlink_dump_control c = { .dump = link->dump, .done = link->done, - .min_dump_alloc = dump_alloc, + .min_dump_alloc = min(dump_alloc, 65535UL), }; err = netlink_dump_start(crypto_nlsk, skb, nlh, &c); } - up_read(&crypto_alg_sem);
return err; }
From: Pan Bian bianpan2016@163.com
[ Upstream commit 1dcd9429212b98bea87fc6ec92fb50bf5953eb47 ]
There are two defects: (1) passing a NULL bss to mwifiex_save_hidden_ssid_channels will result in NULL dereference, (2) using bss after dropping the reference to it via cfg80211_put_bss. To fix them, the patch moves the buggy code to the branch that bss is not NULL and puts it before cfg80211_put_bss.
Signed-off-by: Pan Bian bianpan2016@163.com Signed-off-by: Kalle Valo kvalo@codeaurora.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/marvell/mwifiex/scan.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/drivers/net/wireless/marvell/mwifiex/scan.c b/drivers/net/wireless/marvell/mwifiex/scan.c index 67c3342210777..c013c94fbf15f 100644 --- a/drivers/net/wireless/marvell/mwifiex/scan.c +++ b/drivers/net/wireless/marvell/mwifiex/scan.c @@ -1901,15 +1901,17 @@ mwifiex_parse_single_response_buf(struct mwifiex_private *priv, u8 **bss_info, ETH_ALEN)) mwifiex_update_curr_bss_params(priv, bss); - cfg80211_put_bss(priv->wdev.wiphy, bss); - }
- if ((chan->flags & IEEE80211_CHAN_RADAR) || - (chan->flags & IEEE80211_CHAN_NO_IR)) { - mwifiex_dbg(adapter, INFO, - "radar or passive channel %d\n", - channel); - mwifiex_save_hidden_ssid_channels(priv, bss); + if ((chan->flags & IEEE80211_CHAN_RADAR) || + (chan->flags & IEEE80211_CHAN_NO_IR)) { + mwifiex_dbg(adapter, INFO, + "radar or passive channel %d\n", + channel); + mwifiex_save_hidden_ssid_channels(priv, + bss); + } + + cfg80211_put_bss(priv->wdev.wiphy, bss); } } } else {
From: Brian Norris briannorris@chromium.org
[ Upstream commit 4cb777c64e030778c569f605398d7604d8aabc0f ]
Currently, snippets of this file look like:
rx rates (in Mbps): 0=1M 1=2M2=5.5M 3=11M 4=6M 5=9M 6=12M 7=18M 8=24M 9=36M 10=48M 11=54M12-27=MCS0-15(BW20) 28-43=MCS0-15(BW40) 44-53=MCS0-9(VHT:BW20)54-63=MCS0-9(VHT:BW40)64-73=MCS0-9(VHT:BW80) ... noise_flr[--96dBm] = 22 noise_flr[--95dBm] = 149 noise_flr[--94dBm] = 9 noise_flr[--93dBm] = 2
We're missing some spaces, and we're adding a minus sign ('-') on values that are already negative signed integers.
Signed-off-by: Brian Norris briannorris@chromium.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/marvell/mwifiex/debugfs.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/drivers/net/wireless/marvell/mwifiex/debugfs.c b/drivers/net/wireless/marvell/mwifiex/debugfs.c index 6f4239be609d0..49ca84ef1a992 100644 --- a/drivers/net/wireless/marvell/mwifiex/debugfs.c +++ b/drivers/net/wireless/marvell/mwifiex/debugfs.c @@ -296,15 +296,13 @@ mwifiex_histogram_read(struct file *file, char __user *ubuf, "total samples = %d\n", atomic_read(&phist_data->num_samples));
- p += sprintf(p, "rx rates (in Mbps): 0=1M 1=2M"); - p += sprintf(p, "2=5.5M 3=11M 4=6M 5=9M 6=12M\n"); - p += sprintf(p, "7=18M 8=24M 9=36M 10=48M 11=54M"); - p += sprintf(p, "12-27=MCS0-15(BW20) 28-43=MCS0-15(BW40)\n"); + p += sprintf(p, + "rx rates (in Mbps): 0=1M 1=2M 2=5.5M 3=11M 4=6M 5=9M 6=12M\n" + "7=18M 8=24M 9=36M 10=48M 11=54M 12-27=MCS0-15(BW20) 28-43=MCS0-15(BW40)\n");
if (ISSUPP_11ACENABLED(priv->adapter->fw_cap_info)) { - p += sprintf(p, "44-53=MCS0-9(VHT:BW20)"); - p += sprintf(p, "54-63=MCS0-9(VHT:BW40)"); - p += sprintf(p, "64-73=MCS0-9(VHT:BW80)\n\n"); + p += sprintf(p, + "44-53=MCS0-9(VHT:BW20) 54-63=MCS0-9(VHT:BW40) 64-73=MCS0-9(VHT:BW80)\n\n"); } else { p += sprintf(p, "\n"); } @@ -333,7 +331,7 @@ mwifiex_histogram_read(struct file *file, char __user *ubuf, for (i = 0; i < MWIFIEX_MAX_NOISE_FLR; i++) { value = atomic_read(&phist_data->noise_flr[i]); if (value) - p += sprintf(p, "noise_flr[-%02ddBm] = %d\n", + p += sprintf(p, "noise_flr[%02ddBm] = %d\n", (int)(i-128), value); } for (i = 0; i < MWIFIEX_MAX_SIG_STRENGTH; i++) {
From: Pan Bian bianpan2016@163.com
[ Upstream commit afbb1947db94eacc5a13302eee88a9772fb78935 ]
entry is released via usb_put_urb just after calling usb_submit_urb. However, entry is used if the submission fails, resulting in a use after free bug. The patch fixes this.
Signed-off-by: Pan Bian bianpan2016@163.com ACKed-by: Larry Finger Larry.Finger@lwfinger.net Signed-off-by: Kalle Valo kvalo@codeaurora.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c b/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c index 9a1d15b3ce453..518caaaf8a987 100644 --- a/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c +++ b/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c @@ -444,12 +444,13 @@ static int rtl8187_init_urbs(struct ieee80211_hw *dev) skb_queue_tail(&priv->rx_queue, skb); usb_anchor_urb(entry, &priv->anchored); ret = usb_submit_urb(entry, GFP_KERNEL); - usb_put_urb(entry); if (ret) { skb_unlink(skb, &priv->rx_queue); usb_unanchor_urb(entry); + usb_put_urb(entry); goto err; } + usb_put_urb(entry); } return ret;
From: Darrick J. Wong darrick.wong@oracle.com
[ Upstream commit 64bafd2f1e484e27071e7584642005d56516cb77 ]
Since mkfs always formats the filesystem with the realtime bitmap and summary inodes immediately after the root directory, we should expect that both of them are present and loadable, even if there isn't a realtime volume attached. There's no reason to skip this if rbmino == NULLFSINO; in fact, this causes an immediate crash if the there /is/ a realtime volume and someone writes to it.
Signed-off-by: Darrick J. Wong darrick.wong@oracle.com Reviewed-by: Bill O'Donnell billodo@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/xfs/xfs_rtalloc.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 488719d43ca82..cdcb7235e41ae 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -1214,13 +1214,11 @@ xfs_rtmount_inodes( xfs_sb_t *sbp;
sbp = &mp->m_sb; - if (sbp->sb_rbmino == NULLFSINO) - return 0; error = xfs_iget(mp, NULL, sbp->sb_rbmino, 0, 0, &mp->m_rbmip); if (error) return error; ASSERT(mp->m_rbmip != NULL); - ASSERT(sbp->sb_rsumino != NULLFSINO); + error = xfs_iget(mp, NULL, sbp->sb_rsumino, 0, 0, &mp->m_rsumip); if (error) { IRELE(mp->m_rbmip);
From: Pan Bian bianpan2016@163.com
[ Upstream commit b95f83ab762dd6211351b9140f99f43644076ca8 ]
The MTD device reference is dropped via put_mtd_device, however its field ->index is read and passed to ubi_msg. To fix this, the patch moves the reference dropping after calling ubi_msg.
Signed-off-by: Pan Bian bianpan2016@163.com Reviewed-by: Boris Brezillon boris.brezillon@bootlin.com Signed-off-by: Richard Weinberger richard@nod.at Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mtd/ubi/build.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 6445c693d9359..0104d9537329f 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -1092,10 +1092,10 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway) ubi_wl_close(ubi); ubi_free_internal_volumes(ubi); vfree(ubi->vtbl); - put_mtd_device(ubi->mtd); vfree(ubi->peb_buf); vfree(ubi->fm_buf); ubi_msg(ubi, "mtd%d is detached", ubi->mtd->index); + put_mtd_device(ubi->mtd); put_device(&ubi->dev); return 0; }
From: Pan Bian bianpan2016@163.com
[ Upstream commit e542087701f09418702673631a908429feb3eae0 ]
The UBI device reference is dropped but then the device is used as a parameter of ubi_err. The bug is introduced in changing ubi_err's behavior. The old ubi_err does not require a UBI device as its first parameter, but the new one does.
Fixes: 32608703310 ("UBI: Extend UBI layer debug/messaging capabilities") Signed-off-by: Pan Bian bianpan2016@163.com Reviewed-by: Boris Brezillon boris.brezillon@bootlin.com Signed-off-by: Richard Weinberger richard@nod.at Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mtd/ubi/kapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mtd/ubi/kapi.c b/drivers/mtd/ubi/kapi.c index d4b2e87444986..c2cf6bd3c162a 100644 --- a/drivers/mtd/ubi/kapi.c +++ b/drivers/mtd/ubi/kapi.c @@ -227,9 +227,9 @@ out_unlock: out_free: kfree(desc); out_put_ubi: - ubi_put_device(ubi); ubi_err(ubi, "cannot open device %d, volume %d, error %d", ubi_num, vol_id, err); + ubi_put_device(ubi); return ERR_PTR(err); } EXPORT_SYMBOL_GPL(ubi_open_volume);
From: Masahiro Yamada yamada.masahiro@socionext.com
[ Upstream commit bafcc61d998c1ca18f556d92a0e95335ac68c7da ]
"make ARCH=microblaze help" mentions simpleImage.<dt>.unstrip, but it is not a real Make target. It does not work because Makefile assumes "system.unstrip" is the name of DT.
$ make ARCH=microblaze CROSS_COMPILE=microblaze-linux- simpleImage.system.unstrip [ snip ] make[1]: *** No rule to make target 'arch/microblaze/boot/dts/system.unstrip.dtb', needed by 'arch/microblaze/boot/dts/system.dtb'. Stop. make: *** [Makefile;1060: arch/microblaze/boot/dts] Error 2 make: *** Waiting for unfinished jobs....
simpleImage.<dt> works like a phony target that generates multiple images. Reflect the real behavior. I removed the DT directory path information because it is already explained a few lines below.
While I am here, I deleted the redundant *_defconfig explanation.
The top-level Makefile caters to list available defconfig files:
mmu_defconfig - Build for mmu nommu_defconfig - Build for nommu
Signed-off-by: Masahiro Yamada yamada.masahiro@socionext.com Signed-off-by: Michal Simek michal.simek@xilinx.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/microblaze/Makefile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/arch/microblaze/Makefile b/arch/microblaze/Makefile index d269dd4b82795..188f07bba0959 100644 --- a/arch/microblaze/Makefile +++ b/arch/microblaze/Makefile @@ -91,11 +91,11 @@ define archhelp echo '* linux.bin - Create raw binary' echo ' linux.bin.gz - Create compressed raw binary' echo ' linux.bin.ub - Create U-Boot wrapped raw binary' - echo ' simpleImage.<dt> - ELF image with $(arch)/boot/dts/<dt>.dts linked in' - echo ' - stripped elf with fdt blob' - echo ' simpleImage.<dt>.unstrip - full ELF image with fdt blob' - echo ' *_defconfig - Select default config from arch/microblaze/configs' - echo '' + echo ' simpleImage.<dt> - Create the following images with <dt>.dtb linked in' + echo ' simpleImage.<dt> : raw image' + echo ' simpleImage.<dt>.ub : raw image with U-Boot header' + echo ' simpleImage.<dt>.unstrip: ELF (identical to vmlinux)' + echo ' simpleImage.<dt>.strip : stripped ELF' echo ' Targets with <dt> embed a device tree blob inside the image' echo ' These targets support board with firmware that does not' echo ' support passing a device tree directly. Replace <dt> with the'
From: Masahiro Yamada yamada.masahiro@socionext.com
[ Upstream commit 2e14f94cf4bc2f15ca5362e81ca3a987c79e3062 ]
To prepare for more fixes, move this to arch/microblaze/Makefile. Otherwise, the same "... is ready" would be printed multiple times.
Signed-off-by: Masahiro Yamada yamada.masahiro@socionext.com Signed-off-by: Michal Simek michal.simek@xilinx.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/microblaze/Makefile | 2 ++ arch/microblaze/boot/Makefile | 4 ---- 2 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/arch/microblaze/Makefile b/arch/microblaze/Makefile index 188f07bba0959..fe5e48184c3c2 100644 --- a/arch/microblaze/Makefile +++ b/arch/microblaze/Makefile @@ -83,9 +83,11 @@ archclean:
linux.bin linux.bin.gz linux.bin.ub: vmlinux $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ + @echo 'Kernel: $(boot)/$@ is ready' ' (#'`cat .version`')'
simpleImage.%: vmlinux $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ + @echo 'Kernel: $(boot)/$@ is ready' ' (#'`cat .version`')'
define archhelp echo '* linux.bin - Create raw binary' diff --git a/arch/microblaze/boot/Makefile b/arch/microblaze/boot/Makefile index 7c2f52d4a0e45..49dbd1063d717 100644 --- a/arch/microblaze/boot/Makefile +++ b/arch/microblaze/boot/Makefile @@ -9,15 +9,12 @@ OBJCOPYFLAGS := -R .note -R .comment -R .note.gnu.build-id -O binary
$(obj)/linux.bin: vmlinux FORCE $(call if_changed,objcopy) - @echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
$(obj)/linux.bin.ub: $(obj)/linux.bin FORCE $(call if_changed,uimage) - @echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
$(obj)/linux.bin.gz: $(obj)/linux.bin FORCE $(call if_changed,gzip) - @echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
quiet_cmd_cp = CP $< $@$2 cmd_cp = cat $< >$@$2 || (rm -f $@ && echo false) @@ -35,6 +32,5 @@ $(obj)/simpleImage.%: vmlinux FORCE $(call if_changed,objcopy) $(call if_changed,uimage) $(call if_changed,strip,.strip) - @echo 'Kernel: $(UIMAGE_OUT) is ready' ' (#'`cat .version`')'
clean-files += simpleImage.*.unstrip linux.bin.ub dts/*.dtb
From: Luca Coelho luciano.coelho@intel.com
[ Upstream commit 64866e5da1eabd0c52ff45029b245f5465920031 ]
This function is only half-used by mvm (i.e. only the nvm_version part matters, since the calibration version is irrelevant), so it's pointless to export it from iwlwifi. If mvm uses this function, it has the additional complexity of setting the calib version to a bogus value on all cfg structs.
To avoid this, move the function to dvm and make a simple comparison of the nvm_version in mvm instead.
Signed-off-by: Luca Coelho luciano.coelho@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/intel/iwlwifi/dvm/main.c | 17 +++++++++++++++++ .../wireless/intel/iwlwifi/iwl-eeprom-parse.c | 19 ------------------- .../wireless/intel/iwlwifi/iwl-eeprom-parse.h | 5 ++--- drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 4 +++- 4 files changed, 22 insertions(+), 23 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/main.c b/drivers/net/wireless/intel/iwlwifi/dvm/main.c index 2acd94da9efeb..051a2fea95724 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/main.c @@ -1229,6 +1229,23 @@ static int iwl_eeprom_init_hw_params(struct iwl_priv *priv) return 0; }
+static int iwl_nvm_check_version(struct iwl_nvm_data *data, + struct iwl_trans *trans) +{ + if (data->nvm_version >= trans->cfg->nvm_ver || + data->calib_version >= trans->cfg->nvm_calib_ver) { + IWL_DEBUG_INFO(trans, "device EEPROM VER=0x%x, CALIB=0x%x\n", + data->nvm_version, data->calib_version); + return 0; + } + + IWL_ERR(trans, + "Unsupported (too old) EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n", + data->nvm_version, trans->cfg->nvm_ver, + data->calib_version, trans->cfg->nvm_calib_ver); + return -EINVAL; +} + static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, const struct iwl_fw *fw, diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c index 3199d345b4274..92727f7e42db7 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c @@ -928,22 +928,3 @@ iwl_parse_eeprom_data(struct device *dev, const struct iwl_cfg *cfg, return NULL; } IWL_EXPORT_SYMBOL(iwl_parse_eeprom_data); - -/* helper functions */ -int iwl_nvm_check_version(struct iwl_nvm_data *data, - struct iwl_trans *trans) -{ - if (data->nvm_version >= trans->cfg->nvm_ver || - data->calib_version >= trans->cfg->nvm_calib_ver) { - IWL_DEBUG_INFO(trans, "device EEPROM VER=0x%x, CALIB=0x%x\n", - data->nvm_version, data->calib_version); - return 0; - } - - IWL_ERR(trans, - "Unsupported (too old) EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n", - data->nvm_version, trans->cfg->nvm_ver, - data->calib_version, trans->cfg->nvm_calib_ver); - return -EINVAL; -} -IWL_EXPORT_SYMBOL(iwl_nvm_check_version); diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.h b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.h index b33888991b946..5545210151cd9 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.h @@ -7,6 +7,7 @@ * * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2015 Intel Mobile Communications GmbH + * Copyright (C) 2018 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -33,6 +34,7 @@ * * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2015 Intel Mobile Communications GmbH + * Copyright (C) 2018 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -121,9 +123,6 @@ struct iwl_nvm_data * iwl_parse_eeprom_data(struct device *dev, const struct iwl_cfg *cfg, const u8 *eeprom, size_t eeprom_size);
-int iwl_nvm_check_version(struct iwl_nvm_data *data, - struct iwl_trans *trans); - int iwl_init_sband_channels(struct iwl_nvm_data *data, struct ieee80211_supported_band *sband, int n_channels, enum nl80211_band band); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index 534c0ea7b232e..78228f870f8f5 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -501,7 +501,9 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) if (mvm->nvm_file_name) iwl_mvm_load_nvm_to_nic(mvm);
- WARN_ON(iwl_nvm_check_version(mvm->nvm_data, mvm->trans)); + WARN_ONCE(mvm->nvm_data->nvm_version < mvm->trans->cfg->nvm_ver, + "Too old NVM version (0x%0x, required = 0x%0x)", + mvm->nvm_data->nvm_version, mvm->trans->cfg->nvm_ver);
/* * abort after reading the nvm in case RF Kill is on, we will complete
From: Krzysztof Kozlowski krzk@kernel.org
[ Upstream commit c5510b8dafce5f3f5a039c9b262ebcae0092c462 ]
If CONFIG_GPOILIB is not set, the stub of gpio_to_desc() should return the same type of error as regular version: NULL. All the callers compare the return value of gpio_to_desc() against NULL, so returned ERR_PTR would be treated as non-error case leading to dereferencing of error value.
Fixes: 79a9becda894 ("gpiolib: export descriptor-based GPIO interface") Signed-off-by: Krzysztof Kozlowski krzk@kernel.org Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/gpio/consumer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h index c4a350d835788..79ad4f8b889dc 100644 --- a/include/linux/gpio/consumer.h +++ b/include/linux/gpio/consumer.h @@ -404,7 +404,7 @@ static inline int gpiod_to_irq(const struct gpio_desc *desc)
static inline struct gpio_desc *gpio_to_desc(unsigned gpio) { - return ERR_PTR(-EINVAL); + return NULL; }
static inline int desc_to_gpio(const struct gpio_desc *desc)
From: Jim Mattson jmattson@google.com
[ Upstream commit 0023ef39dc35c773c436eaa46ca539a26b308b55 ]
RDTSCP is supported in legacy mode as well as long mode. The IA32_TSC_AUX MSR should be set to the correct guest value before entering any guest that supports RDTSCP.
Fixes: 4e47c7a6d714 ("KVM: VMX: Add instruction rdtscp support for guest") Signed-off-by: Jim Mattson jmattson@google.com Reviewed-by: Peter Shier pshier@google.com Reviewed-by: Marc Orr marcorr@google.com Reviewed-by: Liran Alon liran.alon@oracle.com Reviewed-by: Sean Christopherson sean.j.christopherson@intel.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/kvm/vmx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index f67fc0f359ff3..76f353aef577f 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -2818,9 +2818,6 @@ static void setup_msrs(struct vcpu_vmx *vmx) index = __find_msr_index(vmx, MSR_CSTAR); if (index >= 0) move_msr_up(vmx, index, save_nmsrs++); - index = __find_msr_index(vmx, MSR_TSC_AUX); - if (index >= 0 && guest_cpuid_has(&vmx->vcpu, X86_FEATURE_RDTSCP)) - move_msr_up(vmx, index, save_nmsrs++); /* * MSR_STAR is only needed on long mode guests, and only * if efer.sce is enabled. @@ -2833,6 +2830,9 @@ static void setup_msrs(struct vcpu_vmx *vmx) index = __find_msr_index(vmx, MSR_EFER); if (index >= 0 && update_transition_efer(vmx, index)) move_msr_up(vmx, index, save_nmsrs++); + index = __find_msr_index(vmx, MSR_TSC_AUX); + if (index >= 0 && guest_cpuid_has(&vmx->vcpu, X86_FEATURE_RDTSCP)) + move_msr_up(vmx, index, save_nmsrs++);
vmx->save_nmsrs = save_nmsrs;
From: Lepton Wu ytht.net@gmail.com
[ Upstream commit 8236b08cf50f85bbfaf48910a0b3ee68318b7c4b ]
The old code always starts from fixed port for VMADDR_PORT_ANY. Sometimes when VMM crashed, there is still orphaned vsock which is waiting for close timer, then it could cause connection time out for new started VM if they are trying to connect to same port with same guest cid since the new packets could hit that orphaned vsock. We could also fix this by doing more in vhost_vsock_reset_orphans, but any way, it should be better to start from a random local port instead of a fixed one.
Signed-off-by: Lepton Wu ytht.net@gmail.com Reviewed-by: Jorgen Hansen jhansen@vmware.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/vmw_vsock/af_vsock.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index 1939b77e98b72..73eac97e19fb1 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -107,6 +107,7 @@ #include <linux/mutex.h> #include <linux/net.h> #include <linux/poll.h> +#include <linux/random.h> #include <linux/skbuff.h> #include <linux/smp.h> #include <linux/socket.h> @@ -487,9 +488,13 @@ out: static int __vsock_bind_stream(struct vsock_sock *vsk, struct sockaddr_vm *addr) { - static u32 port = LAST_RESERVED_PORT + 1; + static u32 port = 0; struct sockaddr_vm new_addr;
+ if (!port) + port = LAST_RESERVED_PORT + 1 + + prandom_u32_max(U32_MAX - LAST_RESERVED_PORT); + vsock_addr_init(&new_addr, addr->svm_cid, addr->svm_port);
if (addr->svm_port == VMADDR_PORT_ANY) {
From: Jerome Brunet jbrunet@baylibre.com
[ Upstream commit 18f92bc02f1739b5c4d5b70009fbb7eada45bca3 ]
On errors, if we don't stop the descriptor chain, it may continue to run and raise IRQ after we have called mmc_request_done(). This is bad because we won't be able to get cmd anymore and properly deal with the IRQ.
This patch makes sure the descriptor chain is stopped before calling mmc_request_done()
Fixes: 79ed05e329c3 ("mmc: meson-gx: add support for descriptor chain mode") Signed-off-by: Jerome Brunet jbrunet@baylibre.com Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mmc/host/meson-gx-mmc.c | 73 ++++++++++++++++++++++++++++----- 1 file changed, 63 insertions(+), 10 deletions(-)
diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c index 08a55c2e96e1b..53ce1bb83d2c5 100644 --- a/drivers/mmc/host/meson-gx-mmc.c +++ b/drivers/mmc/host/meson-gx-mmc.c @@ -21,6 +21,7 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> +#include <linux/delay.h> #include <linux/device.h> #include <linux/of_device.h> #include <linux/platform_device.h> @@ -74,9 +75,11 @@ #define CFG_CLK_ALWAYS_ON BIT(18) #define CFG_CHK_DS BIT(20) #define CFG_AUTO_CLK BIT(23) +#define CFG_ERR_ABORT BIT(27)
#define SD_EMMC_STATUS 0x48 #define STATUS_BUSY BIT(31) +#define STATUS_DESC_BUSY BIT(30) #define STATUS_DATI GENMASK(23, 16)
#define SD_EMMC_IRQ_EN 0x4c @@ -905,6 +908,7 @@ static void meson_mmc_start_cmd(struct mmc_host *mmc, struct mmc_command *cmd)
cmd_cfg |= FIELD_PREP(CMD_CFG_CMD_INDEX_MASK, cmd->opcode); cmd_cfg |= CMD_CFG_OWNER; /* owned by CPU */ + cmd_cfg |= CMD_CFG_ERROR; /* stop in case of error */
meson_mmc_set_response_bits(cmd, &cmd_cfg);
@@ -999,6 +1003,17 @@ static irqreturn_t meson_mmc_irq(int irq, void *dev_id) u32 irq_en, status, raw_status; irqreturn_t ret = IRQ_NONE;
+ irq_en = readl(host->regs + SD_EMMC_IRQ_EN); + raw_status = readl(host->regs + SD_EMMC_STATUS); + status = raw_status & irq_en; + + if (!status) { + dev_dbg(host->dev, + "Unexpected IRQ! irq_en 0x%08x - status 0x%08x\n", + irq_en, raw_status); + return IRQ_NONE; + } + if (WARN_ON(!host) || WARN_ON(!host->cmd)) return IRQ_NONE;
@@ -1006,22 +1021,18 @@ static irqreturn_t meson_mmc_irq(int irq, void *dev_id)
cmd = host->cmd; data = cmd->data; - irq_en = readl(host->regs + SD_EMMC_IRQ_EN); - raw_status = readl(host->regs + SD_EMMC_STATUS); - status = raw_status & irq_en; - cmd->error = 0; if (status & IRQ_CRC_ERR) { dev_dbg(host->dev, "CRC Error - status 0x%08x\n", status); cmd->error = -EILSEQ; - ret = IRQ_HANDLED; + ret = IRQ_WAKE_THREAD; goto out; }
if (status & IRQ_TIMEOUTS) { dev_dbg(host->dev, "Timeout - status 0x%08x\n", status); cmd->error = -ETIMEDOUT; - ret = IRQ_HANDLED; + ret = IRQ_WAKE_THREAD; goto out; }
@@ -1046,17 +1057,49 @@ out: /* ack all enabled interrupts */ writel(irq_en, host->regs + SD_EMMC_STATUS);
+ if (cmd->error) { + /* Stop desc in case of errors */ + u32 start = readl(host->regs + SD_EMMC_START); + + start &= ~START_DESC_BUSY; + writel(start, host->regs + SD_EMMC_START); + } + if (ret == IRQ_HANDLED) meson_mmc_request_done(host->mmc, cmd->mrq); - else if (ret == IRQ_NONE) - dev_warn(host->dev, - "Unexpected IRQ! status=0x%08x, irq_en=0x%08x\n", - raw_status, irq_en);
spin_unlock(&host->lock); return ret; }
+static int meson_mmc_wait_desc_stop(struct meson_host *host) +{ + int loop; + u32 status; + + /* + * It may sometimes take a while for it to actually halt. Here, we + * are giving it 5ms to comply + * + * If we don't confirm the descriptor is stopped, it might raise new + * IRQs after we have called mmc_request_done() which is bad. + */ + for (loop = 50; loop; loop--) { + status = readl(host->regs + SD_EMMC_STATUS); + if (status & (STATUS_BUSY | STATUS_DESC_BUSY)) + udelay(100); + else + break; + } + + if (status & (STATUS_BUSY | STATUS_DESC_BUSY)) { + dev_err(host->dev, "Timed out waiting for host to stop\n"); + return -ETIMEDOUT; + } + + return 0; +} + static irqreturn_t meson_mmc_irq_thread(int irq, void *dev_id) { struct meson_host *host = dev_id; @@ -1067,6 +1110,13 @@ static irqreturn_t meson_mmc_irq_thread(int irq, void *dev_id) if (WARN_ON(!cmd)) return IRQ_NONE;
+ if (cmd->error) { + meson_mmc_wait_desc_stop(host); + meson_mmc_request_done(host->mmc, cmd->mrq); + + return IRQ_HANDLED; + } + data = cmd->data; if (meson_mmc_bounce_buf_read(data)) { xfer_bytes = data->blksz * data->blocks; @@ -1107,6 +1157,9 @@ static void meson_mmc_cfg_init(struct meson_host *host) cfg |= FIELD_PREP(CFG_RC_CC_MASK, ilog2(SD_EMMC_CFG_CMD_GAP)); cfg |= FIELD_PREP(CFG_BLK_LEN_MASK, ilog2(SD_EMMC_CFG_BLK_SIZE));
+ /* abort chain on R/W errors */ + cfg |= CFG_ERR_ABORT; + writel(cfg, host->regs + SD_EMMC_CFG); }
From: Boris Brezillon boris.brezillon@bootlin.com
[ Upstream commit 732774437ae01d9882e60314e303898e63c7f038 ]
The opcodes used by the controller when doing batched page prog should be written in NFC_REG_WCMD_SET not FC_REG_RCMD_SET. Luckily, the default NFC_REG_WCMD_SET value matches the one we set in the driver which explains why we didn't notice the problem.
Fixes: 614049a8d904 ("mtd: nand: sunxi: add support for DMA assisted operations") Signed-off-by: Boris Brezillon boris.brezillon@bootlin.com Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mtd/nand/sunxi_nand.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c index 9589748215821..8e52314823976 100644 --- a/drivers/mtd/nand/sunxi_nand.c +++ b/drivers/mtd/nand/sunxi_nand.c @@ -1435,7 +1435,7 @@ static int sunxi_nfc_hw_ecc_write_page_dma(struct mtd_info *mtd, sunxi_nfc_randomizer_enable(mtd);
writel((NAND_CMD_RNDIN << 8) | NAND_CMD_PAGEPROG, - nfc->regs + NFC_REG_RCMD_SET); + nfc->regs + NFC_REG_WCMD_SET);
dma_async_issue_pending(nfc->dmac);
From: Josef Bacik jbacik@fb.com
[ Upstream commit 158ffa364bf723fa1ef128060646d23dc3942994 ]
We use this number to figure out how many delayed refs to run, but __btrfs_run_delayed_refs really only checks every time we need a new delayed ref head, so we always run at least one ref head completely no matter what the number of items on it. Fix the accounting to only be adjusted when we add/remove a ref head.
In addition to using this number to limit the number of delayed refs run, a future patch is also going to use it to calculate the amount of space required for delayed refs space reservation.
Reviewed-by: Nikolay Borisov nborisov@suse.com Signed-off-by: Josef Bacik jbacik@fb.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/btrfs/delayed-ref.c | 3 --- 1 file changed, 3 deletions(-)
diff --git a/fs/btrfs/delayed-ref.c b/fs/btrfs/delayed-ref.c index 93ffa898df6d8..d56bd36254681 100644 --- a/fs/btrfs/delayed-ref.c +++ b/fs/btrfs/delayed-ref.c @@ -195,8 +195,6 @@ static inline void drop_delayed_ref(struct btrfs_trans_handle *trans, ref->in_tree = 0; btrfs_put_delayed_ref(ref); atomic_dec(&delayed_refs->num_entries); - if (trans->delayed_ref_updates) - trans->delayed_ref_updates--; }
static bool merge_ref(struct btrfs_trans_handle *trans, @@ -458,7 +456,6 @@ add_tail: if (ref->action == BTRFS_ADD_DELAYED_REF) list_add_tail(&ref->add_list, &href->ref_add_list); atomic_inc(&root->num_entries); - trans->delayed_ref_updates++; spin_unlock(&href->lock); return ret; }
From: Pan Bian bianpan2016@163.com
[ Upstream commit 6e0856d317440a950b17c00a9283114f025e5699 ]
The memory chunk allocated by hid_allocate_device() should be released by hid_destroy_device(), not kfree().
Fixes: 0b28cb4bcb1("HID: intel-ish-hid: ISH HID client driver") Signed-off-by: Pan Bian bianpan2016@163.com Reviewed-by: Benjamin Tissoires benjamin.tissoires@redhat.com Signed-off-by: Jiri Kosina jkosina@suse.cz Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hid/intel-ish-hid/ishtp-hid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/hid/intel-ish-hid/ishtp-hid.c b/drivers/hid/intel-ish-hid/ishtp-hid.c index cd23903ddcf19..e918d78e541c0 100644 --- a/drivers/hid/intel-ish-hid/ishtp-hid.c +++ b/drivers/hid/intel-ish-hid/ishtp-hid.c @@ -222,7 +222,7 @@ int ishtp_hid_probe(unsigned int cur_hid_dev, err_hid_device: kfree(hid_data); err_hid_data: - kfree(hid); + hid_destroy_device(hid); return rv; }
From: Darwin Dingel darwin.dingel@alliedtelesis.co.nz
[ Upstream commit 6d7f677a2afa1c82d7fc7af7f9159cbffd5dc010 ]
When a serial port gets faulty or gets flooded with inputs, its interrupt handler starts to work double time to get the characters to the workqueue for the tty layer to handle them. When this busy time on the serial/tty subsystem happens during boot, where it is also busy on the userspace trying to initialise, some processes can continuously get preempted and will be on hold until the interrupts subside.
The fix is to backoff on processing received characters for a specified amount of time when an input overrun is seen (received a new character before the previous one is processed). This only stops receive and will continue to transmit characters to serial port. After the backoff period is done, it receive will be re-enabled. This is optional and will only be enabled by setting 'overrun-throttle-ms' in the dts.
Signed-off-by: Darwin Dingel darwin.dingel@alliedtelesis.co.nz Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/8250/8250_core.c | 25 +++++++++++++++++++++++++ drivers/tty/serial/8250/8250_fsl.c | 23 ++++++++++++++++++++++- drivers/tty/serial/8250/8250_of.c | 5 +++++ include/linux/serial_8250.h | 4 ++++ 4 files changed, 56 insertions(+), 1 deletion(-)
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index d29b512a7d9fa..ceeea4b159c4b 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -953,6 +953,21 @@ static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port * return NULL; }
+static void serial_8250_overrun_backoff_work(struct work_struct *work) +{ + struct uart_8250_port *up = + container_of(to_delayed_work(work), struct uart_8250_port, + overrun_backoff); + struct uart_port *port = &up->port; + unsigned long flags; + + spin_lock_irqsave(&port->lock, flags); + up->ier |= UART_IER_RLSI | UART_IER_RDI; + up->port.read_status_mask |= UART_LSR_DR; + serial_out(up, UART_IER, up->ier); + spin_unlock_irqrestore(&port->lock, flags); +} + /** * serial8250_register_8250_port - register a serial port * @up: serial port template @@ -1063,6 +1078,16 @@ int serial8250_register_8250_port(struct uart_8250_port *up) ret = 0; } } + + /* Initialise interrupt backoff work if required */ + if (up->overrun_backoff_time_ms > 0) { + uart->overrun_backoff_time_ms = up->overrun_backoff_time_ms; + INIT_DELAYED_WORK(&uart->overrun_backoff, + serial_8250_overrun_backoff_work); + } else { + uart->overrun_backoff_time_ms = 0; + } + mutex_unlock(&serial_mutex);
return ret; diff --git a/drivers/tty/serial/8250/8250_fsl.c b/drivers/tty/serial/8250/8250_fsl.c index 910bfee5a88b7..cc138c24ae889 100644 --- a/drivers/tty/serial/8250/8250_fsl.c +++ b/drivers/tty/serial/8250/8250_fsl.c @@ -48,8 +48,29 @@ int fsl8250_handle_irq(struct uart_port *port)
lsr = orig_lsr = up->port.serial_in(&up->port, UART_LSR);
- if (lsr & (UART_LSR_DR | UART_LSR_BI)) + /* Process incoming characters first */ + if ((lsr & (UART_LSR_DR | UART_LSR_BI)) && + (up->ier & (UART_IER_RLSI | UART_IER_RDI))) { lsr = serial8250_rx_chars(up, lsr); + } + + /* Stop processing interrupts on input overrun */ + if ((orig_lsr & UART_LSR_OE) && (up->overrun_backoff_time_ms > 0)) { + unsigned long delay; + + up->ier = port->serial_in(port, UART_IER); + if (up->ier & (UART_IER_RLSI | UART_IER_RDI)) { + port->ops->stop_rx(port); + } else { + /* Keep restarting the timer until + * the input overrun subsides. + */ + cancel_delayed_work(&up->overrun_backoff); + } + + delay = msecs_to_jiffies(up->overrun_backoff_time_ms); + schedule_delayed_work(&up->overrun_backoff, delay); + }
serial8250_modem_status(up);
diff --git a/drivers/tty/serial/8250/8250_of.c b/drivers/tty/serial/8250/8250_of.c index ec510e342e06c..c51044ba503c3 100644 --- a/drivers/tty/serial/8250/8250_of.c +++ b/drivers/tty/serial/8250/8250_of.c @@ -232,6 +232,11 @@ static int of_platform_serial_probe(struct platform_device *ofdev) if (of_property_read_bool(ofdev->dev.of_node, "auto-flow-control")) port8250.capabilities |= UART_CAP_AFE;
+ if (of_property_read_u32(ofdev->dev.of_node, + "overrun-throttle-ms", + &port8250.overrun_backoff_time_ms) != 0) + port8250.overrun_backoff_time_ms = 0; + ret = serial8250_register_8250_port(&port8250); if (ret < 0) goto err_dispose; diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h index a27ef5f564317..791a6be0e3949 100644 --- a/include/linux/serial_8250.h +++ b/include/linux/serial_8250.h @@ -134,6 +134,10 @@ struct uart_8250_port { void (*dl_write)(struct uart_8250_port *, int);
struct uart_8250_em485 *em485; + + /* Serial port overrun backoff */ + struct delayed_work overrun_backoff; + u32 overrun_backoff_time_ms; };
static inline struct uart_8250_port *up_to_u8250p(struct uart_port *up)
From: Andrea Righi righi.andrea@gmail.com
[ Upstream commit bf9445a33ae6ac2f0822d2f1ce1365408387d568 ]
Blacklist symbols in Xen probe-prohibited areas, so that user can see these prohibited symbols in debugfs.
See also: a50480cb6d61.
Signed-off-by: Andrea Righi righi.andrea@gmail.com Acked-by: Masami Hiramatsu mhiramat@kernel.org Signed-off-by: Boris Ostrovsky boris.ostrovsky@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/xen/xen-asm_64.S | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/arch/x86/xen/xen-asm_64.S b/arch/x86/xen/xen-asm_64.S index 3a6feed76dfc1..a93d8a7cef26c 100644 --- a/arch/x86/xen/xen-asm_64.S +++ b/arch/x86/xen/xen-asm_64.S @@ -12,6 +12,7 @@ #include <asm/segment.h> #include <asm/asm-offsets.h> #include <asm/thread_info.h> +#include <asm/asm.h>
#include <xen/interface/xen.h>
@@ -24,6 +25,7 @@ ENTRY(xen_\name) pop %r11 jmp \name END(xen_\name) +_ASM_NOKPROBE(xen_\name) .endm
xen_pv_trap divide_error
From: Ross Lagerwall ross.lagerwall@citrix.com
[ Upstream commit 1669907e3d1abfa3f7586e2d55dbbc117b5adba2 ]
If pcistub_init_device fails, the release function will be called with dev_data set to NULL. Check it before using it to avoid a NULL pointer dereference.
Signed-off-by: Ross Lagerwall ross.lagerwall@citrix.com Reviewed-by: Boris Ostrovsky boris.ostrovsky@oracle.com Signed-off-by: Boris Ostrovsky boris.ostrovsky@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/xen/xen-pciback/pci_stub.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c index 9e480fdebe1f0..8c250f4a3a97a 100644 --- a/drivers/xen/xen-pciback/pci_stub.c +++ b/drivers/xen/xen-pciback/pci_stub.c @@ -106,7 +106,8 @@ static void pcistub_device_release(struct kref *kref) * is called from "unbind" which takes a device_lock mutex. */ __pci_reset_function_locked(dev); - if (pci_load_and_free_saved_state(dev, &dev_data->pci_saved_state)) + if (dev_data && + pci_load_and_free_saved_state(dev, &dev_data->pci_saved_state)) dev_info(&dev->dev, "Could not reload PCI state\n"); else pci_restore_state(dev);
From: Nathan Chancellor natechancellor@gmail.com
[ Upstream commit 8ba35b3a0046d6573c98f00461d9bd1b86250d35 ]
Clang warns:
samples/vfio-mdev/mtty.c:592:39: warning: implicit conversion from 'int' to 'char' changes value from 162 to -94 [-Wconstant-conversion] *buf = UART_MSR_DSR | UART_MSR_DDSR | UART_MSR_DCD; ~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~ 1 warning generated.
Turns out that all uses of buf in this function ultimately end up stored or cast to an unsigned type. Just use u8, which has the same number of bits but can store this larger number so Clang no longer warns.
Signed-off-by: Nathan Chancellor natechancellor@gmail.com Signed-off-by: Alex Williamson alex.williamson@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- samples/vfio-mdev/mtty.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-)
diff --git a/samples/vfio-mdev/mtty.c b/samples/vfio-mdev/mtty.c index ca495686b9c31..f8c7249fa705d 100644 --- a/samples/vfio-mdev/mtty.c +++ b/samples/vfio-mdev/mtty.c @@ -171,7 +171,7 @@ static struct mdev_state *find_mdev_state_by_uuid(uuid_le uuid) return NULL; }
-void dump_buffer(char *buf, uint32_t count) +void dump_buffer(u8 *buf, uint32_t count) { #if defined(DEBUG) int i; @@ -250,7 +250,7 @@ static void mtty_create_config_space(struct mdev_state *mdev_state) }
static void handle_pci_cfg_write(struct mdev_state *mdev_state, u16 offset, - char *buf, u32 count) + u8 *buf, u32 count) { u32 cfg_addr, bar_mask, bar_index = 0;
@@ -304,7 +304,7 @@ static void handle_pci_cfg_write(struct mdev_state *mdev_state, u16 offset, }
static void handle_bar_write(unsigned int index, struct mdev_state *mdev_state, - u16 offset, char *buf, u32 count) + u16 offset, u8 *buf, u32 count) { u8 data = *buf;
@@ -475,7 +475,7 @@ static void handle_bar_write(unsigned int index, struct mdev_state *mdev_state, }
static void handle_bar_read(unsigned int index, struct mdev_state *mdev_state, - u16 offset, char *buf, u32 count) + u16 offset, u8 *buf, u32 count) { /* Handle read requests by guest */ switch (offset) { @@ -650,7 +650,7 @@ static void mdev_read_base(struct mdev_state *mdev_state) } }
-static ssize_t mdev_access(struct mdev_device *mdev, char *buf, size_t count, +static ssize_t mdev_access(struct mdev_device *mdev, u8 *buf, size_t count, loff_t pos, bool is_write) { struct mdev_state *mdev_state; @@ -698,7 +698,7 @@ static ssize_t mdev_access(struct mdev_device *mdev, char *buf, size_t count, #if defined(DEBUG_REGS) pr_info("%s: BAR%d WR @0x%llx %s val:0x%02x dlab:%d\n", __func__, index, offset, wr_reg[offset], - (u8)*buf, mdev_state->s[index].dlab); + *buf, mdev_state->s[index].dlab); #endif handle_bar_write(index, mdev_state, offset, buf, count); } else { @@ -708,7 +708,7 @@ static ssize_t mdev_access(struct mdev_device *mdev, char *buf, size_t count, #if defined(DEBUG_REGS) pr_info("%s: BAR%d RD @0x%llx %s val:0x%02x dlab:%d\n", __func__, index, offset, rd_reg[offset], - (u8)*buf, mdev_state->s[index].dlab); + *buf, mdev_state->s[index].dlab); #endif } break; @@ -827,7 +827,7 @@ ssize_t mtty_read(struct mdev_device *mdev, char __user *buf, size_t count, if (count >= 4 && !(*ppos % 4)) { u32 val;
- ret = mdev_access(mdev, (char *)&val, sizeof(val), + ret = mdev_access(mdev, (u8 *)&val, sizeof(val), *ppos, false); if (ret <= 0) goto read_err; @@ -839,7 +839,7 @@ ssize_t mtty_read(struct mdev_device *mdev, char __user *buf, size_t count, } else if (count >= 2 && !(*ppos % 2)) { u16 val;
- ret = mdev_access(mdev, (char *)&val, sizeof(val), + ret = mdev_access(mdev, (u8 *)&val, sizeof(val), *ppos, false); if (ret <= 0) goto read_err; @@ -851,7 +851,7 @@ ssize_t mtty_read(struct mdev_device *mdev, char __user *buf, size_t count, } else { u8 val;
- ret = mdev_access(mdev, (char *)&val, sizeof(val), + ret = mdev_access(mdev, (u8 *)&val, sizeof(val), *ppos, false); if (ret <= 0) goto read_err; @@ -889,7 +889,7 @@ ssize_t mtty_write(struct mdev_device *mdev, const char __user *buf, if (copy_from_user(&val, buf, sizeof(val))) goto write_err;
- ret = mdev_access(mdev, (char *)&val, sizeof(val), + ret = mdev_access(mdev, (u8 *)&val, sizeof(val), *ppos, true); if (ret <= 0) goto write_err; @@ -901,7 +901,7 @@ ssize_t mtty_write(struct mdev_device *mdev, const char __user *buf, if (copy_from_user(&val, buf, sizeof(val))) goto write_err;
- ret = mdev_access(mdev, (char *)&val, sizeof(val), + ret = mdev_access(mdev, (u8 *)&val, sizeof(val), *ppos, true); if (ret <= 0) goto write_err; @@ -913,7 +913,7 @@ ssize_t mtty_write(struct mdev_device *mdev, const char __user *buf, if (copy_from_user(&val, buf, sizeof(val))) goto write_err;
- ret = mdev_access(mdev, (char *)&val, sizeof(val), + ret = mdev_access(mdev, (u8 *)&val, sizeof(val), *ppos, true); if (ret <= 0) goto write_err;
From: Martin Schiller ms@dev.tdt.de
[ Upstream commit 9b4924da4711674e62d97d4f5360446cc78337af ]
This patch is based on commit a86caa9ba5d7 ("pinctrl: msm: fix gpio-hog related boot issues").
It fixes the issue that the gpio ranges needs to be defined before gpiochip_add().
Therefore, we also have to swap the order of registering the pinctrl driver and registering the gpio chip.
You also have to add the "gpio-ranges" property to the pinctrl device node to get it finally working.
Signed-off-by: Martin Schiller ms@dev.tdt.de Acked-by: John Crispin john@phrozen.org Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/pinctrl-xway.c | 39 +++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 12 deletions(-)
diff --git a/drivers/pinctrl/pinctrl-xway.c b/drivers/pinctrl/pinctrl-xway.c index f9e98a7d4f0ce..1b0c5958c56a7 100644 --- a/drivers/pinctrl/pinctrl-xway.c +++ b/drivers/pinctrl/pinctrl-xway.c @@ -1748,14 +1748,6 @@ static int pinmux_xway_probe(struct platform_device *pdev) } xway_pctrl_desc.pins = xway_info.pads;
- /* register the gpio chip */ - xway_chip.parent = &pdev->dev; - ret = devm_gpiochip_add_data(&pdev->dev, &xway_chip, NULL); - if (ret) { - dev_err(&pdev->dev, "Failed to register gpio chip\n"); - return ret; - } - /* setup the data needed by pinctrl */ xway_pctrl_desc.name = dev_name(&pdev->dev); xway_pctrl_desc.npins = xway_chip.ngpio; @@ -1777,10 +1769,33 @@ static int pinmux_xway_probe(struct platform_device *pdev) return ret; }
- /* finish with registering the gpio range in pinctrl */ - xway_gpio_range.npins = xway_chip.ngpio; - xway_gpio_range.base = xway_chip.base; - pinctrl_add_gpio_range(xway_info.pctrl, &xway_gpio_range); + /* register the gpio chip */ + xway_chip.parent = &pdev->dev; + xway_chip.owner = THIS_MODULE; + xway_chip.of_node = pdev->dev.of_node; + ret = devm_gpiochip_add_data(&pdev->dev, &xway_chip, NULL); + if (ret) { + dev_err(&pdev->dev, "Failed to register gpio chip\n"); + return ret; + } + + /* + * For DeviceTree-supported systems, the gpio core checks the + * pinctrl's device node for the "gpio-ranges" property. + * If it is present, it takes care of adding the pin ranges + * for the driver. In this case the driver can skip ahead. + * + * In order to remain compatible with older, existing DeviceTree + * files which don't set the "gpio-ranges" property or systems that + * utilize ACPI the driver has to call gpiochip_add_pin_range(). + */ + if (!of_property_read_bool(pdev->dev.of_node, "gpio-ranges")) { + /* finish with registering the gpio range in pinctrl */ + xway_gpio_range.npins = xway_chip.ngpio; + xway_gpio_range.base = xway_chip.base; + pinctrl_add_gpio_range(xway_info.pctrl, &xway_gpio_range); + } + dev_info(&pdev->dev, "Init done\n"); return 0; }
From: Leon Romanovsky leonro@mellanox.com
[ Upstream commit 199fa087dc6b503baad06712716fac645a983e8a ]
The failure to create debugfs entry is unpleasant event, but not enough to abort drier initialization. Align the mlx5_core code to debugfs design and continue execution whenever debugfs_create_dir() successes or not.
Fixes: e126ba97dba9 ("mlx5: Add driver for Mellanox Connect-IB adapters") Reviewed-by: Saeed Mahameed saeedm@mellanox.com Signed-off-by: Leon Romanovsky leonro@mellanox.com Signed-off-by: Saeed Mahameed saeedm@mellanox.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/mellanox/mlx5/core/main.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index 97874c2568fc9..1ac0e173da12c 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c @@ -838,11 +838,9 @@ static int mlx5_pci_init(struct mlx5_core_dev *dev, struct mlx5_priv *priv)
priv->numa_node = dev_to_node(&dev->pdev->dev);
- priv->dbg_root = debugfs_create_dir(dev_name(&pdev->dev), mlx5_debugfs_root); - if (!priv->dbg_root) { - dev_err(&pdev->dev, "Cannot create debugfs dir, aborting\n"); - return -ENOMEM; - } + if (mlx5_debugfs_root) + priv->dbg_root = + debugfs_create_dir(pci_name(pdev), mlx5_debugfs_root);
err = mlx5_pci_enable_device(dev); if (err) {
From: Al Viro viro@zeniv.linux.org.uk
[ Upstream commit 26cb5a328c6b2bda9e859307ce4cfc60df3a2c28 ]
... and don't abuse mount_nodev(), while we are at it.
Signed-off-by: Al Viro viro@zeniv.linux.org.uk Reviewed-by: David Howells dhowells@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/exofs/super.c | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-)
diff --git a/fs/exofs/super.c b/fs/exofs/super.c index c9ec652e2fcd2..881d5798a1814 100644 --- a/fs/exofs/super.c +++ b/fs/exofs/super.c @@ -702,21 +702,18 @@ out: /* * Read the superblock from the OSD and fill in the fields */ -static int exofs_fill_super(struct super_block *sb, void *data, int silent) +static int exofs_fill_super(struct super_block *sb, + struct exofs_mountopt *opts, + struct exofs_sb_info *sbi, + int silent) { struct inode *root; - struct exofs_mountopt *opts = data; - struct exofs_sb_info *sbi; /*extended info */ struct osd_dev *od; /* Master device */ struct exofs_fscb fscb; /*on-disk superblock info */ struct ore_comp comp; unsigned table_count; int ret;
- sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); - if (!sbi) - return -ENOMEM; - /* use mount options to fill superblock */ if (opts->is_osdname) { struct osd_dev_info odi = {.systemid_len = 0}; @@ -860,7 +857,9 @@ static struct dentry *exofs_mount(struct file_system_type *type, int flags, const char *dev_name, void *data) { + struct super_block *s; struct exofs_mountopt opts; + struct exofs_sb_info *sbi; int ret;
ret = parse_options(data, &opts); @@ -869,9 +868,31 @@ static struct dentry *exofs_mount(struct file_system_type *type, return ERR_PTR(ret); }
+ sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); + if (!sbi) { + kfree(opts.dev_name); + return ERR_PTR(-ENOMEM); + } + + s = sget(type, NULL, set_anon_super, flags, NULL); + + if (IS_ERR(s)) { + kfree(opts.dev_name); + kfree(sbi); + return ERR_CAST(s); + } + if (!opts.dev_name) opts.dev_name = dev_name; - return mount_nodev(type, flags, &opts, exofs_fill_super); + + + ret = exofs_fill_super(s, &opts, sbi, flags & SB_SILENT ? 1 : 0); + if (ret) { + deactivate_locked_super(s); + return ERR_PTR(ret); + } + s->s_flags |= SB_ACTIVE; + return dget(s->s_root); }
/*
From: Vasundhara Volam vasundhara-v.volam@broadcom.com
[ Upstream commit 7c675421afef18253a86ffc383f57bc15ef32ea8 ]
Currently firmware specific errors are returned directly in flash_device and reset ethtool hooks. Modify it to return linux standard errors to userspace when flashing operations fail.
Signed-off-by: Vasundhara Volam vasundhara-v.volam@broadcom.com Signed-off-by: Michael Chan michael.chan@broadcom.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- .../net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 56 +++++++++++++------ 1 file changed, 39 insertions(+), 17 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c index a22336fef66b2..4879371ad0c75 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c @@ -1339,14 +1339,22 @@ static int bnxt_flash_nvram(struct net_device *dev, rc = hwrm_send_message(bp, &req, sizeof(req), FLASH_NVRAM_TIMEOUT); dma_free_coherent(&bp->pdev->dev, data_len, kmem, dma_handle);
+ if (rc == HWRM_ERR_CODE_RESOURCE_ACCESS_DENIED) { + netdev_info(dev, + "PF does not have admin privileges to flash the device\n"); + rc = -EACCES; + } else if (rc) { + rc = -EIO; + } return rc; }
static int bnxt_firmware_reset(struct net_device *dev, u16 dir_type) { - struct bnxt *bp = netdev_priv(dev); struct hwrm_fw_reset_input req = {0}; + struct bnxt *bp = netdev_priv(dev); + int rc;
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FW_RESET, -1, -1);
@@ -1380,7 +1388,15 @@ static int bnxt_firmware_reset(struct net_device *dev, return -EINVAL; }
- return hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); + rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); + if (rc == HWRM_ERR_CODE_RESOURCE_ACCESS_DENIED) { + netdev_info(dev, + "PF does not have admin privileges to reset the device\n"); + rc = -EACCES; + } else if (rc) { + rc = -EIO; + } + return rc; }
static int bnxt_flash_firmware(struct net_device *dev, @@ -1587,9 +1603,9 @@ static int bnxt_flash_package_from_file(struct net_device *dev, struct hwrm_nvm_install_update_output *resp = bp->hwrm_cmd_resp_addr; struct hwrm_nvm_install_update_input install = {0}; const struct firmware *fw; + int rc, hwrm_err = 0; u32 item_len; u16 index; - int rc;
bnxt_hwrm_fw_set_time(bp);
@@ -1632,15 +1648,16 @@ static int bnxt_flash_package_from_file(struct net_device *dev, memcpy(kmem, fw->data, fw->size); modify.host_src_addr = cpu_to_le64(dma_handle);
- rc = hwrm_send_message(bp, &modify, sizeof(modify), - FLASH_PACKAGE_TIMEOUT); + hwrm_err = hwrm_send_message(bp, &modify, + sizeof(modify), + FLASH_PACKAGE_TIMEOUT); dma_free_coherent(&bp->pdev->dev, fw->size, kmem, dma_handle); } } release_firmware(fw); - if (rc) - return rc; + if (rc || hwrm_err) + goto err_exit;
if ((install_type & 0xffff) == 0) install_type >>= 16; @@ -1648,12 +1665,10 @@ static int bnxt_flash_package_from_file(struct net_device *dev, install.install_type = cpu_to_le32(install_type);
mutex_lock(&bp->hwrm_cmd_lock); - rc = _hwrm_send_message(bp, &install, sizeof(install), - INSTALL_PACKAGE_TIMEOUT); - if (rc) { - rc = -EOPNOTSUPP; + hwrm_err = _hwrm_send_message(bp, &install, sizeof(install), + INSTALL_PACKAGE_TIMEOUT); + if (hwrm_err) goto flash_pkg_exit; - }
if (resp->error_code) { u8 error_code = ((struct hwrm_err_output *)resp)->cmd_err; @@ -1661,12 +1676,11 @@ static int bnxt_flash_package_from_file(struct net_device *dev, if (error_code == NVM_INSTALL_UPDATE_CMD_ERR_CODE_FRAG_ERR) { install.flags |= cpu_to_le16( NVM_INSTALL_UPDATE_REQ_FLAGS_ALLOWED_TO_DEFRAG); - rc = _hwrm_send_message(bp, &install, sizeof(install), - INSTALL_PACKAGE_TIMEOUT); - if (rc) { - rc = -EOPNOTSUPP; + hwrm_err = _hwrm_send_message(bp, &install, + sizeof(install), + INSTALL_PACKAGE_TIMEOUT); + if (hwrm_err) goto flash_pkg_exit; - } } }
@@ -1677,6 +1691,14 @@ static int bnxt_flash_package_from_file(struct net_device *dev, } flash_pkg_exit: mutex_unlock(&bp->hwrm_cmd_lock); +err_exit: + if (hwrm_err == HWRM_ERR_CODE_RESOURCE_ACCESS_DENIED) { + netdev_info(dev, + "PF does not have admin privileges to flash the device\n"); + rc = -EACCES; + } else if (hwrm_err) { + rc = -EOPNOTSUPP; + } return rc; }
From: Vasundhara Volam vasundhara-v.volam@broadcom.com
[ Upstream commit 56d374624778652d2a999e18c87a25338b127b41 ]
With autoneg enabled, PHY loopback test fails. To disable autoneg, driver needs to send a valid forced speed to FW. FW is not sending async event for invalid speeds. To fix this, query forced speeds and send the correct speed when disabling autoneg mode.
Signed-off-by: Vasundhara Volam vasundhara-v.volam@broadcom.com Signed-off-by: Michael Chan michael.chan@broadcom.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- .../net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c index 4879371ad0c75..fc8e185718a1d 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c @@ -2258,17 +2258,37 @@ static int bnxt_hwrm_mac_loopback(struct bnxt *bp, bool enable) return hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); }
+static int bnxt_query_force_speeds(struct bnxt *bp, u16 *force_speeds) +{ + struct hwrm_port_phy_qcaps_output *resp = bp->hwrm_cmd_resp_addr; + struct hwrm_port_phy_qcaps_input req = {0}; + int rc; + + bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_PORT_PHY_QCAPS, -1, -1); + mutex_lock(&bp->hwrm_cmd_lock); + rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); + if (!rc) + *force_speeds = le16_to_cpu(resp->supported_speeds_force_mode); + + mutex_unlock(&bp->hwrm_cmd_lock); + return rc; +} + static int bnxt_disable_an_for_lpbk(struct bnxt *bp, struct hwrm_port_phy_cfg_input *req) { struct bnxt_link_info *link_info = &bp->link_info; - u16 fw_advertising = link_info->advertising; + u16 fw_advertising; u16 fw_speed; int rc;
if (!link_info->autoneg) return 0;
+ rc = bnxt_query_force_speeds(bp, &fw_advertising); + if (rc) + return rc; + fw_speed = PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_1GB; if (netif_carrier_ok(bp->dev)) fw_speed = bp->link_info.link_speed;
From: Michael Mueller mimu@linux.ibm.com
[ Upstream commit 308c3e6673b012beecb96ef04cc65f4a0e7cdd99 ]
Make sure the debug feature and its allocated resources get released upon unsuccessful architecture initialization.
A related indication of the issue will be reported as kernel message.
Signed-off-by: Michael Mueller mimu@linux.ibm.com Reviewed-by: Cornelia Huck cohuck@redhat.com Reviewed-by: Pierre Morel pmorel@linux.ibm.com Reviewed-by: David Hildenbrand david@redhat.com Message-Id: 20181130143215.69496-2-mimu@linux.ibm.com Signed-off-by: Christian Borntraeger borntraeger@de.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/s390/kvm/kvm-s390.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index ff62a4fe2159a..91c24e87fe10a 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -361,19 +361,30 @@ static void kvm_s390_cpu_feat_init(void)
int kvm_arch_init(void *opaque) { + int rc; + kvm_s390_dbf = debug_register("kvm-trace", 32, 1, 7 * sizeof(long)); if (!kvm_s390_dbf) return -ENOMEM;
if (debug_register_view(kvm_s390_dbf, &debug_sprintf_view)) { - debug_unregister(kvm_s390_dbf); - return -ENOMEM; + rc = -ENOMEM; + goto out_debug_unreg; }
kvm_s390_cpu_feat_init();
/* Register floating interrupt controller interface. */ - return kvm_register_device_ops(&kvm_flic_ops, KVM_DEV_TYPE_FLIC); + rc = kvm_register_device_ops(&kvm_flic_ops, KVM_DEV_TYPE_FLIC); + if (rc) { + pr_err("Failed to register FLIC rc=%d\n", rc); + goto out_debug_unreg; + } + return 0; + +out_debug_unreg: + debug_unregister(kvm_s390_dbf); + return rc; }
void kvm_arch_exit(void)
From: Geert Uytterhoeven geert+renesas@glider.be
[ Upstream commit 1b99d0c80bbe1810572c2cb77b90f67886adfa8d ]
The Port F Control Register 3 (PFCR3) contains only a single field. However, counting from left to right, it is the fourth field, not the first field. Insert the missing dummy configuration values (3 fields of 16 values) to fix this.
The descriptor for the Port F Control Register 0 (PFCR0) lacks the description for the 4th field (PF0 Mode, PF0MD[2:0]). Add the missing configuration values to fix this.
Fixes: a8d42fc4217b1ea1 ("sh-pfc: Add sh7264 pinmux support") Signed-off-by: Geert Uytterhoeven geert+renesas@glider.be Reviewed-by: Simon Horman horms+renesas@verge.net.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/sh-pfc/pfc-sh7264.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7264.c b/drivers/pinctrl/sh-pfc/pfc-sh7264.c index 8070765311dbf..e1c34e19222ee 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7264.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7264.c @@ -1716,6 +1716,9 @@ static const struct pinmux_cfg_reg pinmux_config_regs[] = { },
{ PINMUX_CFG_REG("PFCR3", 0xfffe38a8, 16, 4) { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, PF12MD_000, PF12MD_001, 0, PF12MD_011, PF12MD_100, PF12MD_101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } @@ -1759,8 +1762,10 @@ static const struct pinmux_cfg_reg pinmux_config_regs[] = { 0, 0, 0, 0, 0, 0, 0, 0, PF1MD_000, PF1MD_001, PF1MD_010, PF1MD_011, PF1MD_100, PF1MD_101, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 - } + 0, 0, 0, 0, 0, 0, 0, 0, + PF0MD_000, PF0MD_001, PF0MD_010, PF0MD_011, + PF0MD_100, PF0MD_101, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 } },
{ PINMUX_CFG_REG("PFIOR0", 0xfffe38b2, 16, 1) {
From: Geert Uytterhoeven geert+renesas@glider.be
[ Upstream commit 054f2400f706327f96770219c3065b5131f8f154 ]
Some values in the Peripheral Function Select Register 10 descriptor are shifted by one position, which may cause a peripheral function to be programmed incorrectly.
Fixing this makes all HSCIF0 pins use Function 4 (value 3), like was already the case for the HSCK0 pin in field IP10[5:3].
Fixes: ac1ebc2190f575fc ("sh-pfc: Add sh7734 pinmux support") Signed-off-by: Geert Uytterhoeven geert+renesas@glider.be Reviewed-by: Simon Horman horms+renesas@verge.net.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/sh-pfc/pfc-sh7734.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7734.c b/drivers/pinctrl/sh-pfc/pfc-sh7734.c index 6502e676d3686..33232041ee86d 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7734.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7734.c @@ -2213,22 +2213,22 @@ static const struct pinmux_cfg_reg pinmux_config_regs[] = { /* IP10_22 [1] */ FN_CAN_CLK_A, FN_RX4_D, /* IP10_21_19 [3] */ - FN_AUDIO_CLKOUT, FN_TX1_E, FN_HRTS0_C, FN_FSE_B, - FN_LCD_M_DISP_B, 0, 0, 0, + FN_AUDIO_CLKOUT, FN_TX1_E, 0, FN_HRTS0_C, FN_FSE_B, + FN_LCD_M_DISP_B, 0, 0, /* IP10_18_16 [3] */ - FN_AUDIO_CLKC, FN_SCK1_E, FN_HCTS0_C, FN_FRB_B, - FN_LCD_VEPWC_B, 0, 0, 0, + FN_AUDIO_CLKC, FN_SCK1_E, 0, FN_HCTS0_C, FN_FRB_B, + FN_LCD_VEPWC_B, 0, 0, /* IP10_15 [1] */ FN_AUDIO_CLKB_A, FN_LCD_CLK_B, /* IP10_14_12 [3] */ FN_AUDIO_CLKA_A, FN_VI1_CLK_B, FN_SCK1_D, FN_IECLK_B, FN_LCD_FLM_B, 0, 0, 0, /* IP10_11_9 [3] */ - FN_SSI_SDATA3, FN_VI1_7_B, FN_HTX0_C, FN_FWE_B, - FN_LCD_CL2_B, 0, 0, 0, + FN_SSI_SDATA3, FN_VI1_7_B, 0, FN_HTX0_C, FN_FWE_B, + FN_LCD_CL2_B, 0, 0, /* IP10_8_6 [3] */ - FN_SSI_SDATA2, FN_VI1_6_B, FN_HRX0_C, FN_FRE_B, - FN_LCD_CL1_B, 0, 0, 0, + FN_SSI_SDATA2, FN_VI1_6_B, 0, FN_HRX0_C, FN_FRE_B, + FN_LCD_CL1_B, 0, 0, /* IP10_5_3 [3] */ FN_SSI_WS23, FN_VI1_5_B, FN_TX1_D, FN_HSCK0_C, FN_FALE_B, FN_LCD_DON_B, 0, 0, 0,
From: Peter Hutterer peter.hutterer@who-t.net
[ Upstream commit 46b14eef59a8157138dc02f916a7f97c73b3ec53 ]
Signed-off-by: Peter Hutterer peter.hutterer@who-t.net Signed-off-by: Jiri Kosina jkosina@suse.cz Signed-off-by: Sasha Levin sashal@kernel.org --- Documentation/hid/uhid.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Documentation/hid/uhid.txt b/Documentation/hid/uhid.txt index c8656dd029a91..958fff9453044 100644 --- a/Documentation/hid/uhid.txt +++ b/Documentation/hid/uhid.txt @@ -160,7 +160,7 @@ them but you should handle them according to your needs. UHID_OUTPUT: This is sent if the HID device driver wants to send raw data to the I/O device on the interrupt channel. You should read the payload and forward it to - the device. The payload is of type "struct uhid_data_req". + the device. The payload is of type "struct uhid_output_req". This may be received even though you haven't received UHID_OPEN, yet.
UHID_GET_REPORT:
From: Sweet Tea sweettea@redhat.com
[ Upstream commit a00f5276e26636cbf72f24f79831026d2e2868e7 ]
The flakey target is documented to be able to corrupt the Nth byte in a bio, but does not corrupt byte indices after the first biovec in the bio. Change the corrupting function to actually corrupt the Nth byte no matter in which biovec that index falls.
A test device generating two-page bios, atop a flakey device configured to corrupt a byte index on the second page, verified both the failure to corrupt before this patch and the expected corruption after this change.
Signed-off-by: John Dorminy jdorminy@redhat.com Signed-off-by: Mike Snitzer snitzer@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/md/dm-flakey.c | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-)
diff --git a/drivers/md/dm-flakey.c b/drivers/md/dm-flakey.c index 0c1ef63c3461b..b1b68e01b889c 100644 --- a/drivers/md/dm-flakey.c +++ b/drivers/md/dm-flakey.c @@ -282,20 +282,31 @@ static void flakey_map_bio(struct dm_target *ti, struct bio *bio)
static void corrupt_bio_data(struct bio *bio, struct flakey_c *fc) { - unsigned bio_bytes = bio_cur_bytes(bio); - char *data = bio_data(bio); + unsigned int corrupt_bio_byte = fc->corrupt_bio_byte - 1; + + struct bvec_iter iter; + struct bio_vec bvec; + + if (!bio_has_data(bio)) + return;
/* - * Overwrite the Nth byte of the data returned. + * Overwrite the Nth byte of the bio's data, on whichever page + * it falls. */ - if (data && bio_bytes >= fc->corrupt_bio_byte) { - data[fc->corrupt_bio_byte - 1] = fc->corrupt_bio_value; - - DMDEBUG("Corrupting data bio=%p by writing %u to byte %u " - "(rw=%c bi_opf=%u bi_sector=%llu cur_bytes=%u)\n", - bio, fc->corrupt_bio_value, fc->corrupt_bio_byte, - (bio_data_dir(bio) == WRITE) ? 'w' : 'r', bio->bi_opf, - (unsigned long long)bio->bi_iter.bi_sector, bio_bytes); + bio_for_each_segment(bvec, bio, iter) { + if (bio_iter_len(bio, iter) > corrupt_bio_byte) { + char *segment = (page_address(bio_iter_page(bio, iter)) + + bio_iter_offset(bio, iter)); + segment[corrupt_bio_byte] = fc->corrupt_bio_value; + DMDEBUG("Corrupting data bio=%p by writing %u to byte %u " + "(rw=%c bi_opf=%u bi_sector=%llu size=%u)\n", + bio, fc->corrupt_bio_value, fc->corrupt_bio_byte, + (bio_data_dir(bio) == WRITE) ? 'w' : 'r', bio->bi_opf, + (unsigned long long)bio->bi_iter.bi_sector, bio->bi_iter.bi_size); + break; + } + corrupt_bio_byte -= bio_iter_len(bio, iter); } }
From: Bob Peterson rpeterso@redhat.com
[ Upstream commit bc0205612bbd4dd4026d4ba6287f5643c37366ec ]
Before this patch, function do_grow would not reserve enough journal blocks in the transaction to unstuff jdata files while growing them. This patch adds the logic to add one more block if the file to grow is jdata.
Signed-off-by: Bob Peterson rpeterso@redhat.com Reviewed-by: Andreas Gruenbacher agruenba@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/gfs2/bmap.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index 09432b25fe9b8..b3a1b16d4e3e3 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c @@ -1445,6 +1445,8 @@ static int do_grow(struct inode *inode, u64 size) }
error = gfs2_trans_begin(sdp, RES_DINODE + RES_STATFS + RES_RG_BIT + + (unstuff && + gfs2_is_jdata(ip) ? RES_JDATA : 0) + (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF ? 0 : RES_QUOTA), 0); if (error)
From: Nick Bowler nbowler@draconx.ca
[ Upstream commit c456d64449efe37da50832b63d91652a85ea1d20 ]
While inspecting the ioctl implementations, I noticed that the compat implementation of XFS_IOC_ATTRLIST_BY_HANDLE does not do exactly the same thing as the native implementation. Specifically, the "cursor" does not appear to be written out to userspace on the compat path, like it is on the native path.
This adjusts the compat implementation to copy out the cursor just like the native implementation does. The attrlist cursor does not require any special compat handling. This fixes xfstests xfs/269 on both IA-32 and x32 userspace, when running on an amd64 kernel.
Signed-off-by: Nick Bowler nbowler@draconx.ca Fixes: 0facef7fb053b ("xfs: in _attrlist_by_handle, copy the cursor back to userspace") Reviewed-by: Darrick J. Wong darrick.wong@oracle.com Signed-off-by: Darrick J. Wong darrick.wong@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/xfs/xfs_ioctl32.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c index fa0bc4d46065a..d3c0e4b8bf421 100644 --- a/fs/xfs/xfs_ioctl32.c +++ b/fs/xfs/xfs_ioctl32.c @@ -347,6 +347,7 @@ xfs_compat_attrlist_by_handle( { int error; attrlist_cursor_kern_t *cursor; + compat_xfs_fsop_attrlist_handlereq_t __user *p = arg; compat_xfs_fsop_attrlist_handlereq_t al_hreq; struct dentry *dentry; char *kbuf; @@ -381,6 +382,11 @@ xfs_compat_attrlist_by_handle( if (error) goto out_kfree;
+ if (copy_to_user(&p->pos, cursor, sizeof(attrlist_cursor_kern_t))) { + error = -EFAULT; + goto out_kfree; + } + if (copy_to_user(compat_ptr(al_hreq.buffer), kbuf, al_hreq.buflen)) error = -EFAULT;
From: Nick Bowler nbowler@draconx.ca
[ Upstream commit 7ca860e3c1a74ad6bd8949364073ef1044cad758 ]
The bulkstat family of ioctls are problematic on x32, because there is a mixup of native 32-bit and 64-bit conventions. The xfs_fsop_bulkreq struct contains pointers and 32-bit integers so that matches the native 32-bit layout, and that means the ioctl implementation goes into the regular compat path on x32.
However, the 'ubuffer' member of that struct in turn refers to either struct xfs_inogrp or xfs_bstat (or an array of these). On x32, those structures match the native 64-bit layout. The compat implementation writes out the 32-bit version of these structures. This is not the expected format for x32 userspace, causing problems.
Fortunately the functions which actually output these xfs_inogrp and xfs_bstat structures have an easy way to select which output format is required, so we just need a little tweak to select the right format on x32.
Signed-off-by: Nick Bowler nbowler@draconx.ca Reviewed-by: Darrick J. Wong darrick.wong@oracle.com Signed-off-by: Darrick J. Wong darrick.wong@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/xfs/xfs_ioctl32.c | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-)
diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c index d3c0e4b8bf421..5f616a6a5358d 100644 --- a/fs/xfs/xfs_ioctl32.c +++ b/fs/xfs/xfs_ioctl32.c @@ -252,6 +252,32 @@ xfs_compat_ioc_bulkstat( int done; int error;
+ /* + * Output structure handling functions. Depending on the command, + * either the xfs_bstat and xfs_inogrp structures are written out + * to userpace memory via bulkreq.ubuffer. Normally the compat + * functions and structure size are the correct ones to use ... + */ + inumbers_fmt_pf inumbers_func = xfs_inumbers_fmt_compat; + bulkstat_one_pf bs_one_func = xfs_bulkstat_one_compat; + size_t bs_one_size = sizeof(struct compat_xfs_bstat); + +#ifdef CONFIG_X86_X32 + if (in_x32_syscall()) { + /* + * ... but on x32 the input xfs_fsop_bulkreq has pointers + * which must be handled in the "compat" (32-bit) way, while + * the xfs_bstat and xfs_inogrp structures follow native 64- + * bit layout convention. So adjust accordingly, otherwise + * the data written out in compat layout will not match what + * x32 userspace expects. + */ + inumbers_func = xfs_inumbers_fmt; + bs_one_func = xfs_bulkstat_one; + bs_one_size = sizeof(struct xfs_bstat); + } +#endif + /* done = 1 if there are more stats to get and if bulkstat */ /* should be called again (unused here, but used in dmapi) */
@@ -283,15 +309,15 @@ xfs_compat_ioc_bulkstat(
if (cmd == XFS_IOC_FSINUMBERS_32) { error = xfs_inumbers(mp, &inlast, &count, - bulkreq.ubuffer, xfs_inumbers_fmt_compat); + bulkreq.ubuffer, inumbers_func); } else if (cmd == XFS_IOC_FSBULKSTAT_SINGLE_32) { int res;
- error = xfs_bulkstat_one_compat(mp, inlast, bulkreq.ubuffer, - sizeof(compat_xfs_bstat_t), NULL, &res); + error = bs_one_func(mp, inlast, bulkreq.ubuffer, + bs_one_size, NULL, &res); } else if (cmd == XFS_IOC_FSBULKSTAT_32) { error = xfs_bulkstat(mp, &inlast, &count, - xfs_bulkstat_one_compat, sizeof(compat_xfs_bstat_t), + bs_one_func, bs_one_size, bulkreq.ubuffer, &done); } else error = -EINVAL;
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit 5050ae5fa3d54c8e83e1e447cc7e3591110a7f57 ]
We accidentally return success on this error path.
Fixes: f931551bafe1 ("IB/qib: Add new qib driver for QLogic PCIe InfiniBand adapters") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/qib/qib_sdma.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/infiniband/hw/qib/qib_sdma.c b/drivers/infiniband/hw/qib/qib_sdma.c index 891873b38a1e6..5f3f197678b78 100644 --- a/drivers/infiniband/hw/qib/qib_sdma.c +++ b/drivers/infiniband/hw/qib/qib_sdma.c @@ -600,8 +600,10 @@ retry: dw = (len + 3) >> 2; addr = dma_map_single(&ppd->dd->pcidev->dev, sge->vaddr, dw << 2, DMA_TO_DEVICE); - if (dma_mapping_error(&ppd->dd->pcidev->dev, addr)) + if (dma_mapping_error(&ppd->dd->pcidev->dev, addr)) { + ret = -ENOMEM; goto unmap; + } sdmadesc[0] = 0; make_sdma_desc(ppd, sdmadesc, (u64) addr, dw, dwoffset); /* SDmaUseLargeBuf has to be set in every descriptor */
From: Tao Ren taoren@fb.com
[ Upstream commit 86fe57fc47b17b3528fa5497fc57e158d846c4ea ]
TIMER_INTR_MASK register (Base Address of Timer + 0x38) is not designed for masking interrupts on ast2500 chips, and it's not even listed in ast2400 datasheet, so it's not safe to access TIMER_INTR_MASK on aspeed chips.
Similarly, TIMER_INTR_STATE register (Base Address of Timer + 0x34) is not interrupt status register on ast2400 and ast2500 chips. Although there is no side effect to reset the register in fttmr010_common_init(), it's just misleading to do so.
Besides, "count_down" is renamed to "is_aspeed" in "fttmr010" structure, and more comments are added so the code is more readble.
Signed-off-by: Tao Ren taoren@fb.com Reviewed-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Daniel Lezcano daniel.lezcano@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clocksource/timer-fttmr010.c | 73 ++++++++++++++++------------ 1 file changed, 42 insertions(+), 31 deletions(-)
diff --git a/drivers/clocksource/timer-fttmr010.c b/drivers/clocksource/timer-fttmr010.c index cdfe1c82f3f00..3928f3999015e 100644 --- a/drivers/clocksource/timer-fttmr010.c +++ b/drivers/clocksource/timer-fttmr010.c @@ -21,7 +21,7 @@ #include <linux/delay.h>
/* - * Register definitions for the timers + * Register definitions common for all the timer variants. */ #define TIMER1_COUNT (0x00) #define TIMER1_LOAD (0x04) @@ -36,9 +36,10 @@ #define TIMER3_MATCH1 (0x28) #define TIMER3_MATCH2 (0x2c) #define TIMER_CR (0x30) -#define TIMER_INTR_STATE (0x34) -#define TIMER_INTR_MASK (0x38)
+/* + * Control register (TMC30) bit fields for fttmr010/gemini/moxart timers. + */ #define TIMER_1_CR_ENABLE BIT(0) #define TIMER_1_CR_CLOCK BIT(1) #define TIMER_1_CR_INT BIT(2) @@ -53,8 +54,9 @@ #define TIMER_3_CR_UPDOWN BIT(11)
/* - * The Aspeed AST2400 moves bits around in the control register - * and lacks bits for setting the timer to count upwards. + * Control register (TMC30) bit fields for aspeed ast2400/ast2500 timers. + * The aspeed timers move bits around in the control register and lacks + * bits for setting the timer to count upwards. */ #define TIMER_1_CR_ASPEED_ENABLE BIT(0) #define TIMER_1_CR_ASPEED_CLOCK BIT(1) @@ -66,6 +68,18 @@ #define TIMER_3_CR_ASPEED_CLOCK BIT(9) #define TIMER_3_CR_ASPEED_INT BIT(10)
+/* + * Interrupt status/mask register definitions for fttmr010/gemini/moxart + * timers. + * The registers don't exist and they are not needed on aspeed timers + * because: + * - aspeed timer overflow interrupt is controlled by bits in Control + * Register (TMC30). + * - aspeed timers always generate interrupt when either one of the + * Match registers equals to Status register. + */ +#define TIMER_INTR_STATE (0x34) +#define TIMER_INTR_MASK (0x38) #define TIMER_1_INT_MATCH1 BIT(0) #define TIMER_1_INT_MATCH2 BIT(1) #define TIMER_1_INT_OVERFLOW BIT(2) @@ -80,7 +94,7 @@ struct fttmr010 { void __iomem *base; unsigned int tick_rate; - bool count_down; + bool is_aspeed; u32 t1_enable_val; struct clock_event_device clkevt; #ifdef CONFIG_ARM @@ -130,7 +144,7 @@ static int fttmr010_timer_set_next_event(unsigned long cycles, cr &= ~fttmr010->t1_enable_val; writel(cr, fttmr010->base + TIMER_CR);
- if (fttmr010->count_down) { + if (fttmr010->is_aspeed) { /* * ASPEED Timer Controller will load TIMER1_LOAD register * into TIMER1_COUNT register when the timer is re-enabled. @@ -175,16 +189,17 @@ static int fttmr010_timer_set_oneshot(struct clock_event_device *evt)
/* Setup counter start from 0 or ~0 */ writel(0, fttmr010->base + TIMER1_COUNT); - if (fttmr010->count_down) + if (fttmr010->is_aspeed) { writel(~0, fttmr010->base + TIMER1_LOAD); - else + } else { writel(0, fttmr010->base + TIMER1_LOAD);
- /* Enable interrupt */ - cr = readl(fttmr010->base + TIMER_INTR_MASK); - cr &= ~(TIMER_1_INT_OVERFLOW | TIMER_1_INT_MATCH2); - cr |= TIMER_1_INT_MATCH1; - writel(cr, fttmr010->base + TIMER_INTR_MASK); + /* Enable interrupt */ + cr = readl(fttmr010->base + TIMER_INTR_MASK); + cr &= ~(TIMER_1_INT_OVERFLOW | TIMER_1_INT_MATCH2); + cr |= TIMER_1_INT_MATCH1; + writel(cr, fttmr010->base + TIMER_INTR_MASK); + }
return 0; } @@ -201,9 +216,8 @@ static int fttmr010_timer_set_periodic(struct clock_event_device *evt) writel(cr, fttmr010->base + TIMER_CR);
/* Setup timer to fire at 1/HZ intervals. */ - if (fttmr010->count_down) { + if (fttmr010->is_aspeed) { writel(period, fttmr010->base + TIMER1_LOAD); - writel(0, fttmr010->base + TIMER1_MATCH1); } else { cr = 0xffffffff - (period - 1); writel(cr, fttmr010->base + TIMER1_COUNT); @@ -281,23 +295,21 @@ static int __init fttmr010_common_init(struct device_node *np, bool is_aspeed) }
/* - * The Aspeed AST2400 moves bits around in the control register, - * otherwise it works the same. + * The Aspeed timers move bits around in the control register. */ if (is_aspeed) { fttmr010->t1_enable_val = TIMER_1_CR_ASPEED_ENABLE | TIMER_1_CR_ASPEED_INT; - /* Downward not available */ - fttmr010->count_down = true; + fttmr010->is_aspeed = true; } else { fttmr010->t1_enable_val = TIMER_1_CR_ENABLE | TIMER_1_CR_INT; - }
- /* - * Reset the interrupt mask and status - */ - writel(TIMER_INT_ALL_MASK, fttmr010->base + TIMER_INTR_MASK); - writel(0, fttmr010->base + TIMER_INTR_STATE); + /* + * Reset the interrupt mask and status + */ + writel(TIMER_INT_ALL_MASK, fttmr010->base + TIMER_INTR_MASK); + writel(0, fttmr010->base + TIMER_INTR_STATE); + }
/* * Enable timer 1 count up, timer 2 count up, except on Aspeed, @@ -306,9 +318,8 @@ static int __init fttmr010_common_init(struct device_node *np, bool is_aspeed) if (is_aspeed) val = TIMER_2_CR_ASPEED_ENABLE; else { - val = TIMER_2_CR_ENABLE; - if (!fttmr010->count_down) - val |= TIMER_1_CR_UPDOWN | TIMER_2_CR_UPDOWN; + val = TIMER_2_CR_ENABLE | TIMER_1_CR_UPDOWN | + TIMER_2_CR_UPDOWN; } writel(val, fttmr010->base + TIMER_CR);
@@ -321,7 +332,7 @@ static int __init fttmr010_common_init(struct device_node *np, bool is_aspeed) writel(0, fttmr010->base + TIMER2_MATCH1); writel(0, fttmr010->base + TIMER2_MATCH2);
- if (fttmr010->count_down) { + if (fttmr010->is_aspeed) { writel(~0, fttmr010->base + TIMER2_LOAD); clocksource_mmio_init(fttmr010->base + TIMER2_COUNT, "FTTMR010-TIMER2", @@ -371,7 +382,7 @@ static int __init fttmr010_common_init(struct device_node *np, bool is_aspeed)
#ifdef CONFIG_ARM /* Also use this timer for delays */ - if (fttmr010->count_down) + if (fttmr010->is_aspeed) fttmr010->delay_timer.read_current_timer = fttmr010_read_current_timer_down; else
From: Petr Machata petrm@mellanox.com
[ Upstream commit 6db9246871394b3a136cd52001a0763676563840 ]
When a failure occurs in rtnl_configure_link(), the current code calls unregister_netdevice() to roll back the earlier call to register_netdevice(), and jumps to errout, which calls vxlan_fdb_destroy().
However unregister_netdevice() calls transitively ndo_uninit, which is vxlan_uninit(), and that already takes care of deleting the default FDB entry by calling vxlan_fdb_delete_default(). Since the entry added earlier in __vxlan_dev_create() is exactly the default entry, the cleanup code in the errout block always leads to double free and thus a panic.
Besides, since vxlan_fdb_delete_default() always destroys the FDB entry with notification enabled, the deletion of the default entry is notified even before the addition was notified.
Instead, move the unregister_netdevice() call after the manual destroy, which solves both problems.
Fixes: 0241b836732f ("vxlan: fix default fdb entry netlink notify ordering during netdev create") Signed-off-by: Petr Machata petrm@mellanox.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/vxlan.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 6d26bbd190dd6..153a81ece9fe4 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -3217,6 +3217,7 @@ static int __vxlan_dev_create(struct net *net, struct net_device *dev, struct vxlan_net *vn = net_generic(net, vxlan_net_id); struct vxlan_dev *vxlan = netdev_priv(dev); struct vxlan_fdb *f = NULL; + bool unregister = false; int err;
err = vxlan_dev_configure(net, dev, conf, false, extack); @@ -3242,12 +3243,11 @@ static int __vxlan_dev_create(struct net *net, struct net_device *dev, err = register_netdevice(dev); if (err) goto errout; + unregister = true;
err = rtnl_configure_link(dev, NULL); - if (err) { - unregister_netdevice(dev); + if (err) goto errout; - }
/* notify default fdb entry */ if (f) @@ -3255,9 +3255,16 @@ static int __vxlan_dev_create(struct net *net, struct net_device *dev,
list_add(&vxlan->next, &vn->vxlan_list); return 0; + errout: + /* unregister_netdevice() destroys the default FDB entry with deletion + * notification. But the addition notification was not sent yet, so + * destroy the entry by hand here. + */ if (f) vxlan_fdb_destroy(vxlan, f, false); + if (unregister) + unregister_netdevice(dev); return err; }
From: Christophe Leroy christophe.leroy@c-s.fr
[ Upstream commit e93ba1b7eb5b188c749052df7af1c90821c5f320 ]
This patch fixes the loop in p_block_mapped() and v_block_mapped() to scan the entire bat_addrs[] array.
Signed-off-by: Christophe Leroy christophe.leroy@c-s.fr Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/mm/ppc_mmu_32.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/mm/ppc_mmu_32.c b/arch/powerpc/mm/ppc_mmu_32.c index 2a049fb8523d5..96c52271e9c2d 100644 --- a/arch/powerpc/mm/ppc_mmu_32.c +++ b/arch/powerpc/mm/ppc_mmu_32.c @@ -52,7 +52,7 @@ struct batrange { /* stores address ranges mapped by BATs */ phys_addr_t v_block_mapped(unsigned long va) { int b; - for (b = 0; b < 4; ++b) + for (b = 0; b < ARRAY_SIZE(bat_addrs); ++b) if (va >= bat_addrs[b].start && va < bat_addrs[b].limit) return bat_addrs[b].phys + (va - bat_addrs[b].start); return 0; @@ -64,7 +64,7 @@ phys_addr_t v_block_mapped(unsigned long va) unsigned long p_block_mapped(phys_addr_t pa) { int b; - for (b = 0; b < 4; ++b) + for (b = 0; b < ARRAY_SIZE(bat_addrs); ++b) if (pa >= bat_addrs[b].phys && pa < (bat_addrs[b].limit-bat_addrs[b].start) +bat_addrs[b].phys)
From: Christophe Leroy christophe.leroy@c-s.fr
[ Upstream commit 32c8c4c621897199e690760c2d57054f8b84b6e6 ]
mfsrin() takes segment num from bits 31-28 (IBM bits 0-3).
Signed-off-by: Christophe Leroy christophe.leroy@c-s.fr [mpe: Clarify bit numbering] Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/xmon/xmon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index 5a739588aa505..51a53fd517229 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -3293,7 +3293,7 @@ void dump_segments(void)
printf("sr0-15 ="); for (i = 0; i < 16; ++i) - printf(" %x", mfsrin(i)); + printf(" %x", mfsrin(i << 28)); printf("\n"); } #endif
From: Kangjie Lu kjlu@umn.edu
[ Upstream commit 966e927bf8cc6a44f8b72582a1d6d3ffc73b12ad ]
If palmas_smps_read() fails, we should not use the read data in "reg" which may contain random value. The fix inserts a check for the return value of palmas_smps_read(): If it fails, we return the error code upstream and stop using "reg".
Signed-off-by: Kangjie Lu kjlu@umn.edu Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/regulator/palmas-regulator.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index bb5ab7d78895b..c2cc392a27d40 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c @@ -443,13 +443,16 @@ static int palmas_ldo_write(struct palmas *palmas, unsigned int reg, static int palmas_set_mode_smps(struct regulator_dev *dev, unsigned int mode) { int id = rdev_get_id(dev); + int ret; struct palmas_pmic *pmic = rdev_get_drvdata(dev); struct palmas_pmic_driver_data *ddata = pmic->palmas->pmic_ddata; struct palmas_regs_info *rinfo = &ddata->palmas_regs_info[id]; unsigned int reg; bool rail_enable = true;
- palmas_smps_read(pmic->palmas, rinfo->ctrl_addr, ®); + ret = palmas_smps_read(pmic->palmas, rinfo->ctrl_addr, ®); + if (ret) + return ret;
reg &= ~PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK;
From: Jonathan Bakker xc-racer2@live.ca
[ Upstream commit 22bba80500fdf624a7cfbb65fdfa97a038ae224d ]
The Broadcom controller on aries S5PV210 boards sends out a couple of unknown packets after the firmware is loaded. This will cause logging of errors such as: Bluetooth: hci0: Frame reassembly failed (-84)
This is probably also the case with other boards, as there are related Android userspace patches for custom ROMs such as https://review.lineageos.org/#/c/LineageOS/android_system_bt/+/142721/ Since this appears to be intended behaviour, treated them as diagnostic packets.
Note that this is another variant of commit 01d5e44ace8a ("Bluetooth: hci_bcm: Handle empty packet after firmware loading")
Signed-off-by: Jonathan Bakker xc-racer2@live.ca Signed-off-by: Paweł Chmiel pawel.mikolaj.chmiel@gmail.com Signed-off-by: Marcel Holtmann marcel@holtmann.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/bluetooth/hci_bcm.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c index 6d41b2023f09d..61971ddbd2313 100644 --- a/drivers/bluetooth/hci_bcm.c +++ b/drivers/bluetooth/hci_bcm.c @@ -50,6 +50,12 @@ #define BCM_LM_DIAG_PKT 0x07 #define BCM_LM_DIAG_SIZE 63
+#define BCM_TYPE49_PKT 0x31 +#define BCM_TYPE49_SIZE 0 + +#define BCM_TYPE52_PKT 0x34 +#define BCM_TYPE52_SIZE 0 + #define BCM_AUTOSUSPEND_DELAY 5000 /* default autosleep delay */
/* platform device driver resources */ @@ -483,12 +489,28 @@ finalize: .lsize = 0, \ .maxlen = BCM_NULL_SIZE
+#define BCM_RECV_TYPE49 \ + .type = BCM_TYPE49_PKT, \ + .hlen = BCM_TYPE49_SIZE, \ + .loff = 0, \ + .lsize = 0, \ + .maxlen = BCM_TYPE49_SIZE + +#define BCM_RECV_TYPE52 \ + .type = BCM_TYPE52_PKT, \ + .hlen = BCM_TYPE52_SIZE, \ + .loff = 0, \ + .lsize = 0, \ + .maxlen = BCM_TYPE52_SIZE + static const struct h4_recv_pkt bcm_recv_pkts[] = { { H4_RECV_ACL, .recv = hci_recv_frame }, { H4_RECV_SCO, .recv = hci_recv_frame }, { H4_RECV_EVENT, .recv = hci_recv_frame }, { BCM_RECV_LM_DIAG, .recv = hci_recv_diag }, { BCM_RECV_NULL, .recv = hci_recv_diag }, + { BCM_RECV_TYPE49, .recv = hci_recv_diag }, + { BCM_RECV_TYPE52, .recv = hci_recv_diag }, };
static int bcm_recv(struct hci_uart *hu, const void *data, int count)
From: Alexander Shiyan shc_work@mail.ru
[ Upstream commit a8da3c7873ea57acb8f9cea58c0af477522965aa ]
Function max310x_tx_empty() accesses the IRQSTS register, which is cleared by IC when reading, so if there is an interrupt status, we will lose it. This patch implement the transmitter check only by the current FIFO level.
Signed-off-by: Alexander Shiyan shc_work@mail.ru Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/max310x.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c index 0969a0d97b2be..cec995ec11eab 100644 --- a/drivers/tty/serial/max310x.c +++ b/drivers/tty/serial/max310x.c @@ -769,12 +769,9 @@ static void max310x_start_tx(struct uart_port *port)
static unsigned int max310x_tx_empty(struct uart_port *port) { - unsigned int lvl, sts; + u8 lvl = max310x_port_read(port, MAX310X_TXFIFOLVL_REG);
- lvl = max310x_port_read(port, MAX310X_TXFIFOLVL_REG); - sts = max310x_port_read(port, MAX310X_IRQSTS_REG); - - return ((sts & MAX310X_IRQ_TXEMPTY_BIT) && !lvl) ? TIOCSER_TEMT : 0; + return lvl ? 0 : TIOCSER_TEMT; }
static unsigned int max310x_get_mctrl(struct uart_port *port)
From: Geert Uytterhoeven geert@linux-m68k.org
[ Upstream commit 57ce8ba0fd3a95bf29ed741df1c52bd591bf43ff ]
OpenRISC was mainlined as "openrisc", not "or32". vmlinux.lds is generated from vmlinux.lds.S.
Signed-off-by: Geert Uytterhoeven geert@linux-m68k.org Signed-off-by: Stafford Horne shorne@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/openrisc/kernel/entry.S | 2 +- arch/openrisc/kernel/head.S | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/openrisc/kernel/entry.S b/arch/openrisc/kernel/entry.S index b16e95a4e875f..1107d34e45bf1 100644 --- a/arch/openrisc/kernel/entry.S +++ b/arch/openrisc/kernel/entry.S @@ -184,7 +184,7 @@ handler: ;\ * occured. in fact they never do. if you need them use * values saved on stack (for SPR_EPC, SPR_ESR) or content * of r4 (for SPR_EEAR). for details look at EXCEPTION_HANDLE() - * in 'arch/or32/kernel/head.S' + * in 'arch/openrisc/kernel/head.S' */
/* =====================================================[ exceptions] === */ diff --git a/arch/openrisc/kernel/head.S b/arch/openrisc/kernel/head.S index 90979acdf165b..4d878d13b8606 100644 --- a/arch/openrisc/kernel/head.S +++ b/arch/openrisc/kernel/head.S @@ -1551,7 +1551,7 @@ _string_nl:
/* * .data section should be page aligned - * (look into arch/or32/kernel/vmlinux.lds) + * (look into arch/openrisc/kernel/vmlinux.lds.S) */ .section .data,"aw" .align 8192
From: Bart Van Assche bvanassche@acm.org
[ Upstream commit 2ee00f6a98c36f7e4ba07cc33f24cc5a69060cc9 ]
This patch avoids that the SCSI mid-layer keeps retrying forever if ib_post_send() fails. This was discovered while testing immediate data support and passing a too large num_sge value to ib_post_send().
Cc: Sergey Gorenko sergeygo@mellanox.com Cc: Max Gurtovoy maxg@mellanox.com Cc: Laurence Oberman loberman@redhat.com Signed-off-by: Bart Van Assche bvanassche@acm.org Signed-off-by: Doug Ledford dledford@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/ulp/srp/ib_srp.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 3f5b5893792cd..9f7287f45d06f 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -2210,6 +2210,7 @@ static int srp_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmnd)
if (srp_post_send(ch, iu, len)) { shost_printk(KERN_ERR, target->scsi_host, PFX "Send failed\n"); + scmnd->result = DID_ERROR << 16; goto err_unmap; }
From: Anatoliy Glagolev glagolig@gmail.com
[ Upstream commit 17b18eaa6f59044a5172db7d07149e31ede0f920 ]
The intent of invoking configfs_depend_item in commit 7474f52a82d51 ("tcm_qla2xxx: Perform configfs depend/undepend for base_tpg") was to prevent a physical Fibre Channel port removal when virtual (NPIV) ports announced through that physical port are active. The change does not work as expected: it makes enabled physical port dependent on target configfs subsystem (the port's parent), something the configfs guarantees anyway.
Besides, scheduling work in a worker thread and waiting for the work's completion is not really a valid workaround for the requirement not to call configfs_depend_item from a configfs callback: the call occasionally deadlocks.
Thus, removing configfs_depend_item calls does not break anything and fixes the deadlock problem.
Signed-off-by: Anatoliy Glagolev glagolig@gmail.com Acked-by: Himanshu Madhani hmadhani@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qla2xxx/tcm_qla2xxx.c | 48 +++++------------------------- drivers/scsi/qla2xxx/tcm_qla2xxx.h | 3 -- 2 files changed, 8 insertions(+), 43 deletions(-)
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index 2fcdaadd10fa5..e08ac431bc496 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c @@ -903,38 +903,14 @@ static ssize_t tcm_qla2xxx_tpg_enable_show(struct config_item *item, atomic_read(&tpg->lport_tpg_enabled)); }
-static void tcm_qla2xxx_depend_tpg(struct work_struct *work) -{ - struct tcm_qla2xxx_tpg *base_tpg = container_of(work, - struct tcm_qla2xxx_tpg, tpg_base_work); - struct se_portal_group *se_tpg = &base_tpg->se_tpg; - struct scsi_qla_host *base_vha = base_tpg->lport->qla_vha; - - if (!target_depend_item(&se_tpg->tpg_group.cg_item)) { - atomic_set(&base_tpg->lport_tpg_enabled, 1); - qlt_enable_vha(base_vha); - } - complete(&base_tpg->tpg_base_comp); -} - -static void tcm_qla2xxx_undepend_tpg(struct work_struct *work) -{ - struct tcm_qla2xxx_tpg *base_tpg = container_of(work, - struct tcm_qla2xxx_tpg, tpg_base_work); - struct se_portal_group *se_tpg = &base_tpg->se_tpg; - struct scsi_qla_host *base_vha = base_tpg->lport->qla_vha; - - if (!qlt_stop_phase1(base_vha->vha_tgt.qla_tgt)) { - atomic_set(&base_tpg->lport_tpg_enabled, 0); - target_undepend_item(&se_tpg->tpg_group.cg_item); - } - complete(&base_tpg->tpg_base_comp); -} - static ssize_t tcm_qla2xxx_tpg_enable_store(struct config_item *item, const char *page, size_t count) { struct se_portal_group *se_tpg = to_tpg(item); + struct se_wwn *se_wwn = se_tpg->se_tpg_wwn; + struct tcm_qla2xxx_lport *lport = container_of(se_wwn, + struct tcm_qla2xxx_lport, lport_wwn); + struct scsi_qla_host *vha = lport->qla_vha; struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, struct tcm_qla2xxx_tpg, se_tpg); unsigned long op; @@ -953,24 +929,16 @@ static ssize_t tcm_qla2xxx_tpg_enable_store(struct config_item *item, if (atomic_read(&tpg->lport_tpg_enabled)) return -EEXIST;
- INIT_WORK(&tpg->tpg_base_work, tcm_qla2xxx_depend_tpg); + atomic_set(&tpg->lport_tpg_enabled, 1); + qlt_enable_vha(vha); } else { if (!atomic_read(&tpg->lport_tpg_enabled)) return count;
- INIT_WORK(&tpg->tpg_base_work, tcm_qla2xxx_undepend_tpg); + atomic_set(&tpg->lport_tpg_enabled, 0); + qlt_stop_phase1(vha->vha_tgt.qla_tgt); } - init_completion(&tpg->tpg_base_comp); - schedule_work(&tpg->tpg_base_work); - wait_for_completion(&tpg->tpg_base_comp);
- if (op) { - if (!atomic_read(&tpg->lport_tpg_enabled)) - return -ENODEV; - } else { - if (atomic_read(&tpg->lport_tpg_enabled)) - return -EPERM; - } return count; }
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.h b/drivers/scsi/qla2xxx/tcm_qla2xxx.h index 7550ba2831c36..147cf6c903666 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.h +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.h @@ -48,9 +48,6 @@ struct tcm_qla2xxx_tpg { struct tcm_qla2xxx_tpg_attrib tpg_attrib; /* Returned by tcm_qla2xxx_make_tpg() */ struct se_portal_group se_tpg; - /* Items for dealing with configfs_depend_item */ - struct completion tpg_base_comp; - struct work_struct tpg_base_work; };
struct tcm_qla2xxx_fc_loopid {
From: Varun Prakash varun@chelsio.com
[ Upstream commit 9934613edcb40b92a216122876cd3b7e76d08390 ]
In case of ->vport_create() call scsi_add_host_with_dma() instead of scsi_add_host() to pass correct dma device.
Signed-off-by: Varun Prakash varun@chelsio.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/csiostor/csio_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/scsi/csiostor/csio_init.c b/drivers/scsi/csiostor/csio_init.c index 28a9c7d706cb0..03c7b1603dbc1 100644 --- a/drivers/scsi/csiostor/csio_init.c +++ b/drivers/scsi/csiostor/csio_init.c @@ -649,7 +649,7 @@ csio_shost_init(struct csio_hw *hw, struct device *dev, if (csio_lnode_init(ln, hw, pln)) goto err_shost_put;
- if (scsi_add_host(shost, dev)) + if (scsi_add_host_with_dma(shost, dev, &hw->pdev->dev)) goto err_lnode_exit;
return ln;
From: Kyle Roeschley kyle.roeschley@ni.com
[ Upstream commit fb376a495fbdb886f38cfaf5a3805401b9e46f13 ]
Commit dd45b7598f1c ("ath6kl: Include match ssid list in scheduled scan") merged the probed and matched SSID lists before sending them to the firmware. In the process, it assumed match set support is always available in ath6kl_set_probed_ssids, which breaks scans for hidden SSIDs. Now, check that the firmware supports matching SSIDs in scheduled scans before setting MATCH_SSID_FLAG.
Fixes: dd45b7598f1c ("ath6kl: Include match ssid list in scheduled scan") Signed-off-by: Kyle Roeschley kyle.roeschley@ni.com Signed-off-by: Kalle Valo kvalo@codeaurora.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 414b5b596efcd..f790d8021fa17 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -939,7 +939,7 @@ static int ath6kl_set_probed_ssids(struct ath6kl *ar, else ssid_list[i].flag = ANY_SSID_FLAG;
- if (n_match_ssid == 0) + if (ar->wiphy->max_match_sets != 0 && n_match_ssid == 0) ssid_list[i].flag |= MATCH_SSID_FLAG; }
From: Kyle Roeschley kyle.roeschley@ni.com
[ Upstream commit 5803c12816c43bd09e5f4247dd9313c2d9a2c41b ]
When ath6kl was reworked to share code between regular and scheduled scans in commit 3b8ffc6a22ba ("ath6kl: Configure probed SSID list consistently"), probed SSID entry changed from 1-index to 0-indexed. However, ath6kl_cfg80211_scan_complete_event() was missed in that change. Fix its indexing so that we correctly clear out the probed SSID list.
Signed-off-by: Kyle Roeschley kyle.roeschley@ni.com Signed-off-by: Kalle Valo kvalo@codeaurora.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index f790d8021fa17..37deb9bae3643 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -1093,7 +1093,7 @@ void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted) if (vif->scan_req->n_ssids && vif->scan_req->ssids[0].ssid_len) { for (i = 0; i < vif->scan_req->n_ssids; i++) { ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, - i + 1, DISABLE_SSID_FLAG, + i, DISABLE_SSID_FLAG, 0, NULL); } }
From: Madhavan Srinivasan maddy@linux.vnet.ibm.com
[ Upstream commit 2d46d4877b1afd14059393a48bdb8ce27955174c ]
Raw event code has couple of fields "unit" and "cache" in it, to capture the "unit" to monitor for a given pmcxsel and cache reload qualifier to program in MMCR1.
isa207_get_constraint() refers "unit" field to update the MMCRC (L2/L3) Event bus control fields with "cache" bits of the raw event code. These are power8 specific and not supported by PowerISA v3.0 pmu. So wrap the checks to be power8 specific. Also, "cache" bit field is referred to update MMCR1[16:17] and this check can be power8 specific.
Fixes: 7ffd948fae4cd ('powerpc/perf: factor out power8 pmu functions') Signed-off-by: Madhavan Srinivasan maddy@linux.vnet.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/perf/isa207-common.c | 25 ++++++++++++++++++------- arch/powerpc/perf/isa207-common.h | 4 ++-- 2 files changed, 20 insertions(+), 9 deletions(-)
diff --git a/arch/powerpc/perf/isa207-common.c b/arch/powerpc/perf/isa207-common.c index cf9c35aa0cf45..7ecea7143e587 100644 --- a/arch/powerpc/perf/isa207-common.c +++ b/arch/powerpc/perf/isa207-common.c @@ -150,6 +150,14 @@ static bool is_thresh_cmp_valid(u64 event) return true; }
+static unsigned int dc_ic_rld_quad_l1_sel(u64 event) +{ + unsigned int cache; + + cache = (event >> EVENT_CACHE_SEL_SHIFT) & MMCR1_DC_IC_QUAL_MASK; + return cache; +} + static inline u64 isa207_find_source(u64 idx, u32 sub_idx) { u64 ret = PERF_MEM_NA; @@ -290,10 +298,10 @@ int isa207_get_constraint(u64 event, unsigned long *maskp, unsigned long *valp) * have a cache selector of zero. The bank selector (bit 3) is * irrelevant, as long as the rest of the value is 0. */ - if (cache & 0x7) + if (!cpu_has_feature(CPU_FTR_ARCH_300) && (cache & 0x7)) return -1;
- } else if (event & EVENT_IS_L1) { + } else if (cpu_has_feature(CPU_FTR_ARCH_300) || (event & EVENT_IS_L1)) { mask |= CNST_L1_QUAL_MASK; value |= CNST_L1_QUAL_VAL(cache); } @@ -396,11 +404,14 @@ int isa207_compute_mmcr(u64 event[], int n_ev, /* In continuous sampling mode, update SDAR on TLB miss */ mmcra_sdar_mode(event[i], &mmcra);
- if (event[i] & EVENT_IS_L1) { - cache = event[i] >> EVENT_CACHE_SEL_SHIFT; - mmcr1 |= (cache & 1) << MMCR1_IC_QUAL_SHIFT; - cache >>= 1; - mmcr1 |= (cache & 1) << MMCR1_DC_QUAL_SHIFT; + if (cpu_has_feature(CPU_FTR_ARCH_300)) { + cache = dc_ic_rld_quad_l1_sel(event[i]); + mmcr1 |= (cache) << MMCR1_DC_IC_QUAL_SHIFT; + } else { + if (event[i] & EVENT_IS_L1) { + cache = dc_ic_rld_quad_l1_sel(event[i]); + mmcr1 |= (cache) << MMCR1_DC_IC_QUAL_SHIFT; + } }
if (is_event_marked(event[i])) { diff --git a/arch/powerpc/perf/isa207-common.h b/arch/powerpc/perf/isa207-common.h index 6c737d675792e..493e5cc5fa8a6 100644 --- a/arch/powerpc/perf/isa207-common.h +++ b/arch/powerpc/perf/isa207-common.h @@ -232,8 +232,8 @@ #define MMCR1_COMBINE_SHIFT(pmc) (35 - ((pmc) - 1)) #define MMCR1_PMCSEL_SHIFT(pmc) (24 - (((pmc) - 1)) * 8) #define MMCR1_FAB_SHIFT 36 -#define MMCR1_DC_QUAL_SHIFT 47 -#define MMCR1_IC_QUAL_SHIFT 46 +#define MMCR1_DC_IC_QUAL_MASK 0x3 +#define MMCR1_DC_IC_QUAL_SHIFT 46
/* MMCR1 Combine bits macro for power9 */ #define p9_MMCR1_COMBINE_SHIFT(pmc) (38 - ((pmc - 1) * 2))
From: Christophe Leroy christophe.leroy@c-s.fr
[ Upstream commit b18f0ae92b0a1db565c3e505fa87b6971ad3b641 ]
This patch fixes early DEBUG messages in prom.c: - Use %px instead of %p to see the addresses - Cast memblock_phys_mem_size() with (unsigned long long) to avoid build failure when phys_addr_t is not 64 bits.
Signed-off-by: Christophe Leroy christophe.leroy@c-s.fr Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/kernel/prom.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index f830562974417..d96b284150904 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -128,7 +128,7 @@ static void __init move_device_tree(void) p = __va(memblock_alloc(size, PAGE_SIZE)); memcpy(p, initial_boot_params, size); initial_boot_params = p; - DBG("Moved device tree to 0x%p\n", p); + DBG("Moved device tree to 0x%px\n", p); }
DBG("<- move_device_tree\n"); @@ -662,7 +662,7 @@ void __init early_init_devtree(void *params) { phys_addr_t limit;
- DBG(" -> early_init_devtree(%p)\n", params); + DBG(" -> early_init_devtree(%px)\n", params);
/* Too early to BUG_ON(), do it by hand */ if (!early_init_dt_verify(params)) @@ -722,7 +722,7 @@ void __init early_init_devtree(void *params) memblock_allow_resize(); memblock_dump_all();
- DBG("Phys. mem: %llx\n", memblock_phys_mem_size()); + DBG("Phys. mem: %llx\n", (unsigned long long)memblock_phys_mem_size());
/* We may need to relocate the flat tree, do it now. * FIXME .. and the initrd too? */
From: Christophe Leroy christophe.leroy@c-s.fr
[ Upstream commit 49a502ea23bf9dec47f8f3c3960909ff409cd1bb ]
As several other arches including x86, this patch makes it explicit that a bad page fault is a NULL pointer dereference when the fault address is lower than PAGE_SIZE
In the mean time, this page makes all bad_page_fault() messages shorter so that they remain on one single line. And it prefixes them by "BUG: " so that they get easily grepped.
Signed-off-by: Christophe Leroy christophe.leroy@c-s.fr [mpe: Avoid pr_cont()] Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/mm/fault.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c index 52863deed65df..5fc8a010fdf07 100644 --- a/arch/powerpc/mm/fault.c +++ b/arch/powerpc/mm/fault.c @@ -581,21 +581,22 @@ void bad_page_fault(struct pt_regs *regs, unsigned long address, int sig) switch (regs->trap) { case 0x300: case 0x380: - printk(KERN_ALERT "Unable to handle kernel paging request for " - "data at address 0x%08lx\n", regs->dar); + pr_alert("BUG: %s at 0x%08lx\n", + regs->dar < PAGE_SIZE ? "Kernel NULL pointer dereference" : + "Unable to handle kernel data access", regs->dar); break; case 0x400: case 0x480: - printk(KERN_ALERT "Unable to handle kernel paging request for " - "instruction fetch\n"); + pr_alert("BUG: Unable to handle kernel instruction fetch%s", + regs->nip < PAGE_SIZE ? " (NULL pointer?)\n" : "\n"); break; case 0x600: - printk(KERN_ALERT "Unable to handle kernel paging request for " - "unaligned access at address 0x%08lx\n", regs->dar); + pr_alert("BUG: Unable to handle kernel unaligned access at 0x%08lx\n", + regs->dar); break; default: - printk(KERN_ALERT "Unable to handle kernel paging request for " - "unknown fault\n"); + pr_alert("BUG: Unable to handle unknown paging fault at 0x%08lx\n", + regs->dar); break; } printk(KERN_ALERT "Faulting instruction address: 0x%08lx\n",
From: Benjamin Herrenschmidt benh@kernel.crashing.org
[ Upstream commit 3cfb9ebe906b51f2942b1e251009bb251efd2ba6 ]
The bamboo dts has a bug: it uses a non-naturally aligned range for PCI memory space. This isnt' supported by the code, thus causing PCI to break on this system.
This is due to the fact that while the chip memory map has 1G reserved for PCI memory, it's only 512M aligned. The code doesn't know how to split that into 2 different PMMs and fails, so limit the region to 512M.
Signed-off-by: Benjamin Herrenschmidt benh@kernel.crashing.org Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/boot/dts/bamboo.dts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/boot/dts/bamboo.dts b/arch/powerpc/boot/dts/bamboo.dts index aa68911f6560a..084b82ba74933 100644 --- a/arch/powerpc/boot/dts/bamboo.dts +++ b/arch/powerpc/boot/dts/bamboo.dts @@ -268,8 +268,10 @@ /* Outbound ranges, one memory and one IO, * later cannot be changed. Chip supports a second * IO range but we don't use it for now + * The chip also supports a larger memory range but + * it's not naturally aligned, so our code will break */ - ranges = <0x02000000 0x00000000 0xa0000000 0x00000000 0xa0000000 0x00000000 0x40000000 + ranges = <0x02000000 0x00000000 0xa0000000 0x00000000 0xa0000000 0x00000000 0x20000000 0x02000000 0x00000000 0x00000000 0x00000000 0xe0000000 0x00000000 0x00100000 0x01000000 0x00000000 0x00000000 0x00000000 0xe8000000 0x00000000 0x00010000>;
From: Alexey Kardashevskiy aik@ozlabs.ru
[ Upstream commit 517ad4ae8aa93dccdb9a88c27257ecb421c9e848 ]
As a part of cleanup, the SPAPR TCE IOMMU subdriver releases preregistered memory. If there is a bug in memory release, the loop in tce_iommu_release() becomes infinite; this actually happened to me.
This makes the loop finite and prints a warning on every failure to make the code more bug prone.
Signed-off-by: Alexey Kardashevskiy aik@ozlabs.ru Reviewed-by: David Gibson david@gibson.dropbear.id.au Acked-by: Alex Williamson alex.williamson@redhat.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/vfio/vfio_iommu_spapr_tce.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/drivers/vfio/vfio_iommu_spapr_tce.c b/drivers/vfio/vfio_iommu_spapr_tce.c index b4c68f3b82be9..eba9aaf3cc17c 100644 --- a/drivers/vfio/vfio_iommu_spapr_tce.c +++ b/drivers/vfio/vfio_iommu_spapr_tce.c @@ -409,6 +409,7 @@ static void tce_iommu_release(void *iommu_data) { struct tce_container *container = iommu_data; struct tce_iommu_group *tcegrp; + struct tce_iommu_prereg *tcemem, *tmtmp; long i;
while (tce_groups_attached(container)) { @@ -431,13 +432,8 @@ static void tce_iommu_release(void *iommu_data) tce_iommu_free_table(container, tbl); }
- while (!list_empty(&container->prereg_list)) { - struct tce_iommu_prereg *tcemem; - - tcemem = list_first_entry(&container->prereg_list, - struct tce_iommu_prereg, next); - WARN_ON_ONCE(tce_iommu_prereg_free(container, tcemem)); - } + list_for_each_entry_safe(tcemem, tmtmp, &container->prereg_list, next) + WARN_ON(tce_iommu_prereg_free(container, tcemem));
tce_iommu_disable(container); if (container->mm)
From: Alexey Kardashevskiy aik@ozlabs.ru
[ Upstream commit c20577014f85f36d4e137d3d52a1f61225b4a3d2 ]
The current implementation of the OPAL_PCI_EEH_FREEZE_STATUS call in skiboot's NPU driver does not touch the pci_error_type parameter so it might have garbage but the powernv code analyzes it nevertheless.
This initializes pcierr and fstate to zero in all call sites.
Signed-off-by: Alexey Kardashevskiy aik@ozlabs.ru Reviewed-by: Sam Bobroff sbobroff@linux.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/platforms/powernv/eeh-powernv.c | 8 ++++---- arch/powerpc/platforms/powernv/pci-ioda.c | 4 ++-- arch/powerpc/platforms/powernv/pci.c | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c index 8864065eba227..fa2965c96155b 100644 --- a/arch/powerpc/platforms/powernv/eeh-powernv.c +++ b/arch/powerpc/platforms/powernv/eeh-powernv.c @@ -548,8 +548,8 @@ static void pnv_eeh_get_phb_diag(struct eeh_pe *pe) static int pnv_eeh_get_phb_state(struct eeh_pe *pe) { struct pnv_phb *phb = pe->phb->private_data; - u8 fstate; - __be16 pcierr; + u8 fstate = 0; + __be16 pcierr = 0; s64 rc; int result = 0;
@@ -587,8 +587,8 @@ static int pnv_eeh_get_phb_state(struct eeh_pe *pe) static int pnv_eeh_get_pe_state(struct eeh_pe *pe) { struct pnv_phb *phb = pe->phb->private_data; - u8 fstate; - __be16 pcierr; + u8 fstate = 0; + __be16 pcierr = 0; s64 rc; int result;
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index ddef22e00ddd7..d3d5796f7df60 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -598,8 +598,8 @@ static int pnv_ioda_unfreeze_pe(struct pnv_phb *phb, int pe_no, int opt) static int pnv_ioda_get_pe_state(struct pnv_phb *phb, int pe_no) { struct pnv_ioda_pe *slave, *pe; - u8 fstate, state; - __be16 pcierr; + u8 fstate = 0, state; + __be16 pcierr = 0; s64 rc;
/* Sanity check on PE number */ diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index 5422f4a6317ca..e2d031a3ec157 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c @@ -600,8 +600,8 @@ static void pnv_pci_handle_eeh_config(struct pnv_phb *phb, u32 pe_no) static void pnv_pci_config_check_eeh(struct pci_dn *pdn) { struct pnv_phb *phb = pdn->phb->private_data; - u8 fstate; - __be16 pcierr; + u8 fstate = 0; + __be16 pcierr = 0; unsigned int pe_no; s64 rc;
From: Lars Ellenberg lars.ellenberg@linbit.com
[ Upstream commit 94c43a13b8d6e3e0dd77b3536b5e04a84936b762 ]
During handshake, if we are diskless ourselves, we used to accept any size presented by the peer.
Which could be zero if that peer was just brought up and connected to us without having a disk attached first, in which case both peers would just "flip" their volume sizes.
Now, even a diskless node will ignore "zero" sizes presented by a diskless peer.
Also a currently Diskless Primary will refuse to shrink during handshake: it may be frozen, and waiting for a "suitable" local disk or peer to re-appear (on-no-data-accessible suspend-io). If the peer is smaller than what we used to be, it is not suitable.
The logic for a diskless node during handshake is now supposed to be: believe the peer, if - I don't have a current size myself - we agree on the size anyways - I do have a current size, am Secondary, and he has the only disk - I do have a current size, am Primary, and he has the only disk, which is larger than my current size
Signed-off-by: Lars Ellenberg lars.ellenberg@linbit.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/block/drbd/drbd_receiver.c | 33 +++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-)
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index 8fbdfaacc2226..08586bc5219bf 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -3977,6 +3977,7 @@ static int receive_sizes(struct drbd_connection *connection, struct packet_info struct o_qlim *o = (connection->agreed_features & DRBD_FF_WSAME) ? p->qlim : NULL; enum determine_dev_size dd = DS_UNCHANGED; sector_t p_size, p_usize, p_csize, my_usize; + sector_t new_size, cur_size; int ldsc = 0; /* local disk size changed */ enum dds_flags ddsf;
@@ -3984,6 +3985,7 @@ static int receive_sizes(struct drbd_connection *connection, struct packet_info if (!peer_device) return config_unknown_volume(connection, pi); device = peer_device->device; + cur_size = drbd_get_capacity(device->this_bdev);
p_size = be64_to_cpu(p->d_size); p_usize = be64_to_cpu(p->u_size); @@ -3994,7 +3996,6 @@ static int receive_sizes(struct drbd_connection *connection, struct packet_info device->p_size = p_size;
if (get_ldev(device)) { - sector_t new_size, cur_size; rcu_read_lock(); my_usize = rcu_dereference(device->ldev->disk_conf)->disk_size; rcu_read_unlock(); @@ -4012,7 +4013,6 @@ static int receive_sizes(struct drbd_connection *connection, struct packet_info /* Never shrink a device with usable data during connect. But allow online shrinking if we are connected. */ new_size = drbd_new_dev_size(device, device->ldev, p_usize, 0); - cur_size = drbd_get_capacity(device->this_bdev); if (new_size < cur_size && device->state.disk >= D_OUTDATED && device->state.conn < C_CONNECTED) { @@ -4077,9 +4077,36 @@ static int receive_sizes(struct drbd_connection *connection, struct packet_info * * However, if he sends a zero current size, * take his (user-capped or) backing disk size anyways. + * + * Unless of course he does not have a disk himself. + * In which case we ignore this completely. */ + sector_t new_size = p_csize ?: p_usize ?: p_size; drbd_reconsider_queue_parameters(device, NULL, o); - drbd_set_my_capacity(device, p_csize ?: p_usize ?: p_size); + if (new_size == 0) { + /* Ignore, peer does not know nothing. */ + } else if (new_size == cur_size) { + /* nothing to do */ + } else if (cur_size != 0 && p_size == 0) { + drbd_warn(device, "Ignored diskless peer device size (peer:%llu != me:%llu sectors)!\n", + (unsigned long long)new_size, (unsigned long long)cur_size); + } else if (new_size < cur_size && device->state.role == R_PRIMARY) { + drbd_err(device, "The peer's device size is too small! (%llu < %llu sectors); demote me first!\n", + (unsigned long long)new_size, (unsigned long long)cur_size); + conn_request_state(peer_device->connection, NS(conn, C_DISCONNECTING), CS_HARD); + return -EIO; + } else { + /* I believe the peer, if + * - I don't have a current size myself + * - we agree on the size anyways + * - I do have a current size, am Secondary, + * and he has the only disk + * - I do have a current size, am Primary, + * and he has the only disk, + * which is larger than my current size + */ + drbd_set_my_capacity(device, new_size); + } }
if (get_ldev(device)) {
From: Lars Ellenberg lars.ellenberg@linbit.com
[ Upstream commit fe43ed97bba3b11521abd934b83ed93143470e4f ]
Multiple failure scenario: a) all good Connected Primary/Secondary UpToDate/UpToDate b) lose disk on Primary, Connected Primary/Secondary Diskless/UpToDate c) continue to write to the device, changes only make it to the Secondary storage. d) lose disk on Secondary, Connected Primary/Secondary Diskless/Diskless e) now try to re-attach on Primary
This would have succeeded before, even though that is clearly the wrong data set to attach to (missing the modifications from c). Because we only compared our "effective" and the "to-be-attached" data generation uuid tags if (device->state.conn < C_CONNECTED).
Fix: change that constraint to (device->state.pdsk != D_UP_TO_DATE) compare the uuids, and reject the attach.
This patch also tries to improve the reverse scenario: first lose Secondary, then Primary disk, then try to attach the disk on Secondary.
Before this patch, the attach on the Secondary succeeds, but since commit drbd: disconnect, if the wrong UUIDs are attached on a connected peer the Primary will notice unsuitable data, and drop the connection hard.
Though unfortunately at a point in time during the handshake where we cannot easily abort the attach on the peer without more refactoring of the handshake.
We now reject any attach to "unsuitable" uuids, as long as we can see a Primary role, unless we already have access to "good" data.
Signed-off-by: Lars Ellenberg lars.ellenberg@linbit.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/block/drbd/drbd_nl.c | 6 +++--- drivers/block/drbd/drbd_receiver.c | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-)
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index ad13ec66c8e4d..a675a0f61f9c0 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c @@ -1935,9 +1935,9 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info) } }
- if (device->state.conn < C_CONNECTED && - device->state.role == R_PRIMARY && device->ed_uuid && - (device->ed_uuid & ~((u64)1)) != (nbc->md.uuid[UI_CURRENT] & ~((u64)1))) { + if (device->state.pdsk != D_UP_TO_DATE && device->ed_uuid && + (device->state.role == R_PRIMARY || device->state.peer == R_PRIMARY) && + (device->ed_uuid & ~((u64)1)) != (nbc->md.uuid[UI_CURRENT] & ~((u64)1))) { drbd_err(device, "Can only attach to data with current UUID=%016llX\n", (unsigned long long)device->ed_uuid); retcode = ERR_DATA_NOT_CURRENT; diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index 08586bc5219bf..a7c180426c601 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -4392,6 +4392,25 @@ static int receive_state(struct drbd_connection *connection, struct packet_info if (peer_state.conn == C_AHEAD) ns.conn = C_BEHIND;
+ /* TODO: + * if (primary and diskless and peer uuid != effective uuid) + * abort attach on peer; + * + * If this node does not have good data, was already connected, but + * the peer did a late attach only now, trying to "negotiate" with me, + * AND I am currently Primary, possibly frozen, with some specific + * "effective" uuid, this should never be reached, really, because + * we first send the uuids, then the current state. + * + * In this scenario, we already dropped the connection hard + * when we received the unsuitable uuids (receive_uuids(). + * + * Should we want to change this, that is: not drop the connection in + * receive_uuids() already, then we would need to add a branch here + * that aborts the attach of "unsuitable uuids" on the peer in case + * this node is currently Diskless Primary. + */ + if (device->p_uuid && peer_state.disk >= D_NEGOTIATING && get_ldev_if_state(device, D_NEGOTIATING)) { int cr; /* consider resync */
From: Lars Ellenberg lars.ellenberg@linbit.com
[ Upstream commit f708bd08ecbdc23d03aaedf5b3311ebe44cfdb50 ]
"suspending" IO is overloaded. It can mean "do not allow new requests" (obviously), but it also may mean "must not complete pending IO", for example while the fencing handlers do their arbitration.
When adjusting disk options, we suspend io (disallow new requests), then wait for the activity-log to become unused (drain all IO completions), and possibly replace it with a new activity log of different size.
If the other "suspend IO" aspect is active, pending IO completions won't happen, and we would block forever (unkillable drbdsetup process).
Fix this by skipping the activity log adjustment if the "al-extents" setting did not change. Also, in case it did change, fail early without blocking if it looks like we would block forever.
Signed-off-by: Lars Ellenberg lars.ellenberg@linbit.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/block/drbd/drbd_nl.c | 37 ++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-)
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index a675a0f61f9c0..31d7fe4480afd 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c @@ -1515,6 +1515,30 @@ static void sanitize_disk_conf(struct drbd_device *device, struct disk_conf *dis } }
+static int disk_opts_check_al_size(struct drbd_device *device, struct disk_conf *dc) +{ + int err = -EBUSY; + + if (device->act_log && + device->act_log->nr_elements == dc->al_extents) + return 0; + + drbd_suspend_io(device); + /* If IO completion is currently blocked, we would likely wait + * "forever" for the activity log to become unused. So we don't. */ + if (atomic_read(&device->ap_bio_cnt)) + goto out; + + wait_event(device->al_wait, lc_try_lock(device->act_log)); + drbd_al_shrink(device); + err = drbd_check_al_size(device, dc); + lc_unlock(device->act_log); + wake_up(&device->al_wait); +out: + drbd_resume_io(device); + return err; +} + int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info) { struct drbd_config_context adm_ctx; @@ -1577,15 +1601,12 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info) } }
- drbd_suspend_io(device); - wait_event(device->al_wait, lc_try_lock(device->act_log)); - drbd_al_shrink(device); - err = drbd_check_al_size(device, new_disk_conf); - lc_unlock(device->act_log); - wake_up(&device->al_wait); - drbd_resume_io(device); - + err = disk_opts_check_al_size(device, new_disk_conf); if (err) { + /* Could be just "busy". Ignore? + * Introduce dedicated error code? */ + drbd_msg_put_info(adm_ctx.reply_skb, + "Try again without changing current al-extents setting"); retcode = ERR_NOMEM; goto fail_unlock; }
From: Luc Van Oostenryck luc.vanoostenryck@gmail.com
[ Upstream commit 2c38f035117331eb78d0504843c79ea7c7fabf37 ]
print_st_err() is defined with its 4th argument taking an 'enum drbd_state_rv' but its prototype use an int for it.
Fix this by using 'enum drbd_state_rv' in the prototype too.
Signed-off-by: Luc Van Oostenryck luc.vanoostenryck@gmail.com Signed-off-by: Roland Kammerer roland.kammerer@linbit.com Signed-off-by: Lars Ellenberg lars.ellenberg@linbit.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/block/drbd/drbd_state.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/block/drbd/drbd_state.h b/drivers/block/drbd/drbd_state.h index ea58301d0895c..b2a390ba73a05 100644 --- a/drivers/block/drbd/drbd_state.h +++ b/drivers/block/drbd/drbd_state.h @@ -131,7 +131,7 @@ extern enum drbd_state_rv _drbd_set_state(struct drbd_device *, union drbd_state enum chg_state_flags, struct completion *done); extern void print_st_err(struct drbd_device *, union drbd_state, - union drbd_state, int); + union drbd_state, enum drbd_state_rv);
enum drbd_state_rv _conn_request_state(struct drbd_connection *connection, union drbd_state mask, union drbd_state val,
From: Parav Pandit parav@mellanox.com
[ Upstream commit d5108e69fe013ff47ab815b849caba9cc33ca1e5 ]
Current rxe device counters are not thread safe. When multiple QPs are used, they can be racy. Make them thread safe by making it atomic64.
Fixes: 0b1e5b99a48b ("IB/rxe: Add port protocol stats") Signed-off-by: Parav Pandit parav@mellanox.com Signed-off-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/sw/rxe/rxe_hw_counters.c | 2 +- drivers/infiniband/sw/rxe/rxe_verbs.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/infiniband/sw/rxe/rxe_hw_counters.c b/drivers/infiniband/sw/rxe/rxe_hw_counters.c index 6aeb7a165e469..ea4542a9d69e6 100644 --- a/drivers/infiniband/sw/rxe/rxe_hw_counters.c +++ b/drivers/infiniband/sw/rxe/rxe_hw_counters.c @@ -59,7 +59,7 @@ int rxe_ib_get_hw_stats(struct ib_device *ibdev, return -EINVAL;
for (cnt = 0; cnt < ARRAY_SIZE(rxe_counter_name); cnt++) - stats->value[cnt] = dev->stats_counters[cnt]; + stats->value[cnt] = atomic64_read(&dev->stats_counters[cnt]);
return ARRAY_SIZE(rxe_counter_name); } diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.h b/drivers/infiniband/sw/rxe/rxe_verbs.h index b2b76a316ebae..d1cc89f6f2e33 100644 --- a/drivers/infiniband/sw/rxe/rxe_verbs.h +++ b/drivers/infiniband/sw/rxe/rxe_verbs.h @@ -410,16 +410,16 @@ struct rxe_dev { spinlock_t mmap_offset_lock; /* guard mmap_offset */ int mmap_offset;
- u64 stats_counters[RXE_NUM_OF_COUNTERS]; + atomic64_t stats_counters[RXE_NUM_OF_COUNTERS];
struct rxe_port port; struct list_head list; struct crypto_shash *tfm; };
-static inline void rxe_counter_inc(struct rxe_dev *rxe, enum rxe_counters cnt) +static inline void rxe_counter_inc(struct rxe_dev *rxe, enum rxe_counters index) { - rxe->stats_counters[cnt]++; + atomic64_inc(&rxe->stats_counters[index]); }
static inline struct rxe_dev *to_rdev(struct ib_device *dev)
From: Kangjie Lu kjlu@umn.edu
[ Upstream commit cd07e3701fa6a4c68f8493ee1d12caa18d46ec6a ]
tps65910_reg_set_bits() may fail. The fix checks if it fails, and if so, returns with its error code.
Signed-off-by: Kangjie Lu kjlu@umn.edu Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/regulator/tps65910-regulator.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index 81672a58fcc23..194fa0cbbc048 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c @@ -1102,8 +1102,10 @@ static int tps65910_probe(struct platform_device *pdev) platform_set_drvdata(pdev, pmic);
/* Give control of all register to control port */ - tps65910_reg_set_bits(pmic->mfd, TPS65910_DEVCTRL, + err = tps65910_reg_set_bits(pmic->mfd, TPS65910_DEVCTRL, DEVCTRL_SR_CTL_I2C_SEL_MASK); + if (err < 0) + return err;
switch (tps65910_chip_id(tps65910)) { case TPS65910:
From: Christophe Leroy christophe.leroy@c-s.fr
[ Upstream commit 0deae39cec6dab3a66794f3e9e83ca4dc30080f1 ]
When the watchdog timer is set in interrupt mode, it causes a machine check when it times out. The purpose of this mode is to ease debugging, not to crash the kernel and reboot the machine.
This patch implements a special handling for that, in order to not crash the kernel if the watchdog times out while in interrupt or within the idle task.
Signed-off-by: Christophe Leroy christophe.leroy@c-s.fr [scottwood: added missing #include] Signed-off-by: Scott Wood oss@buserror.net Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/include/asm/cputable.h | 1 + arch/powerpc/include/asm/reg.h | 2 ++ arch/powerpc/kernel/cputable.c | 10 ++++++---- arch/powerpc/platforms/83xx/misc.c | 17 +++++++++++++++++ 4 files changed, 26 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h index 7e3ccf21830e6..e4451b30d7e32 100644 --- a/arch/powerpc/include/asm/cputable.h +++ b/arch/powerpc/include/asm/cputable.h @@ -45,6 +45,7 @@ extern int machine_check_e500(struct pt_regs *regs); extern int machine_check_e200(struct pt_regs *regs); extern int machine_check_47x(struct pt_regs *regs); int machine_check_8xx(struct pt_regs *regs); +int machine_check_83xx(struct pt_regs *regs);
extern void cpu_down_flush_e500v2(void); extern void cpu_down_flush_e500mc(void); diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index b779f3ccd4126..05f3c2b3aa0ec 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h @@ -733,6 +733,8 @@ #define SRR1_PROGTRAP 0x00020000 /* Trap */ #define SRR1_PROGADDR 0x00010000 /* SRR0 contains subsequent addr */
+#define SRR1_MCE_MCP 0x00080000 /* Machine check signal caused interrupt */ + #define SPRN_HSRR0 0x13A /* Save/Restore Register 0 */ #define SPRN_HSRR1 0x13B /* Save/Restore Register 1 */ #define HSRR1_DENORM 0x00100000 /* Denorm exception */ diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 760872916013d..da4b0e3792380 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -1185,6 +1185,7 @@ static struct cpu_spec __initdata cpu_specs[] = { .machine_check = machine_check_generic, .platform = "ppc603", }, +#ifdef CONFIG_PPC_83xx { /* e300c1 (a 603e core, plus some) on 83xx */ .pvr_mask = 0x7fff0000, .pvr_value = 0x00830000, @@ -1195,7 +1196,7 @@ static struct cpu_spec __initdata cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .cpu_setup = __setup_cpu_603, - .machine_check = machine_check_generic, + .machine_check = machine_check_83xx, .platform = "ppc603", }, { /* e300c2 (an e300c1 core, plus some, minus FPU) on 83xx */ @@ -1209,7 +1210,7 @@ static struct cpu_spec __initdata cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .cpu_setup = __setup_cpu_603, - .machine_check = machine_check_generic, + .machine_check = machine_check_83xx, .platform = "ppc603", }, { /* e300c3 (e300c1, plus one IU, half cache size) on 83xx */ @@ -1223,7 +1224,7 @@ static struct cpu_spec __initdata cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .cpu_setup = __setup_cpu_603, - .machine_check = machine_check_generic, + .machine_check = machine_check_83xx, .num_pmcs = 4, .oprofile_cpu_type = "ppc/e300", .oprofile_type = PPC_OPROFILE_FSL_EMB, @@ -1240,12 +1241,13 @@ static struct cpu_spec __initdata cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .cpu_setup = __setup_cpu_603, - .machine_check = machine_check_generic, + .machine_check = machine_check_83xx, .num_pmcs = 4, .oprofile_cpu_type = "ppc/e300", .oprofile_type = PPC_OPROFILE_FSL_EMB, .platform = "ppc603", }, +#endif { /* default match, we assume split I/D cache & TB (non-601)... */ .pvr_mask = 0x00000000, .pvr_value = 0x00000000, diff --git a/arch/powerpc/platforms/83xx/misc.c b/arch/powerpc/platforms/83xx/misc.c index d75c9816a5c92..2b6589fe812dd 100644 --- a/arch/powerpc/platforms/83xx/misc.c +++ b/arch/powerpc/platforms/83xx/misc.c @@ -14,6 +14,7 @@ #include <linux/of_platform.h> #include <linux/pci.h>
+#include <asm/debug.h> #include <asm/io.h> #include <asm/hw_irq.h> #include <asm/ipic.h> @@ -150,3 +151,19 @@ void __init mpc83xx_setup_arch(void)
mpc83xx_setup_pci(); } + +int machine_check_83xx(struct pt_regs *regs) +{ + u32 mask = 1 << (31 - IPIC_MCP_WDT); + + if (!(regs->msr & SRR1_MCE_MCP) || !(ipic_get_mcp_status() & mask)) + return machine_check_generic(regs); + ipic_clear_mcp_status(mask); + + if (debugger_fault_handler(regs)) + return 1; + + die("Watchdog NMI Reset", regs, 0); + + return 1; +}
From: Michael Ellerman mpe@ellerman.id.au
[ Upstream commit 47918bc68b7427e961035949cc1501a864578a69 ]
In update_lmb_associativity_index() we lookup dr_node using of_find_node_by_path() which takes a reference for us. In the non-error case we forget to drop the reference. Note that find_aa_index() does modify properties of the node, but doesn't need an extra reference held once it's returned.
Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/platforms/pseries/hotplug-memory.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c index 99a3cf51c5ba4..fdfce7a46d733 100644 --- a/arch/powerpc/platforms/pseries/hotplug-memory.c +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c @@ -295,6 +295,7 @@ static u32 lookup_lmb_associativity_index(struct of_drconf_cell *lmb)
aa_index = find_aa_index(dr_node, ala_prop, lmb_assoc);
+ of_node_put(dr_node); dlpar_free_cc_nodes(lmb_node); return aa_index; }
From: Fabio Estevam festevam@gmail.com
[ Upstream commit 2326828ee40357b3d2b1359b8ca7526af201495b ]
The following build warnings are seen when building for ARM64 allmodconfig:
drivers/crypto/mxc-scc.c:181:20: warning: format '%d' expects argument of type 'int', but argument 5 has type 'size_t' {aka 'long unsigned int'} [-Wformat=] drivers/crypto/mxc-scc.c:186:21: warning: format '%d' expects argument of type 'int', but argument 4 has type 'size_t' {aka 'long unsigned int'} [-Wformat=] drivers/crypto/mxc-scc.c:277:21: warning: format '%d' expects argument of type 'int', but argument 4 has type 'size_t' {aka 'long unsigned int'} [-Wformat=] drivers/crypto/mxc-scc.c:339:3: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] drivers/crypto/mxc-scc.c:340:3: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
Fix them by using the %zu specifier to print a size_t variable and using a plain %x to print the result of a readl().
Signed-off-by: Fabio Estevam festevam@gmail.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/mxc-scc.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/crypto/mxc-scc.c b/drivers/crypto/mxc-scc.c index e01c46387df8d..519086730791b 100644 --- a/drivers/crypto/mxc-scc.c +++ b/drivers/crypto/mxc-scc.c @@ -178,12 +178,12 @@ static int mxc_scc_get_data(struct mxc_scc_ctx *ctx, else from = scc->black_memory;
- dev_dbg(scc->dev, "pcopy: from 0x%p %d bytes\n", from, + dev_dbg(scc->dev, "pcopy: from 0x%p %zu bytes\n", from, ctx->dst_nents * 8); len = sg_pcopy_from_buffer(ablkreq->dst, ctx->dst_nents, from, ctx->size, ctx->offset); if (!len) { - dev_err(scc->dev, "pcopy err from 0x%p (len=%d)\n", from, len); + dev_err(scc->dev, "pcopy err from 0x%p (len=%zu)\n", from, len); return -EINVAL; }
@@ -274,7 +274,7 @@ static int mxc_scc_put_data(struct mxc_scc_ctx *ctx, len = sg_pcopy_to_buffer(req->src, ctx->src_nents, to, len, ctx->offset); if (!len) { - dev_err(scc->dev, "pcopy err to 0x%p (len=%d)\n", to, len); + dev_err(scc->dev, "pcopy err to 0x%p (len=%zu)\n", to, len); return -EINVAL; }
@@ -335,9 +335,9 @@ static void mxc_scc_ablkcipher_next(struct mxc_scc_ctx *ctx, return; }
- dev_dbg(scc->dev, "Start encryption (0x%p/0x%p)\n", - (void *)readl(scc->base + SCC_SCM_RED_START), - (void *)readl(scc->base + SCC_SCM_BLACK_START)); + dev_dbg(scc->dev, "Start encryption (0x%x/0x%x)\n", + readl(scc->base + SCC_SCM_RED_START), + readl(scc->base + SCC_SCM_BLACK_START));
/* clear interrupt control registers */ writel(SCC_SCM_INTR_CTRL_CLR_INTR,
From: Alexander Shiyan shc_work@mail.ru
[ Upstream commit b0f17570b8203c22f139459c86cfbaa0311313ed ]
Commit e39c0df1be5a ("pwm: Introduce the pwm_args concept") has changed the variable for the period for clps711x-pwm driver, so now pwm_get/set_period() works with pwm->state.period variable instead of pwm->args.period. This patch changes the period variable in other places where it is used.
Signed-off-by: Alexander Shiyan shc_work@mail.ru Signed-off-by: Thierry Reding thierry.reding@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pwm/pwm-clps711x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/pwm/pwm-clps711x.c b/drivers/pwm/pwm-clps711x.c index 26ec24e457b12..7e16b7def0dcb 100644 --- a/drivers/pwm/pwm-clps711x.c +++ b/drivers/pwm/pwm-clps711x.c @@ -48,7 +48,7 @@ static void clps711x_pwm_update_val(struct clps711x_chip *priv, u32 n, u32 v) static unsigned int clps711x_get_duty(struct pwm_device *pwm, unsigned int v) { /* Duty cycle 0..15 max */ - return DIV_ROUND_CLOSEST(v * 0xf, pwm_get_period(pwm)); + return DIV_ROUND_CLOSEST(v * 0xf, pwm->args.period); }
static int clps711x_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) @@ -71,7 +71,7 @@ static int clps711x_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, struct clps711x_chip *priv = to_clps711x_chip(chip); unsigned int duty;
- if (period_ns != pwm_get_period(pwm)) + if (period_ns != pwm->args.period) return -EINVAL;
duty = clps711x_get_duty(pwm, duty_ns);
From: Aditya Pakki pakki001@umn.edu
[ Upstream commit 89dfd0083751d00d5d7ead36f6d8b045bf89c5e1 ]
In tipc_nl_compat_sk_dump(), if nla_parse_nested() fails, it could return an error. To be consistent with other invocations of the function call, on error, the fix passes the return value upstream.
Signed-off-by: Aditya Pakki pakki001@umn.edu Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/tipc/netlink_compat.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c index ad4dcc663c6de..1c8ac0c11008c 100644 --- a/net/tipc/netlink_compat.c +++ b/net/tipc/netlink_compat.c @@ -1021,8 +1021,11 @@ static int tipc_nl_compat_sk_dump(struct tipc_nl_compat_msg *msg, u32 node; struct nlattr *con[TIPC_NLA_CON_MAX + 1];
- nla_parse_nested(con, TIPC_NLA_CON_MAX, - sock[TIPC_NLA_SOCK_CON], NULL, NULL); + err = nla_parse_nested(con, TIPC_NLA_CON_MAX, + sock[TIPC_NLA_SOCK_CON], NULL, NULL); + + if (err) + return err;
node = nla_get_u32(con[TIPC_NLA_CON_NODE]); tipc_tlv_sprintf(msg->rep, " connected to <%u.%u.%u:%u>",
From: Aditya Pakki pakki001@umn.edu
[ Upstream commit 0eb987c874dc93f9c9d85a6465dbde20fdd3884c ]
In net_ns_init(), register_pernet_subsys() could fail while registering network namespace subsystems. The fix checks the return value and sends a panic() on failure.
Signed-off-by: Aditya Pakki pakki001@umn.edu Reviewed-by: Kirill Tkhai ktkhai@virtuozzo.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/core/net_namespace.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index 60b88718b1d48..1af25d53f63ca 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -854,7 +854,8 @@ static int __init net_ns_init(void)
mutex_unlock(&net_mutex);
- register_pernet_subsys(&net_ns_ops); + if (register_pernet_subsys(&net_ns_ops)) + panic("Could not register network namespace subsystems");
rtnl_register(PF_UNSPEC, RTM_NEWNSID, rtnl_net_newid, NULL, RTNL_FLAG_DOIT_UNLOCKED);
From: Chao Yu yuchao0@huawei.com
[ Upstream commit b32e019049e959ee10ec359893c9dd5d057dad55 ]
If user change inode's i_flags via ioctl, let's add it into global dirty list, so that checkpoint can guarantee its persistence before fsync, it can make checkpoint keeping strong consistency.
Signed-off-by: Chao Yu yuchao0@huawei.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 1b17921994459..d68b0132718a6 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -1593,7 +1593,7 @@ static int __f2fs_ioc_setflags(struct inode *inode, unsigned int flags)
inode->i_ctime = current_time(inode); f2fs_set_inode_flags(inode); - f2fs_mark_inode_dirty_sync(inode, false); + f2fs_mark_inode_dirty_sync(inode, true); return 0; }
From: Richard Weinberger richard@nod.at
[ Upstream commit 550ed0e2036663b35cec12374b835444f9c60454 ]
Both do more or less the same thing and are mutually exclusive. If both are enabled the build will fail. Sooner or later we can kill UML's GCOV.
Signed-off-by: Richard Weinberger richard@nod.at Signed-off-by: Sasha Levin sashal@kernel.org --- arch/um/Kconfig.debug | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/um/Kconfig.debug b/arch/um/Kconfig.debug index 967d3109689ff..39d44bfb241d5 100644 --- a/arch/um/Kconfig.debug +++ b/arch/um/Kconfig.debug @@ -19,6 +19,7 @@ config GPROF config GCOV bool "Enable gcov support" depends on DEBUG_INFO + depends on !KCOV help This option allows developers to retrieve coverage data from a UML session.
From: Kangjie Lu kjlu@umn.edu
[ Upstream commit 2d822f2dbab7f4c820f72eb8570aacf3f35855bd ]
clk_prepare() could fail, so let's check its status, and if it fails, return its error code upstream.
Signed-off-by: Kangjie Lu kjlu@umn.edu Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/ti/cpts.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/ti/cpts.c b/drivers/net/ethernet/ti/cpts.c index e7b76f6b4f67e..7d1281d812480 100644 --- a/drivers/net/ethernet/ti/cpts.c +++ b/drivers/net/ethernet/ti/cpts.c @@ -567,7 +567,9 @@ struct cpts *cpts_create(struct device *dev, void __iomem *regs, return ERR_PTR(PTR_ERR(cpts->refclk)); }
- clk_prepare(cpts->refclk); + ret = clk_prepare(cpts->refclk); + if (ret) + return ERR_PTR(ret);
cpts->cc.read = cpts_systim_read; cpts->cc.mask = CLOCKSOURCE_MASK(32);
From: Kangjie Lu kjlu@umn.edu
[ Upstream commit f86a3b83833e7cfe558ca4d70b64ebc48903efec ]
clk_prepare() could fail, so let's check its status, and if it fails, return its error code upstream.
Signed-off-by: Kangjie Lu kjlu@umn.edu Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c index d07520fb969e6..62ccbd47c1db2 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c @@ -59,7 +59,9 @@ static int sun7i_gmac_init(struct platform_device *pdev, void *priv) gmac->clk_enabled = 1; } else { clk_set_rate(gmac->tx_clk, SUN7I_GMAC_MII_RATE); - clk_prepare(gmac->tx_clk); + ret = clk_prepare(gmac->tx_clk); + if (ret) + return ret; }
return 0;
From: Kangjie Lu kjlu@umn.edu
[ Upstream commit e49505f7255be8ced695919c08a29bf2c3d79616 ]
Both bcm_sf2_sw_indir_rw and mdiobus_write_nested could fail, so let's return their error codes upstream.
Signed-off-by: Kangjie Lu kjlu@umn.edu Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/dsa/bcm_sf2.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c index af666951a9592..94ad2fdd6ef0d 100644 --- a/drivers/net/dsa/bcm_sf2.c +++ b/drivers/net/dsa/bcm_sf2.c @@ -432,11 +432,10 @@ static int bcm_sf2_sw_mdio_write(struct mii_bus *bus, int addr, int regnum, * send them to our master MDIO bus controller */ if (addr == BRCM_PSEUDO_PHY_ADDR && priv->indir_phy_mask & BIT(addr)) - bcm_sf2_sw_indir_rw(priv, 0, addr, regnum, val); + return bcm_sf2_sw_indir_rw(priv, 0, addr, regnum, val); else - mdiobus_write_nested(priv->master_mii_bus, addr, regnum, val); - - return 0; + return mdiobus_write_nested(priv->master_mii_bus, addr, + regnum, val); }
static irqreturn_t bcm_sf2_switch_0_isr(int irq, void *dev_id)
From: Kangjie Lu kjlu@umn.edu
[ Upstream commit ff07d48d7bc0974d4f96a85a4df14564fb09f1ef ]
atl1e_write_phy_reg() could fail. The fix issues an error message when it fails.
Signed-off-by: Kangjie Lu kjlu@umn.edu Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/atheros/atl1e/atl1e_main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c index 4f7e195af0bc6..0d08039981b54 100644 --- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c +++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c @@ -472,7 +472,9 @@ static void atl1e_mdio_write(struct net_device *netdev, int phy_id, { struct atl1e_adapter *adapter = netdev_priv(netdev);
- atl1e_write_phy_reg(&adapter->hw, reg_num & MDIO_REG_ADDR_MASK, val); + if (atl1e_write_phy_reg(&adapter->hw, + reg_num & MDIO_REG_ADDR_MASK, val)) + netdev_err(netdev, "write phy register failed\n"); }
static int atl1e_mii_ioctl(struct net_device *netdev,
From: Kangjie Lu kjlu@umn.edu
[ Upstream commit 46273cf7e009231d2b6bc10a926e82b8928a9fb2 ]
genlmsg_put could fail. The fix inserts a check of its return value, and if it fails, returns -EMSGSIZE.
Signed-off-by: Kangjie Lu kjlu@umn.edu Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/tipc/netlink_compat.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c index 1c8ac0c11008c..91d51a595ac23 100644 --- a/net/tipc/netlink_compat.c +++ b/net/tipc/netlink_compat.c @@ -974,6 +974,8 @@ static int tipc_nl_compat_publ_dump(struct tipc_nl_compat_msg *msg, u32 sock)
hdr = genlmsg_put(args, 0, 0, &tipc_genl_family, NLM_F_MULTI, TIPC_NL_PUBL_GET); + if (!hdr) + return -EMSGSIZE;
nest = nla_nest_start(args, TIPC_NLA_SOCK); if (!nest) {
From: Wen Yang wen.yang99@zte.com.cn
[ Upstream commit 40752b3eae29f8ca2378e978a02bd6dbeeb06d16 ]
This patch fixes potential double frees if register_hdlc_device() fails.
Signed-off-by: Wen Yang wen.yang99@zte.com.cn Reviewed-by: Peng Hao peng.hao2@zte.com.cn CC: Zhao Qiang qiang.zhao@nxp.com CC: "David S. Miller" davem@davemloft.net CC: netdev@vger.kernel.org CC: linuxppc-dev@lists.ozlabs.org CC: linux-kernel@vger.kernel.org Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wan/fsl_ucc_hdlc.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/drivers/net/wan/fsl_ucc_hdlc.c b/drivers/net/wan/fsl_ucc_hdlc.c index 18b648648adb2..289dff262948d 100644 --- a/drivers/net/wan/fsl_ucc_hdlc.c +++ b/drivers/net/wan/fsl_ucc_hdlc.c @@ -1114,7 +1114,6 @@ static int ucc_hdlc_probe(struct platform_device *pdev) if (register_hdlc_device(dev)) { ret = -ENOBUFS; pr_err("ucc_hdlc: unable to register hdlc device\n"); - free_netdev(dev); goto free_dev; }
From: Junxiao Bi junxiao.bi@oracle.com
[ Upstream commit d85400af790dba2aa294f0a77e712f166681f977 ]
Dirty flag of the journal should be cleared at the last stage of umount, if do it before jbd2_journal_destroy(), then some metadata in uncommitted transaction could be lost due to io error, but as dirty flag of journal was already cleared, we can't find that until run a full fsck. This may cause system panic or other corruption.
Link: http://lkml.kernel.org/r/20181121020023.3034-3-junxiao.bi@oracle.com Signed-off-by: Junxiao Bi junxiao.bi@oracle.com Reviewed-by: Yiwen Jiang jiangyiwen@huawei.com Reviewed-by: Joseph Qi jiangqi903@gmail.com Cc: Jun Piao piaojun@huawei.com Cc: Changwei Ge ge.changwei@h3c.com Cc: Joel Becker jlbec@evilplan.org Cc: Mark Fasheh mfasheh@versity.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/ocfs2/journal.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c index f7fba58618ef3..2459ae9d2234f 100644 --- a/fs/ocfs2/journal.c +++ b/fs/ocfs2/journal.c @@ -1018,7 +1018,8 @@ void ocfs2_journal_shutdown(struct ocfs2_super *osb) mlog_errno(status); }
- if (status == 0) { + /* Shutdown the kernel journal system */ + if (!jbd2_journal_destroy(journal->j_journal) && !status) { /* * Do not toggle if flush was unsuccessful otherwise * will leave dirty metadata in a "clean" journal @@ -1027,9 +1028,6 @@ void ocfs2_journal_shutdown(struct ocfs2_super *osb) if (status < 0) mlog_errno(status); } - - /* Shutdown the kernel journal system */ - jbd2_journal_destroy(journal->j_journal); journal->j_journal = NULL;
OCFS2_I(inode)->ip_open_count--;
From: Wei Yang richard.weiyang@gmail.com
[ Upstream commit 8b09549c2bfd9f3f8f4cdad74107ef4f4ff9cdd7 ]
Commit fa5e084e43eb ("vmscan: do not unconditionally treat zones that fail zone_reclaim() as full") changed the return value of node_reclaim(). The original return value 0 means NODE_RECLAIM_SOME after this commit.
While the return value of node_reclaim() when CONFIG_NUMA is n is not changed. This will leads to call zone_watermark_ok() again.
This patch fixes the return value by adjusting to NODE_RECLAIM_NOSCAN. Since node_reclaim() is only called in page_alloc.c, move it to mm/internal.h.
Link: http://lkml.kernel.org/r/20181113080436.22078-1-richard.weiyang@gmail.com Signed-off-by: Wei Yang richard.weiyang@gmail.com Acked-by: Michal Hocko mhocko@suse.com Reviewed-by: Matthew Wilcox willy@infradead.org Cc: Mel Gorman mgorman@techsingularity.net Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/swap.h | 6 ------ mm/internal.h | 10 ++++++++++ 2 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/include/linux/swap.h b/include/linux/swap.h index e643866912b70..411953964c345 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -363,14 +363,8 @@ extern unsigned long vm_total_pages; extern int node_reclaim_mode; extern int sysctl_min_unmapped_ratio; extern int sysctl_min_slab_ratio; -extern int node_reclaim(struct pglist_data *, gfp_t, unsigned int); #else #define node_reclaim_mode 0 -static inline int node_reclaim(struct pglist_data *pgdat, gfp_t mask, - unsigned int order) -{ - return 0; -} #endif
extern int page_evictable(struct page *page); diff --git a/mm/internal.h b/mm/internal.h index 1df011f624801..a182506242c43 100644 --- a/mm/internal.h +++ b/mm/internal.h @@ -455,6 +455,16 @@ static inline void mminit_validate_memmodel_limits(unsigned long *start_pfn, #define NODE_RECLAIM_SOME 0 #define NODE_RECLAIM_SUCCESS 1
+#ifdef CONFIG_NUMA +extern int node_reclaim(struct pglist_data *, gfp_t, unsigned int); +#else +static inline int node_reclaim(struct pglist_data *pgdat, gfp_t mask, + unsigned int order) +{ + return NODE_RECLAIM_NOSCAN; +} +#endif + extern int hwpoison_filter(struct page *p);
extern u32 hwpoison_filter_dev_major;
From: Alexey Skidanov alexey.skidanov@intel.com
[ Upstream commit 52fbf1134d479234d7e64ba9dcbaea23405f229e ]
gen_pool_alloc_algo() uses different allocation functions implementing different allocation algorithms. With gen_pool_first_fit_align() allocation function, the returned address should be aligned on the requested boundary.
If chunk start address isn't aligned on the requested boundary, the returned address isn't aligned too. The only way to get properly aligned address is to initialize the pool with chunks aligned on the requested boundary. If want to have an ability to allocate buffers aligned on different boundaries (for example, 4K, 1MB, ...), the chunk start address should be aligned on the max possible alignment.
This happens because gen_pool_first_fit_align() looks for properly aligned memory block without taking into account the chunk start address alignment.
To fix this, we provide chunk start address to gen_pool_first_fit_align() and change its implementation such that it starts looking for properly aligned block with appropriate offset (exactly as is done in CMA).
Link: https://lkml.kernel.org/lkml/a170cf65-6884-3592-1de9-4c235888cc8a@intel.com Link: http://lkml.kernel.org/r/1541690953-4623-1-git-send-email-alexey.skidanov@in... Signed-off-by: Alexey Skidanov alexey.skidanov@intel.com Reviewed-by: Andrew Morton akpm@linux-foundation.org Cc: Logan Gunthorpe logang@deltatee.com Cc: Daniel Mentz danielmentz@google.com Cc: Mathieu Desnoyers mathieu.desnoyers@efficios.com Cc: Laura Abbott labbott@redhat.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/genalloc.h | 13 +++++++------ lib/genalloc.c | 20 ++++++++++++-------- 2 files changed, 19 insertions(+), 14 deletions(-)
diff --git a/include/linux/genalloc.h b/include/linux/genalloc.h index 872f930f1b06d..dd0a452373e71 100644 --- a/include/linux/genalloc.h +++ b/include/linux/genalloc.h @@ -51,7 +51,8 @@ typedef unsigned long (*genpool_algo_t)(unsigned long *map, unsigned long size, unsigned long start, unsigned int nr, - void *data, struct gen_pool *pool); + void *data, struct gen_pool *pool, + unsigned long start_addr);
/* * General purpose special memory pool descriptor. @@ -131,24 +132,24 @@ extern void gen_pool_set_algo(struct gen_pool *pool, genpool_algo_t algo,
extern unsigned long gen_pool_first_fit(unsigned long *map, unsigned long size, unsigned long start, unsigned int nr, void *data, - struct gen_pool *pool); + struct gen_pool *pool, unsigned long start_addr);
extern unsigned long gen_pool_fixed_alloc(unsigned long *map, unsigned long size, unsigned long start, unsigned int nr, - void *data, struct gen_pool *pool); + void *data, struct gen_pool *pool, unsigned long start_addr);
extern unsigned long gen_pool_first_fit_align(unsigned long *map, unsigned long size, unsigned long start, unsigned int nr, - void *data, struct gen_pool *pool); + void *data, struct gen_pool *pool, unsigned long start_addr);
extern unsigned long gen_pool_first_fit_order_align(unsigned long *map, unsigned long size, unsigned long start, unsigned int nr, - void *data, struct gen_pool *pool); + void *data, struct gen_pool *pool, unsigned long start_addr);
extern unsigned long gen_pool_best_fit(unsigned long *map, unsigned long size, unsigned long start, unsigned int nr, void *data, - struct gen_pool *pool); + struct gen_pool *pool, unsigned long start_addr);
extern struct gen_pool *devm_gen_pool_create(struct device *dev, diff --git a/lib/genalloc.c b/lib/genalloc.c index ca06adc4f4451..5deb25c40a5a1 100644 --- a/lib/genalloc.c +++ b/lib/genalloc.c @@ -311,7 +311,7 @@ unsigned long gen_pool_alloc_algo(struct gen_pool *pool, size_t size, end_bit = chunk_size(chunk) >> order; retry: start_bit = algo(chunk->bits, end_bit, start_bit, - nbits, data, pool); + nbits, data, pool, chunk->start_addr); if (start_bit >= end_bit) continue; remain = bitmap_set_ll(chunk->bits, start_bit, nbits); @@ -525,7 +525,7 @@ EXPORT_SYMBOL(gen_pool_set_algo); */ unsigned long gen_pool_first_fit(unsigned long *map, unsigned long size, unsigned long start, unsigned int nr, void *data, - struct gen_pool *pool) + struct gen_pool *pool, unsigned long start_addr) { return bitmap_find_next_zero_area(map, size, start, nr, 0); } @@ -543,16 +543,19 @@ EXPORT_SYMBOL(gen_pool_first_fit); */ unsigned long gen_pool_first_fit_align(unsigned long *map, unsigned long size, unsigned long start, unsigned int nr, void *data, - struct gen_pool *pool) + struct gen_pool *pool, unsigned long start_addr) { struct genpool_data_align *alignment; - unsigned long align_mask; + unsigned long align_mask, align_off; int order;
alignment = data; order = pool->min_alloc_order; align_mask = ((alignment->align + (1UL << order) - 1) >> order) - 1; - return bitmap_find_next_zero_area(map, size, start, nr, align_mask); + align_off = (start_addr & (alignment->align - 1)) >> order; + + return bitmap_find_next_zero_area_off(map, size, start, nr, + align_mask, align_off); } EXPORT_SYMBOL(gen_pool_first_fit_align);
@@ -567,7 +570,7 @@ EXPORT_SYMBOL(gen_pool_first_fit_align); */ unsigned long gen_pool_fixed_alloc(unsigned long *map, unsigned long size, unsigned long start, unsigned int nr, void *data, - struct gen_pool *pool) + struct gen_pool *pool, unsigned long start_addr) { struct genpool_data_fixed *fixed_data; int order; @@ -601,7 +604,8 @@ EXPORT_SYMBOL(gen_pool_fixed_alloc); */ unsigned long gen_pool_first_fit_order_align(unsigned long *map, unsigned long size, unsigned long start, - unsigned int nr, void *data, struct gen_pool *pool) + unsigned int nr, void *data, struct gen_pool *pool, + unsigned long start_addr) { unsigned long align_mask = roundup_pow_of_two(nr) - 1;
@@ -624,7 +628,7 @@ EXPORT_SYMBOL(gen_pool_first_fit_order_align); */ unsigned long gen_pool_best_fit(unsigned long *map, unsigned long size, unsigned long start, unsigned int nr, void *data, - struct gen_pool *pool) + struct gen_pool *pool, unsigned long start_addr) { unsigned long start_bit = size; unsigned long len = size + 1;
From: Huang Shijie sjhuang@iluvatar.ai
[ Upstream commit 6862d2fc81859f88c1f3f660886427893f2b4f3f ]
Some devices may have big memory on chip, such as over 1G. In some cases, the nbytes maybe bigger then 4M which is the bounday of the memory buddy system (4K default).
So use vzalloc_node() to allocate the bitmap. Also use vfree to free it.
Link: http://lkml.kernel.org/r/20181225015701.6289-1-sjhuang@iluvatar.ai Signed-off-by: Huang Shijie sjhuang@iluvatar.ai Reviewed-by: Andrew Morton akpm@linux-foundation.org Cc: Alexey Skidanov alexey.skidanov@intel.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- lib/genalloc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/genalloc.c b/lib/genalloc.c index 5deb25c40a5a1..f365d71cdc774 100644 --- a/lib/genalloc.c +++ b/lib/genalloc.c @@ -187,7 +187,7 @@ int gen_pool_add_virt(struct gen_pool *pool, unsigned long virt, phys_addr_t phy int nbytes = sizeof(struct gen_pool_chunk) + BITS_TO_LONGS(nbits) * sizeof(long);
- chunk = kzalloc_node(nbytes, GFP_KERNEL, nid); + chunk = vzalloc_node(nbytes, nid); if (unlikely(chunk == NULL)) return -ENOMEM;
@@ -251,7 +251,7 @@ void gen_pool_destroy(struct gen_pool *pool) bit = find_next_bit(chunk->bits, end_bit, 0); BUG_ON(bit < end_bit);
- kfree(chunk); + vfree(chunk); } kfree_const(pool->name); kfree(pool);
From: Yi Wang wang.yi59@zte.com.cn
[ Upstream commit fb5bf31722d0805a3f394f7d59f2e8cd07acccb7 ]
We get a warning when building kernel with W=1:
kernel/fork.c:167:13: warning: no previous prototype for `arch_release_thread_stack' [-Wmissing-prototypes] kernel/fork.c:779:13: warning: no previous prototype for `fork_init' [-Wmissing-prototypes]
Add the missing declaration in head file to fix this.
Also, remove arch_release_thread_stack() completely because no arch seems to implement it since bb9d81264 (arch: remove tile port).
Link: http://lkml.kernel.org/r/1542170087-23645-1-git-send-email-wang.yi59@zte.com... Signed-off-by: Yi Wang wang.yi59@zte.com.cn Acked-by: Michal Hocko mhocko@suse.com Acked-by: Mike Rapoport rppt@linux.ibm.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/sched/task.h | 2 ++ init/main.c | 1 - kernel/fork.c | 5 ----- 3 files changed, 2 insertions(+), 6 deletions(-)
diff --git a/include/linux/sched/task.h b/include/linux/sched/task.h index a74ec619ac510..11b4fba82950f 100644 --- a/include/linux/sched/task.h +++ b/include/linux/sched/task.h @@ -39,6 +39,8 @@ void __noreturn do_task_dead(void);
extern void proc_caches_init(void);
+extern void fork_init(void); + extern void release_task(struct task_struct * p);
#ifdef CONFIG_HAVE_COPY_THREAD_TLS diff --git a/init/main.c b/init/main.c index 51067e2db509d..b1ab36fe1a55c 100644 --- a/init/main.c +++ b/init/main.c @@ -98,7 +98,6 @@ static int kernel_init(void *);
extern void init_IRQ(void); -extern void fork_init(void); extern void radix_tree_init(void);
/* diff --git a/kernel/fork.c b/kernel/fork.c index 3352fdbd5e20d..3d9d6a28e21d9 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -162,10 +162,6 @@ static inline void free_task_struct(struct task_struct *tsk) } #endif
-void __weak arch_release_thread_stack(unsigned long *stack) -{ -} - #ifndef CONFIG_ARCH_THREAD_STACK_ALLOCATOR
/* @@ -348,7 +344,6 @@ static void release_task_stack(struct task_struct *tsk) return; /* Better to leak the stack than to free prematurely */
account_kernel_stack(tsk, -1); - arch_release_thread_stack(tsk->stack); free_thread_stack(tsk); tsk->stack = NULL; #ifdef CONFIG_VMAP_STACK
From: Qian Cai cai@gmx.us
[ Upstream commit 967d3010df8b6f6f9aa95c198edc5fe3646ebf36 ]
unreferenced object 0xffff808ec6dc5a80 (size 128): comm "swapper/0", pid 1, jiffies 4294938063 (age 2560.530s) hex dump (first 32 bytes): ff ff ff ff 00 00 00 00 6b 6b 6b 6b 6b 6b 6b 6b ........kkkkkkkk 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk backtrace: [<00000000476dcf8c>] kmem_cache_alloc_trace+0x430/0x500 [<000000004f708d37>] platform_device_register_full+0xbc/0x1e8 [<000000006c2a7ec7>] acpi_create_platform_device+0x370/0x450 [<00000000ef135642>] acpi_default_enumeration+0x34/0x78 [<000000003bd9a052>] acpi_bus_attach+0x2dc/0x3e0 [<000000003cf4f7f2>] acpi_bus_attach+0x108/0x3e0 [<000000003cf4f7f2>] acpi_bus_attach+0x108/0x3e0 [<000000002968643e>] acpi_bus_scan+0xb0/0x110 [<0000000010dd0bd7>] acpi_scan_init+0x1a8/0x410 [<00000000965b3c5a>] acpi_init+0x408/0x49c [<00000000ed4b9fe2>] do_one_initcall+0x178/0x7f4 [<00000000a5ac5a74>] kernel_init_freeable+0x9d4/0xa9c [<0000000070ea6c15>] kernel_init+0x18/0x138 [<00000000fb8fff06>] ret_from_fork+0x10/0x1c [<0000000041273a0d>] 0xffffffffffffffff
Then, faddr2line pointed out this line,
/* * This memory isn't freed when the device is put, * I don't have a nice idea for that though. Conceptually * dma_mask in struct device should not be a pointer. * See http://thread.gmane.org/gmane.linux.kernel.pci/9081 */ pdev->dev.dma_mask = kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL);
Since this leak has existed for more than 8 years and it does not reference other parts of the memory, let kmemleak ignore it, so users don't need to waste time reporting this in the future.
Link: http://lkml.kernel.org/r/20181206160751.36211-1-cai@gmx.us Signed-off-by: Qian Cai cai@gmx.us Reviewed-by: Andrew Morton akpm@linux-foundation.org Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: "Rafael J . Wysocki" rafael.j.wysocki@intel.com Cc: Catalin Marinas catalin.marinas@arm.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/base/platform.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 9045c5f3734e8..f1105de0d9fed 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -27,6 +27,7 @@ #include <linux/clk/clk-conf.h> #include <linux/limits.h> #include <linux/property.h> +#include <linux/kmemleak.h>
#include "base.h" #include "power/power.h" @@ -526,6 +527,8 @@ struct platform_device *platform_device_register_full( if (!pdev->dev.dma_mask) goto err;
+ kmemleak_ignore(pdev->dev.dma_mask); + *pdev->dev.dma_mask = pdevinfo->dma_mask; pdev->dev.coherent_dma_mask = pdevinfo->dma_mask; }
From: Olof Johansson olof@lixom.net
[ Upstream commit 35004f2e55807a1a1491db24ab512dd2f770a130 ]
Fixes build break on most ARM/ARM64 defconfigs:
lib/genalloc.c: In function 'gen_pool_add_virt': lib/genalloc.c:190:10: error: implicit declaration of function 'vzalloc_node'; did you mean 'kzalloc_node'? lib/genalloc.c:190:8: warning: assignment to 'struct gen_pool_chunk *' from 'int' makes pointer from integer without a cast [-Wint-conversion] lib/genalloc.c: In function 'gen_pool_destroy': lib/genalloc.c:254:3: error: implicit declaration of function 'vfree'; did you mean 'kfree'?
Fixes: 6862d2fc8185 ('lib/genalloc.c: use vzalloc_node() to allocate the bitmap') Cc: Huang Shijie sjhuang@iluvatar.ai Cc: Andrew Morton akpm@linux-foundation.org Cc: Alexey Skidanov alexey.skidanov@intel.com Signed-off-by: Olof Johansson olof@lixom.net Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- lib/genalloc.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/lib/genalloc.c b/lib/genalloc.c index f365d71cdc774..7e85d1e37a6ea 100644 --- a/lib/genalloc.c +++ b/lib/genalloc.c @@ -35,6 +35,7 @@ #include <linux/interrupt.h> #include <linux/genalloc.h> #include <linux/of_device.h> +#include <linux/vmalloc.h>
static inline size_t chunk_size(const struct gen_pool_chunk *chunk) {
From: Boris Brezillon bbrezillon@kernel.org
[ Upstream commit 2b6f0090a3335b7bdd03ca520c35591159463041 ]
add_mtd_device() can fail. We should always check its return value and gracefully handle the failure case. Fix the call sites where this not done (in mtdpart.c) and add a __must_check attribute to the prototype to avoid this kind of mistakes.
Signed-off-by: Boris Brezillon bbrezillon@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mtd/mtdcore.h | 2 +- drivers/mtd/mtdpart.c | 36 +++++++++++++++++++++++++++++++----- 2 files changed, 32 insertions(+), 6 deletions(-)
diff --git a/drivers/mtd/mtdcore.h b/drivers/mtd/mtdcore.h index 37accfd0400e5..24480b75a88dd 100644 --- a/drivers/mtd/mtdcore.h +++ b/drivers/mtd/mtdcore.h @@ -7,7 +7,7 @@ extern struct mutex mtd_table_mutex;
struct mtd_info *__mtd_next_device(int i); -int add_mtd_device(struct mtd_info *mtd); +int __must_check add_mtd_device(struct mtd_info *mtd); int del_mtd_device(struct mtd_info *mtd); int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int); int del_mtd_partitions(struct mtd_info *); diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index a308e707392d5..27d9785487d69 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c @@ -684,10 +684,22 @@ int mtd_add_partition(struct mtd_info *parent, const char *name, list_add(&new->list, &mtd_partitions); mutex_unlock(&mtd_partitions_mutex);
- add_mtd_device(&new->mtd); + ret = add_mtd_device(&new->mtd); + if (ret) + goto err_remove_part;
mtd_add_partition_attrs(new);
+ return 0; + +err_remove_part: + mutex_lock(&mtd_partitions_mutex); + list_del(&new->list); + mutex_unlock(&mtd_partitions_mutex); + + free_partition(new); + pr_info("%s:%i\n", __func__, __LINE__); + return ret; } EXPORT_SYMBOL_GPL(mtd_add_partition); @@ -778,22 +790,31 @@ int add_mtd_partitions(struct mtd_info *master, { struct mtd_part *slave; uint64_t cur_offset = 0; - int i; + int i, ret;
printk(KERN_NOTICE "Creating %d MTD partitions on "%s":\n", nbparts, master->name);
for (i = 0; i < nbparts; i++) { slave = allocate_partition(master, parts + i, i, cur_offset); if (IS_ERR(slave)) { - del_mtd_partitions(master); - return PTR_ERR(slave); + ret = PTR_ERR(slave); + goto err_del_partitions; }
mutex_lock(&mtd_partitions_mutex); list_add(&slave->list, &mtd_partitions); mutex_unlock(&mtd_partitions_mutex);
- add_mtd_device(&slave->mtd); + ret = add_mtd_device(&slave->mtd); + if (ret) { + mutex_lock(&mtd_partitions_mutex); + list_del(&slave->list); + mutex_unlock(&mtd_partitions_mutex); + + free_partition(slave); + goto err_del_partitions; + } + mtd_add_partition_attrs(slave); if (parts[i].types) mtd_parse_part(slave, parts[i].types); @@ -802,6 +823,11 @@ int add_mtd_partitions(struct mtd_info *master, }
return 0; + +err_del_partitions: + del_mtd_partitions(master); + + return ret; }
static DEFINE_SPINLOCK(part_parser_lock);
From: Gustavo A. R. Silva gustavo@embeddedor.com
[ Upstream commit f87d8ad9233f115db92c6c087d58403b0009ed36 ]
There is a memory leak in case genlmsg_put fails.
Fix this by freeing *args* before return.
Addresses-Coverity-ID: 1476406 ("Resource leak") Fixes: 46273cf7e009 ("tipc: fix a missing check of genlmsg_put") Signed-off-by: Gustavo A. R. Silva gustavo@embeddedor.com Acked-by: Ying Xue ying.xue@windriver.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/tipc/netlink_compat.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c index 91d51a595ac23..bbd05707c4e07 100644 --- a/net/tipc/netlink_compat.c +++ b/net/tipc/netlink_compat.c @@ -974,8 +974,10 @@ static int tipc_nl_compat_publ_dump(struct tipc_nl_compat_msg *msg, u32 sock)
hdr = genlmsg_put(args, 0, 0, &tipc_genl_family, NLM_F_MULTI, TIPC_NL_PUBL_GET); - if (!hdr) + if (!hdr) { + kfree_skb(args); return -EMSGSIZE; + }
nest = nla_nest_start(args, TIPC_NLA_SOCK); if (!nest) {
From: Konstantin Khlebnikov khlebnikov@yandex-team.ru
[ Upstream commit 85704cb8dcfd88d351bfc87faaeba1c8214f3177 ]
This fixes false-positive kmemleak reports about leaked neighbour entries:
unreferenced object 0xffff8885c6e4d0a8 (size 1024): comm "softirq", pid 0, jiffies 4294922664 (age 167640.804s) hex dump (first 32 bytes): 00 00 00 00 00 00 00 00 20 2c f3 83 ff ff ff ff ........ ,...... 08 c0 ef 5f 84 88 ff ff 01 8c 7d 02 01 00 00 00 ..._......}..... backtrace: [<00000000748509fe>] ip6_finish_output2+0x887/0x1e40 [<0000000036d7a0d8>] ip6_output+0x1ba/0x600 [<0000000027ea7dba>] ip6_send_skb+0x92/0x2f0 [<00000000d6e2111d>] udp_v6_send_skb.isra.24+0x680/0x15e0 [<000000000668a8be>] udpv6_sendmsg+0x18c9/0x27a0 [<000000004bd5fa90>] sock_sendmsg+0xb3/0xf0 [<000000008227b29f>] ___sys_sendmsg+0x745/0x8f0 [<000000008698009d>] __sys_sendmsg+0xde/0x170 [<00000000889dacf1>] do_syscall_64+0x9b/0x400 [<0000000081cdb353>] entry_SYSCALL_64_after_hwframe+0x49/0xbe [<000000005767ed39>] 0xffffffffffffffff
Signed-off-by: Konstantin Khlebnikov khlebnikov@yandex-team.ru Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/core/neighbour.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index eb3efeabac91d..9a28a21a51f05 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -18,6 +18,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/slab.h> +#include <linux/kmemleak.h> #include <linux/types.h> #include <linux/kernel.h> #include <linux/module.h> @@ -361,12 +362,14 @@ static struct neigh_hash_table *neigh_hash_alloc(unsigned int shift) ret = kmalloc(sizeof(*ret), GFP_ATOMIC); if (!ret) return NULL; - if (size <= PAGE_SIZE) + if (size <= PAGE_SIZE) { buckets = kzalloc(size, GFP_ATOMIC); - else + } else { buckets = (struct neighbour __rcu **) __get_free_pages(GFP_ATOMIC | __GFP_ZERO, get_order(size)); + kmemleak_alloc(buckets, size, 0, GFP_ATOMIC); + } if (!buckets) { kfree(ret); return NULL; @@ -386,10 +389,12 @@ static void neigh_hash_free_rcu(struct rcu_head *head) size_t size = (1 << nht->hash_shift) * sizeof(struct neighbour *); struct neighbour __rcu **buckets = nht->hash_buckets;
- if (size <= PAGE_SIZE) + if (size <= PAGE_SIZE) { kfree(buckets); - else + } else { + kmemleak_free(buckets); free_pages((unsigned long)buckets, get_order(size)); + } kfree(nht); }
From: Ming Lei ming.lei@redhat.com
[ Upstream commit 77f88abd4a6f73a1a68dbdc0e3f21575fd508fc3 ]
The API of pci_alloc_irq_vectors_affinity() says it returns -ENOSPC if fewer than @min_vecs interrupt vectors are available for @dev.
However, if a device supports MSI-X but not MSI and a caller requests @min_vecs that can't be satisfied by MSI-X, we previously returned -EINVAL (from the failed attempt to enable MSI), not -ENOSPC.
When -ENOSPC is returned, callers may reduce the number IRQs they request and try again. Most callers can use the @min_vecs and @max_vecs parameters to avoid this retry loop, but that doesn't work when using IRQ affinity "nr_sets" because rebalancing the sets is driver-specific.
This return value bug has been present since pci_alloc_irq_vectors() was added in v4.10 by aff171641d18 ("PCI: Provide sensible IRQ vector alloc/free routines"), but it wasn't an issue because @min_vecs/@max_vecs removed the need for callers to iteratively reduce the number of IRQs requested and retry the allocation, so they didn't need to distinguish -ENOSPC from -EINVAL.
In v5.0, 6da4b3ab9a6e ("genirq/affinity: Add support for allocating interrupt sets") added IRQ sets to the interface, which reintroduced the need to check for -ENOSPC and possibly reduce the number of IRQs requested and retry the allocation.
Signed-off-by: Ming Lei ming.lei@redhat.com [bhelgaas: changelog] Signed-off-by: Bjorn Helgaas bhelgaas@google.com Cc: Jens Axboe axboe@fb.com Cc: Keith Busch keith.busch@intel.com Cc: Christoph Hellwig hch@lst.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/msi.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 536e9a5cd2b14..d66ef88e13cf1 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -1156,7 +1156,8 @@ int pci_alloc_irq_vectors_affinity(struct pci_dev *dev, unsigned int min_vecs, const struct irq_affinity *affd) { static const struct irq_affinity msi_default_affd; - int vecs = -ENOSPC; + int msix_vecs = -ENOSPC; + int msi_vecs = -ENOSPC;
if (flags & PCI_IRQ_AFFINITY) { if (!affd) @@ -1167,16 +1168,17 @@ int pci_alloc_irq_vectors_affinity(struct pci_dev *dev, unsigned int min_vecs, }
if (flags & PCI_IRQ_MSIX) { - vecs = __pci_enable_msix_range(dev, NULL, min_vecs, max_vecs, - affd); - if (vecs > 0) - return vecs; + msix_vecs = __pci_enable_msix_range(dev, NULL, min_vecs, + max_vecs, affd); + if (msix_vecs > 0) + return msix_vecs; }
if (flags & PCI_IRQ_MSI) { - vecs = __pci_enable_msi_range(dev, min_vecs, max_vecs, affd); - if (vecs > 0) - return vecs; + msi_vecs = __pci_enable_msi_range(dev, min_vecs, max_vecs, + affd); + if (msi_vecs > 0) + return msi_vecs; }
/* use legacy irq if allowed */ @@ -1187,7 +1189,9 @@ int pci_alloc_irq_vectors_affinity(struct pci_dev *dev, unsigned int min_vecs, } }
- return vecs; + if (msix_vecs == -ENOSPC) + return -ENOSPC; + return msi_vecs; } EXPORT_SYMBOL(pci_alloc_irq_vectors_affinity);
From: Konstantin Khlebnikov khlebnikov@yandex-team.ru
[ Upstream commit 01b833ab44c9e484060aad72267fc7e71beb559b ]
This should be 1 for normal allocations, 0 disables leak reporting.
Signed-off-by: Konstantin Khlebnikov khlebnikov@yandex-team.ru Reported-by: Cong Wang xiyou.wangcong@gmail.com Fixes: 85704cb8dcfd ("net/core/neighbour: tell kmemleak about hash tables") Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/core/neighbour.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 9a28a21a51f05..2664ad58e5c01 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -368,7 +368,7 @@ static struct neigh_hash_table *neigh_hash_alloc(unsigned int shift) buckets = (struct neighbour __rcu **) __get_free_pages(GFP_ATOMIC | __GFP_ZERO, get_order(size)); - kmemleak_alloc(buckets, size, 0, GFP_ATOMIC); + kmemleak_alloc(buckets, size, 1, GFP_ATOMIC); } if (!buckets) { kfree(ret);
From: He Zhe zhe.he@windriver.com
[ Upstream commit 352c4cf40c4a7d439fa5d30aa2160f54b394da82 ]
The initialization code of interrupt backoff work might reference NULL pointer and cause the following crash, if no port was found.
[ 10.017727] CPU 0 Unable to handle kernel paging request at virtual address 000001b0, epc == 807088e0, ra == 8070863c ---- snip ---- [ 11.704470] [<807088e0>] serial8250_register_8250_port+0x318/0x4ac [ 11.747251] [<80708d74>] serial8250_probe+0x148/0x1c0 [ 11.789301] [<80728450>] platform_drv_probe+0x40/0x94 [ 11.830515] [<807264f8>] really_probe+0xf8/0x318 [ 11.870876] [<80726b7c>] __driver_attach+0x110/0x12c [ 11.910960] [<80724374>] bus_for_each_dev+0x78/0xcc [ 11.951134] [<80725958>] bus_add_driver+0x200/0x234 [ 11.989756] [<807273d8>] driver_register+0x84/0x148 [ 12.029832] [<80d72f84>] serial8250_init+0x138/0x198 [ 12.070447] [<80100e6c>] do_one_initcall+0x5c/0x2a0 [ 12.110104] [<80d3a208>] kernel_init_freeable+0x370/0x484 [ 12.150722] [<80a49420>] kernel_init+0x10/0xf8 [ 12.191517] [<8010756c>] ret_from_kernel_thread+0x14/0x1c
This patch makes sure the initialization code can be reached only if a port is found.
Fixes: 6d7f677a2afa ("serial: 8250: Rate limit serial port rx interrupts during input overruns") Signed-off-by: He Zhe zhe.he@windriver.com Reviewed-by: Darwin Dingel darwin.dingel@alliedtelesis.co.nz Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/8250/8250_core.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index ceeea4b159c4b..c698ebab6d3bd 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -1077,15 +1077,16 @@ int serial8250_register_8250_port(struct uart_8250_port *up)
ret = 0; } - }
- /* Initialise interrupt backoff work if required */ - if (up->overrun_backoff_time_ms > 0) { - uart->overrun_backoff_time_ms = up->overrun_backoff_time_ms; - INIT_DELAYED_WORK(&uart->overrun_backoff, - serial_8250_overrun_backoff_work); - } else { - uart->overrun_backoff_time_ms = 0; + /* Initialise interrupt backoff work if required */ + if (up->overrun_backoff_time_ms > 0) { + uart->overrun_backoff_time_ms = + up->overrun_backoff_time_ms; + INIT_DELAYED_WORK(&uart->overrun_backoff, + serial_8250_overrun_backoff_work); + } else { + uart->overrun_backoff_time_ms = 0; + } }
mutex_unlock(&serial_mutex);
From: Lucas Stach l.stach@pengutronix.de
[ Upstream commit eb0200a4357da100064971689d3a0e9e3cf57f33 ]
On a NOP double buffer update where current buffer address is the same as the next buffer address, the SDW_UPDATE bit clears too late. As we are now using this bit to determine when it is safe to signal flip completion to userspace this will delay completion of atomic commits where one plane doesn't change the buffer by a whole frame period.
Fix this by remembering the last buffer address and just skip the double buffer update if it would not change the buffer address.
Signed-off-by: Lucas Stach l.stach@pengutronix.de [p.zabel@pengutronix.de: initialize last_bufaddr in ipu_pre_configure] Signed-off-by: Philipp Zabel p.zabel@pengutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/ipu-v3/ipu-pre.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/drivers/gpu/ipu-v3/ipu-pre.c b/drivers/gpu/ipu-v3/ipu-pre.c index 1d1612e28854b..6fd4af647f599 100644 --- a/drivers/gpu/ipu-v3/ipu-pre.c +++ b/drivers/gpu/ipu-v3/ipu-pre.c @@ -102,6 +102,7 @@ struct ipu_pre { void *buffer_virt; bool in_use; unsigned int safe_window_end; + unsigned int last_bufaddr; };
static DEFINE_MUTEX(ipu_pre_list_mutex); @@ -177,6 +178,7 @@ void ipu_pre_configure(struct ipu_pre *pre, unsigned int width,
writel(bufaddr, pre->regs + IPU_PRE_CUR_BUF); writel(bufaddr, pre->regs + IPU_PRE_NEXT_BUF); + pre->last_bufaddr = bufaddr;
val = IPU_PRE_PREF_ENG_CTRL_INPUT_PIXEL_FORMAT(0) | IPU_PRE_PREF_ENG_CTRL_INPUT_ACTIVE_BPP(active_bpp) | @@ -218,7 +220,11 @@ void ipu_pre_update(struct ipu_pre *pre, unsigned int bufaddr) unsigned short current_yblock; u32 val;
+ if (bufaddr == pre->last_bufaddr) + return; + writel(bufaddr, pre->regs + IPU_PRE_NEXT_BUF); + pre->last_bufaddr = bufaddr;
do { if (time_after(jiffies, timeout)) {
From: Edward Cree ecree@solarflare.com
[ Upstream commit 3366463513f544c12c6b88c13da4462ee9e7a1a1 ]
Use a bitmap to keep track of which partition types we've already seen; for duplicates, return -EEXIST from efx_ef10_mtd_probe_partition() and thus skip adding that partition. Duplicate partitions occur because of the A/B backup scheme used by newer sfc NICs. Prior to this patch they cause sysfs_warn_dup errors because they have the same name, causing us not to expose any MTDs at all.
Signed-off-by: Edward Cree ecree@solarflare.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/sfc/ef10.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c index 09352ee43b55c..cc3be94d05622 100644 --- a/drivers/net/ethernet/sfc/ef10.c +++ b/drivers/net/ethernet/sfc/ef10.c @@ -5852,22 +5852,25 @@ static const struct efx_ef10_nvram_type_info efx_ef10_nvram_types[] = { { NVRAM_PARTITION_TYPE_LICENSE, 0, 0, "sfc_license" }, { NVRAM_PARTITION_TYPE_PHY_MIN, 0xff, 0, "sfc_phy_fw" }, }; +#define EF10_NVRAM_PARTITION_COUNT ARRAY_SIZE(efx_ef10_nvram_types)
static int efx_ef10_mtd_probe_partition(struct efx_nic *efx, struct efx_mcdi_mtd_partition *part, - unsigned int type) + unsigned int type, + unsigned long *found) { MCDI_DECLARE_BUF(inbuf, MC_CMD_NVRAM_METADATA_IN_LEN); MCDI_DECLARE_BUF(outbuf, MC_CMD_NVRAM_METADATA_OUT_LENMAX); const struct efx_ef10_nvram_type_info *info; size_t size, erase_size, outlen; + int type_idx = 0; bool protected; int rc;
- for (info = efx_ef10_nvram_types; ; info++) { - if (info == - efx_ef10_nvram_types + ARRAY_SIZE(efx_ef10_nvram_types)) + for (type_idx = 0; ; type_idx++) { + if (type_idx == EF10_NVRAM_PARTITION_COUNT) return -ENODEV; + info = efx_ef10_nvram_types + type_idx; if ((type & ~info->type_mask) == info->type) break; } @@ -5880,6 +5883,13 @@ static int efx_ef10_mtd_probe_partition(struct efx_nic *efx, if (protected) return -ENODEV; /* hide it */
+ /* If we've already exposed a partition of this type, hide this + * duplicate. All operations on MTDs are keyed by the type anyway, + * so we can't act on the duplicate. + */ + if (__test_and_set_bit(type_idx, found)) + return -EEXIST; + part->nvram_type = type;
MCDI_SET_DWORD(inbuf, NVRAM_METADATA_IN_TYPE, type); @@ -5908,6 +5918,7 @@ static int efx_ef10_mtd_probe_partition(struct efx_nic *efx, static int efx_ef10_mtd_probe(struct efx_nic *efx) { MCDI_DECLARE_BUF(outbuf, MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX); + DECLARE_BITMAP(found, EF10_NVRAM_PARTITION_COUNT); struct efx_mcdi_mtd_partition *parts; size_t outlen, n_parts_total, i, n_parts; unsigned int type; @@ -5936,11 +5947,13 @@ static int efx_ef10_mtd_probe(struct efx_nic *efx) for (i = 0; i < n_parts_total; i++) { type = MCDI_ARRAY_DWORD(outbuf, NVRAM_PARTITIONS_OUT_TYPE_ID, i); - rc = efx_ef10_mtd_probe_partition(efx, &parts[n_parts], type); - if (rc == 0) - n_parts++; - else if (rc != -ENODEV) + rc = efx_ef10_mtd_probe_partition(efx, &parts[n_parts], type, + found); + if (rc == -EEXIST || rc == -ENODEV) + continue; + if (rc) goto fail; + n_parts++; }
rc = efx_mtd_add(efx, &parts[0].common, n_parts, sizeof(*parts));
From: wenxu wenxu@ucloud.cn
[ Upstream commit d71b57532d70c03f4671dd04e84157ac6bf021b0 ]
ip l add dev tun type gretap key 1000 ip a a dev tun 10.0.0.1/24
Packets with tun-id 1000 can be recived by tun dev. But packet can't be sent through dev tun for non-tunnel-dst
With this patch: tunnel-dst can be get through lwtunnel like beflow: ip r a 10.0.0.7 encap ip dst 172.168.0.11 dev tun
Signed-off-by: wenxu wenxu@ucloud.cn Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/ipv4/ip_tunnel.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c index fabc299cb875f..7a31287ff1232 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c @@ -661,13 +661,19 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, dst = tnl_params->daddr; if (dst == 0) { /* NBMA tunnel */ + struct ip_tunnel_info *tun_info;
if (!skb_dst(skb)) { dev->stats.tx_fifo_errors++; goto tx_error; }
- if (skb->protocol == htons(ETH_P_IP)) { + tun_info = skb_tunnel_info(skb); + if (tun_info && (tun_info->mode & IP_TUNNEL_INFO_TX) && + ip_tunnel_info_af(tun_info) == AF_INET && + tun_info->key.u.ipv4.dst) + dst = tun_info->key.u.ipv4.dst; + else if (skb->protocol == htons(ETH_P_IP)) { rt = skb_rtable(skb); dst = rt_nexthop(rt, inner_iph->daddr); }
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit 50c2936634bcb1db78a8ca63249236810c11a80f ]
Digging through the ioctls with Al because of the previous patches, we found that on 64-bit decnet's dn_dev_ioctl() is wrong, because struct ifreq::ifr_ifru is actually 24 bytes (not 16 as expected from struct sockaddr) due to the ifru_map and ifru_settings members.
Clearly, decnet expects the ioctl to be called with a struct like struct ifreq_dn { char ifr_name[IFNAMSIZ]; struct sockaddr_dn ifr_addr; };
since it does struct ifreq *ifr = ...; struct sockaddr_dn *sdn = (struct sockaddr_dn *)&ifr->ifr_addr;
This means that DN_IFREQ_SIZE is too big for what it wants on 64-bit, as it is sizeof(struct ifreq) - sizeof(struct sockaddr) + sizeof(struct sockaddr_dn)
This assumes that sizeof(struct sockaddr) is the size of ifr_ifru but that isn't true.
Fix this to use offsetof(struct ifreq, ifr_ifru).
This indeed doesn't really matter much - the result is that we copy in/out 8 bytes more than we should on 64-bit platforms. In case the "struct ifreq_dn" lands just on the end of a page though it might lead to faults.
As far as I can tell, it has been like this forever, so it seems very likely that nobody cares.
Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/decnet/dn_dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c index df042b6d80b83..22876a197ebec 100644 --- a/net/decnet/dn_dev.c +++ b/net/decnet/dn_dev.c @@ -56,7 +56,7 @@ #include <net/dn_neigh.h> #include <net/dn_fib.h>
-#define DN_IFREQ_SIZE (sizeof(struct ifreq) - sizeof(struct sockaddr) + sizeof(struct sockaddr_dn)) +#define DN_IFREQ_SIZE (offsetof(struct ifreq, ifr_ifru) + sizeof(struct sockaddr_dn))
static char dn_rt_all_end_mcast[ETH_ALEN] = {0xAB,0x00,0x00,0x04,0x00,0x00}; static char dn_rt_all_rt_mcast[ETH_ALEN] = {0xAB,0x00,0x00,0x03,0x00,0x00};
From: Karsten Graul kgraul@linux.ibm.com
[ Upstream commit 77f838ace755d2f466536c44dac6c856f62cd901 ]
To prevent races between smc_lgr_terminate() and smc_conn_free() add an extra check of the lgr field before accessing it, and cancel a delayed free_work when a new smc connection is created. This fixes the problem that free_work cleared the lgr variable but smc_lgr_terminate() or smc_conn_free() still access it in parallel.
Signed-off-by: Karsten Graul kgraul@linux.ibm.com Signed-off-by: Ursula Braun ubraun@linux.ibm.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/smc/smc_core.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c index f04a037dc9677..0de788fa43e95 100644 --- a/net/smc/smc_core.c +++ b/net/smc/smc_core.c @@ -103,6 +103,8 @@ static void smc_lgr_unregister_conn(struct smc_connection *conn) struct smc_link_group *lgr = conn->lgr; int reduced = 0;
+ if (!lgr) + return; write_lock_bh(&lgr->conns_lock); if (conn->alert_token_local) { reduced = 1; @@ -431,6 +433,8 @@ int smc_conn_create(struct smc_sock *smc, __be32 peer_in_addr, local_contact = SMC_REUSE_CONTACT; conn->lgr = lgr; smc_lgr_register_conn(conn); /* add smc conn to lgr */ + if (delayed_work_pending(&lgr->free_work)) + cancel_delayed_work(&lgr->free_work); write_unlock_bh(&lgr->conns_lock); break; }
From: Jan Kara jack@suse.cz
[ Upstream commit 0803de78049fe1b0baf44bcddc727b036fb9139b ]
Currently, blktrace will not show requests that don't have any data as rq->__sector is initialized to -1 which is out of device range and thus discarded by act_log_check(). This is most notably the case for cache flush requests sent to the device. Fix the problem by making blk_rq_trace_sector() return 0 for requests without initialized sector.
Reviewed-by: Johannes Thumshirn jthumshirn@suse.de Signed-off-by: Jan Kara jack@suse.cz Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/blktrace_api.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h index 8804753805ac5..7bb2d8de9f308 100644 --- a/include/linux/blktrace_api.h +++ b/include/linux/blktrace_api.h @@ -116,7 +116,13 @@ extern void blk_fill_rwbs(char *rwbs, unsigned int op, int bytes);
static inline sector_t blk_rq_trace_sector(struct request *rq) { - return blk_rq_is_passthrough(rq) ? 0 : blk_rq_pos(rq); + /* + * Tracing should ignore starting sector for passthrough requests and + * requests where starting sector didn't get set. + */ + if (blk_rq_is_passthrough(rq) || blk_rq_pos(rq) == (sector_t)-1) + return 0; + return blk_rq_pos(rq); }
static inline unsigned int blk_rq_trace_nr_sectors(struct request *rq)
From: Hoang Le hoang.h.le@dektech.com.au
[ Upstream commit 7384b538d3aed2ed49d3575483d17aeee790fb06 ]
When we free skb at tipc_data_input, we return a 'false' boolean. Then, skb passed to subcalling tipc_link_input in tipc_link_rcv,
<snip> 1303 int tipc_link_rcv: ... 1354 if (!tipc_data_input(l, skb, l->inputq)) 1355 rc |= tipc_link_input(l, skb, l->inputq); </snip>
Fix it by simple changing to a 'true' boolean when skb is being free-ed. Then, tipc_link_rcv will bypassed to subcalling tipc_link_input as above condition.
Acked-by: Ying Xue ying.xue@windriver.com Acked-by: Jon Maloy maloy@donjonn.com Signed-off-by: Hoang Le hoang.h.le@dektech.com.au Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/tipc/link.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/tipc/link.c b/net/tipc/link.c index 631bfc7e9127e..da749916faac4 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -1073,7 +1073,7 @@ static bool tipc_data_input(struct tipc_link *l, struct sk_buff *skb, default: pr_warn("Dropping received illegal msg type\n"); kfree_skb(skb); - return false; + return true; }; }
From: Bert Kenward bkenward@solarflare.com
[ Upstream commit c65285428b6e7797f1bb063f33b0ae7e93397b7b ]
The bitmap of found partitions in efx_ef10_mtd_probe was not initialised, causing partitions to be suppressed based off whatever value was in the bitmap at the start.
Fixes: 3366463513f5 ("sfc: suppress duplicate nvmem partition types in efx_ef10_mtd_probe") Signed-off-by: Bert Kenward bkenward@solarflare.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/sfc/ef10.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c index cc3be94d05622..2d92a9fe4606c 100644 --- a/drivers/net/ethernet/sfc/ef10.c +++ b/drivers/net/ethernet/sfc/ef10.c @@ -5918,7 +5918,7 @@ static int efx_ef10_mtd_probe_partition(struct efx_nic *efx, static int efx_ef10_mtd_probe(struct efx_nic *efx) { MCDI_DECLARE_BUF(outbuf, MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX); - DECLARE_BITMAP(found, EF10_NVRAM_PARTITION_COUNT); + DECLARE_BITMAP(found, EF10_NVRAM_PARTITION_COUNT) = { 0 }; struct efx_mcdi_mtd_partition *parts; size_t outlen, n_parts_total, i, n_parts; unsigned int type;
From: Eric Dumazet edumazet@google.com
[ Upstream commit 5bf325a53202b8728cf7013b72688c46071e212e ]
With many active TCP sockets, fat TCP sockets could fool __sk_mem_raise_allocated() thanks to an overflow.
They would increase their share of the memory, instead of decreasing it.
Signed-off-by: Eric Dumazet edumazet@google.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- include/net/sock.h | 2 +- net/core/sock.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/net/sock.h b/include/net/sock.h index 780c6c0a86f04..0af46cbd3649c 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -1232,7 +1232,7 @@ static inline void sk_sockets_allocated_inc(struct sock *sk) percpu_counter_inc(sk->sk_prot->sockets_allocated); }
-static inline int +static inline u64 sk_sockets_allocated_read_positive(struct sock *sk) { return percpu_counter_read_positive(sk->sk_prot->sockets_allocated); diff --git a/net/core/sock.c b/net/core/sock.c index 7ccbcd853cbce..90ccbbf9e6b00 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -2357,7 +2357,7 @@ int __sk_mem_raise_allocated(struct sock *sk, int size, int amt, int kind) }
if (sk_has_memory_pressure(sk)) { - int alloc; + u64 alloc;
if (!sk_under_memory_pressure(sk)) return 1;
From: Maciej Kwiecien maciej.kwiecien@nokia.com
[ Upstream commit d1f20c03f48102e52eb98b8651d129b83134cae4 ]
hb_timer might not start at all for a particular transport because its start is conditional. In a result a node is not sending heartbeats.
Function sctp_transport_reset_hb_timer has two roles: - initial start of hb_timer for a given transport, - update expire date of hb_timer for a given transport. The function is optimized to update timer's expire only if it is before a new calculated one but this comparison is invalid for a timer which has not yet started. Such a timer has expire == 0 and if a new expire value is bigger than (MAX_JIFFIES / 2 + 2) then "time_before" macro will fail and timer will not start resulting in no heartbeat packets send by the node.
This was found when association was initialized within first 5 mins after system boot due to jiffies init value which is near to MAX_JIFFIES.
Test kernel version: 4.9.154 (ARCH=arm) hb_timer.expire = 0; //initialized, not started timer new_expire = MAX_JIFFIES / 2 + 2; //or more time_before(hb_timer.expire, new_expire) == false
Fixes: ba6f5e33bdbb ("sctp: avoid refreshing heartbeat timer too often") Reported-by: Marcin Stojek marcin.stojek@nokia.com Tested-by: Marcin Stojek marcin.stojek@nokia.com Signed-off-by: Maciej Kwiecien maciej.kwiecien@nokia.com Reviewed-by: Alexander Sverdlin alexander.sverdlin@nokia.com Acked-by: Marcelo Ricardo Leitner marcelo.leitner@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/sctp/transport.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/sctp/transport.c b/net/sctp/transport.c index 43105cf04bc45..274df899e7bfa 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c @@ -210,7 +210,8 @@ void sctp_transport_reset_hb_timer(struct sctp_transport *transport)
/* When a data chunk is sent, reset the heartbeat interval. */ expires = jiffies + sctp_transport_timeout(transport); - if (time_before(transport->hb_timer.expires, expires) && + if ((time_before(transport->hb_timer.expires, expires) || + !timer_pending(&transport->hb_timer)) && !mod_timer(&transport->hb_timer, expires + prandom_u32_max(transport->rto))) sctp_transport_hold(transport);
From: Peng Sun sironhide0null@gmail.com
[ Upstream commit 781e62823cb81b972dc8652c1827205cda2ac9ac ]
In bpf/syscall.c, bpf_map_get_fd_by_id() use bpf_map_inc_not_zero() to increase the refcount, both map->refcnt and map->usercnt. Then, if bpf_map_new_fd() fails, should handle map->usercnt too.
Fixes: bd5f5f4ecb78 ("bpf: Add BPF_MAP_GET_FD_BY_ID") Signed-off-by: Peng Sun sironhide0null@gmail.com Acked-by: Martin KaFai Lau kafai@fb.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/bpf/syscall.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 59d2e94ecb798..34110450a78f2 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -1354,7 +1354,7 @@ static int bpf_map_get_fd_by_id(const union bpf_attr *attr)
fd = bpf_map_new_fd(map); if (fd < 0) - bpf_map_put(map); + bpf_map_put_with_uref(map);
return fd; }
From: Andy Shevchenko andriy.shevchenko@linux.intel.com
[ Upstream commit f4d7b3e23d259c44f1f1c39645450680fcd935d6 ]
1 << 31 is Undefined Behaviour according to the C standard. Use U type modifier to avoid theoretical overflow.
Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/netdevice.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 40b830d55fe50..4725a9d9597fc 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -3522,7 +3522,7 @@ static inline u32 netif_msg_init(int debug_value, int default_msg_enable_bits) if (debug_value == 0) /* no output */ return 0; /* set low N bits */ - return (1 << debug_value) - 1; + return (1U << debug_value) - 1; }
static inline void __netif_tx_lock(struct netdev_queue *txq, int cpu)
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
[ Upstream commit 8ed0579c12b2fe56a1fac2f712f58fc26c1dc49b ]
debugfs can now report an error code if something went wrong instead of just NULL. So if the return value is to be used as a "real" dentry, it needs to be checked if it is an error before dereferencing it.
This is now happening because of ff9fb72bc077 ("debugfs: return error values, not NULL"). syzbot has found a way to trigger multiple debugfs files attempting to be created, which fails, and then the error code gets passed to dentry_path_raw() which obviously does not like it.
Reported-by: Eric Biggers ebiggers@kernel.org Reported-and-tested-by: syzbot+7857962b4d45e602b8ad@syzkaller.appspotmail.com Cc: "Radim Krčmář" rkrcmar@redhat.com Cc: kvm@vger.kernel.org Acked-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- virt/kvm/kvm_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index cdaacdf7bc877..deff4b3eb9722 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -3989,7 +3989,7 @@ static void kvm_uevent_notify_change(unsigned int type, struct kvm *kvm) } add_uevent_var(env, "PID=%d", kvm->userspace_pid);
- if (kvm->debugfs_dentry) { + if (!IS_ERR_OR_NULL(kvm->debugfs_dentry)) { char *tmp, *p = kmalloc(PATH_MAX, GFP_KERNEL);
if (p) {
From: Peng Sun sironhide0null@gmail.com
[ Upstream commit 352d20d611414715353ee65fc206ee57ab1a6984 ]
In bpf/syscall.c, map_create() first set map->usercnt to 1, a file descriptor is supposed to return to userspace. When bpf_map_new_fd() fails, drop the refcount.
Fixes: bd5f5f4ecb78 ("bpf: Add BPF_MAP_GET_FD_BY_ID") Signed-off-by: Peng Sun sironhide0null@gmail.com Acked-by: Martin KaFai Lau kafai@fb.com Signed-off-by: Alexei Starovoitov ast@kernel.org Signed-off-by: Daniel Borkmann daniel@iogearbox.net Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/bpf/syscall.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 34110450a78f2..f5c1d5479ba3d 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -348,12 +348,12 @@ static int map_create(union bpf_attr *attr) err = bpf_map_new_fd(map); if (err < 0) { /* failed to allocate fd. - * bpf_map_put() is needed because the above + * bpf_map_put_with_uref() is needed because the above * bpf_map_alloc_id() has published the map * to the userspace and the userspace may * have refcnt-ed it through BPF_MAP_GET_FD_BY_ID. */ - bpf_map_put(map); + bpf_map_put_with_uref(map); return err; }
From: Yunsheng Lin linyunsheng@huawei.com
[ Upstream commit 4a402f47cfce904051cd8b31bef4fe2910d9dce9 ]
According to firmware error code definition, the error code of 2 means NOT_SUPPORTED, this patch changes it to NOT_SUPPORTED.
Signed-off-by: Yunsheng Lin linyunsheng@huawei.com Signed-off-by: Peng Li lipeng321@huawei.com Signed-off-by: Huazhong Tan tanhuazhong@huawei.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c | 2 ++ drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c index 8b511e6e0ce9d..396ea0db71023 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c @@ -251,6 +251,8 @@ int hclge_cmd_send(struct hclge_hw *hw, struct hclge_desc *desc, int num) if ((enum hclge_cmd_return_status)desc_ret == HCLGE_CMD_EXEC_SUCCESS) retval = 0; + else if (desc_ret == HCLGE_CMD_NOT_SUPPORTED) + retval = -EOPNOTSUPP; else retval = -EIO; hw->cmq.last_status = (enum hclge_cmd_status)desc_ret; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h index 758cf39481312..3823ae6303ad6 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h @@ -52,7 +52,7 @@ struct hclge_cmq_ring { enum hclge_cmd_return_status { HCLGE_CMD_EXEC_SUCCESS = 0, HCLGE_CMD_NO_AUTH = 1, - HCLGE_CMD_NOT_EXEC = 2, + HCLGE_CMD_NOT_SUPPORTED = 2, HCLGE_CMD_QUEUE_FULL = 3, };
From: Aaron Ma aaron.ma@canonical.com
[ Upstream commit bb6bccba390c7d743c1e4427de4ef284c8cc6869 ]
Add a non-NULL check to fix potential NULL pointer dereference Cleanup code to call function once.
Signed-off-by: Aaron Ma aaron.ma@canonical.com Fixes: 2bf9a0a12749b ('iommu/amd: Add iommu support for ACPI HID devices') Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iommu/amd_iommu.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 07b6cf58fd99b..d09c24825734e 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -139,10 +139,14 @@ static struct lock_class_key reserved_rbtree_key; static inline int match_hid_uid(struct device *dev, struct acpihid_map_entry *entry) { + struct acpi_device *adev = ACPI_COMPANION(dev); const char *hid, *uid;
- hid = acpi_device_hid(ACPI_COMPANION(dev)); - uid = acpi_device_uid(ACPI_COMPANION(dev)); + if (!adev) + return -ENODEV; + + hid = acpi_device_hid(adev); + uid = acpi_device_uid(adev);
if (!hid || !(*hid)) return -ENODEV;
From: Chris Coulson chris.coulson@canonical.com
[ Upstream commit 201218e4d3dfa1346e30997f48725acce3f26d01 ]
Although the apparmorfs dentries are always dropped from the dentry cache when the usage count drops to zero, there is no guarantee that this will happen in aafs_remove(), as another thread might still be using it. In this scenario, this means that the dentry will temporarily continue to appear in the results of lookups, even after the call to aafs_remove().
In the case of removal of a profile - it also causes simple_rmdir() on the profile directory to fail, as the directory won't be empty until the usage counts of all child dentries have decreased to zero. This results in the dentry for the profile directory leaking and appearing empty in the file system tree forever.
Signed-off-by: Chris Coulson chris.coulson@canonical.com Signed-off-by: John Johansen john.johansen@canonical.com Signed-off-by: Sasha Levin sashal@kernel.org --- security/apparmor/apparmorfs.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c index dd746bd69a9b2..c106988c1b254 100644 --- a/security/apparmor/apparmorfs.c +++ b/security/apparmor/apparmorfs.c @@ -363,6 +363,7 @@ static void aafs_remove(struct dentry *dentry) simple_rmdir(dir, dentry); else simple_unlink(dir, dentry); + d_delete(dentry); dput(dentry); } inode_unlock(dir);
From: John Garry john.garry@huawei.com
[ Upstream commit cec9771d2e954650095aa37a6a97722c8194e7d2 ]
+----------+ +----------+ | | | | | |--- 3.0 G ---| |--- 6.0 G --- SAS disk | | | | | |--- 3.0 G ---| |--- 6.0 G --- SAS disk |initiator | | | | device |--- 3.0 G ---| Expander |--- 6.0 G --- SAS disk | | | | | |--- 3.0 G ---| |--- 6.0 G --- SATA disk -->failed to connect | | | | | | | |--- 6.0 G --- SATA disk -->failed to connect | | | | +----------+ +----------+
According to Serial Attached SCSI - 1.1 (SAS-1.1): If an expander PHY attached to a SATA PHY is using a physical link rate greater than the maximum connection rate supported by the pathway from an STP initiator port, a management application client should use the SMP PHY CONTROL function (see 10.4.3.10) to set the PROGRAMMED MAXIMUM PHYSICAL LINK RATE field of the expander PHY to the maximum connection rate supported by the pathway from that STP initiator port.
Currently libsas does not support checking if this condition occurs, nor rectifying when it does.
Such a condition is not at all common, however it has been seen on some pre-silicon environments where the initiator PHY only supports a 1.5 Gbit maximum linkrate, mated with 12G expander PHYs and 3/6G SATA phy.
This patch adds support for checking and rectifying this condition during initial device discovery only.
We do support checking min pathway connection rate during revalidation phase, when new devices can be detected in the topology. However we do not support in the case of the the user reprogramming PHY linkrates, such that min pathway condition is not met/maintained.
A note on root port PHY rates: The libsas root port PHY rates calculation is broken. Libsas sets the rates (min, max, and current linkrate) of a root port to the same linkrate of the first PHY member of that same port. In doing so, it assumes that all other PHYs which subsequently join the port to have the same negotiated linkrate, when they could actually be different.
In practice this doesn't happen, as initiator and expander PHYs are normally initialised with consistent min/max linkrates.
This has not caused an issue so far, so leave alone for now.
Tested-by: Jian Luo luojian5@huawei.com Signed-off-by: John Garry john.garry@huawei.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/libsas/sas_expander.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index 7f2d00354a850..63c44eaabf69e 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c @@ -817,6 +817,26 @@ static struct domain_device *sas_ex_discover_end_dev(
#ifdef CONFIG_SCSI_SAS_ATA if ((phy->attached_tproto & SAS_PROTOCOL_STP) || phy->attached_sata_dev) { + if (child->linkrate > parent->min_linkrate) { + struct sas_phy_linkrates rates = { + .maximum_linkrate = parent->min_linkrate, + .minimum_linkrate = parent->min_linkrate, + }; + int ret; + + pr_notice("ex %016llx phy%02d SATA device linkrate > min pathway connection rate, attempting to lower device linkrate\n", + SAS_ADDR(child->sas_addr), phy_id); + ret = sas_smp_phy_control(parent, phy_id, + PHY_FUNC_LINK_RESET, &rates); + if (ret) { + pr_err("ex %016llx phy%02d SATA device could not set linkrate (%d)\n", + SAS_ADDR(child->sas_addr), phy_id, ret); + goto out_free; + } + pr_notice("ex %016llx phy%02d SATA device set linkrate successfully\n", + SAS_ADDR(child->sas_addr), phy_id); + child->linkrate = child->min_linkrate; + } res = sas_get_ata_info(child, phy); if (res) goto out_free;
From: James Morse james.morse@arm.com
[ Upstream commit 78b0b690f6558ed788dccafa45965325dd11ba89 ]
oops_begin() exists to group printk() messages with the oops message printed by die(). To reach this caller we know that platform firmware took this error first, then notified the OS via NMI with a 'panic' severity.
Don't wait for another CPU to release the die-lock before panic()ing, our only goal is to print this fatal error and panic().
This code is always called in_nmi(), and since commit 42a0bb3f7138 ("printk/nmi: generic solution for safe printk in NMI"), it has been safe to call printk() from this context. Messages are batched in a per-cpu buffer and printed via irq-work, or a call back from panic().
Link: https://patchwork.kernel.org/patch/10313555/ Acked-by: Borislav Petkov bp@suse.de Signed-off-by: James Morse james.morse@arm.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/acpi/apei/ghes.c | 2 -- 1 file changed, 2 deletions(-)
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index 5889f6407fea8..9c31c7cd5cb5e 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -33,7 +33,6 @@ #include <linux/interrupt.h> #include <linux/timer.h> #include <linux/cper.h> -#include <linux/kdebug.h> #include <linux/platform_device.h> #include <linux/mutex.h> #include <linux/ratelimit.h> @@ -936,7 +935,6 @@ static int ghes_notify_nmi(unsigned int cmd, struct pt_regs *regs)
sev = ghes_severity(ghes->estatus->error_severity); if (sev >= GHES_SEV_PANIC) { - oops_begin(); ghes_print_queued_estatus(); __ghes_panic(ghes); }
From: James Morse james.morse@arm.com
[ Upstream commit 0ac234be1a9497498e57d958f4251f5257b116b4 ]
The ghes code is careful to parse and round firmware's advertised memory requirements for CPER records, up to a maximum of 64K. However when ghes_estatus_pool_expand() does its work, it splits the requested size into PAGE_SIZE granules.
This means if firmware generates 5K of CPER records, and correctly describes this in the table, __process_error() will silently fail as it is unable to allocate more than PAGE_SIZE.
Switch the estatus pool to vmalloc() memory. On x86 vmalloc() memory may fault and be fixed up by vmalloc_fault(). To prevent this call vmalloc_sync_all() before an NMI handler could discover the memory.
Signed-off-by: James Morse james.morse@arm.com Reviewed-by: Borislav Petkov bp@suse.de Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/acpi/apei/ghes.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index 9c31c7cd5cb5e..cd6fae6ad4c2a 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -170,40 +170,40 @@ static int ghes_estatus_pool_init(void) return 0; }
-static void ghes_estatus_pool_free_chunk_page(struct gen_pool *pool, +static void ghes_estatus_pool_free_chunk(struct gen_pool *pool, struct gen_pool_chunk *chunk, void *data) { - free_page(chunk->start_addr); + vfree((void *)chunk->start_addr); }
static void ghes_estatus_pool_exit(void) { gen_pool_for_each_chunk(ghes_estatus_pool, - ghes_estatus_pool_free_chunk_page, NULL); + ghes_estatus_pool_free_chunk, NULL); gen_pool_destroy(ghes_estatus_pool); }
static int ghes_estatus_pool_expand(unsigned long len) { - unsigned long i, pages, size, addr; - int ret; + unsigned long size, addr;
ghes_estatus_pool_size_request += PAGE_ALIGN(len); size = gen_pool_size(ghes_estatus_pool); if (size >= ghes_estatus_pool_size_request) return 0; - pages = (ghes_estatus_pool_size_request - size) / PAGE_SIZE; - for (i = 0; i < pages; i++) { - addr = __get_free_page(GFP_KERNEL); - if (!addr) - return -ENOMEM; - ret = gen_pool_add(ghes_estatus_pool, addr, PAGE_SIZE, -1); - if (ret) - return ret; - }
- return 0; + addr = (unsigned long)vmalloc(PAGE_ALIGN(len)); + if (!addr) + return -ENOMEM; + + /* + * New allocation must be visible in all pgd before it can be found by + * an NMI allocating from the pool. + */ + vmalloc_sync_all(); + + return gen_pool_add(ghes_estatus_pool, addr, PAGE_ALIGN(len), -1); }
static int map_gen_v2(struct ghes *ghes)
From: John Garry john.garry@huawei.com
[ Upstream commit 01929a65dfa13e18d89264ab1378854a91857e59 ]
Currently the SMP PHY control execution result is checked, however the function result for the command is not.
As such, we may be missing all potential errors, like SMP FUNCTION FAILED, INVALID REQUEST FRAME LENGTH, etc., meaning the PHY control request has failed.
In some scenarios we need to ensure the function result is accepted, so add a check for this.
Tested-by: Jian Luo luojian5@huawei.com Signed-off-by: John Garry john.garry@huawei.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/libsas/sas_expander.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index 63c44eaabf69e..f77d72f01da91 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c @@ -614,7 +614,14 @@ int sas_smp_phy_control(struct domain_device *dev, int phy_id, }
res = smp_execute_task(dev, pc_req, PC_REQ_SIZE, pc_resp,PC_RESP_SIZE); - + if (res) { + pr_err("ex %016llx phy%02d PHY control failed: %d\n", + SAS_ADDR(dev->sas_addr), phy_id, res); + } else if (pc_resp[2] != SMP_RESP_FUNC_ACC) { + pr_err("ex %016llx phy%02d PHY control failed: function result 0x%x\n", + SAS_ADDR(dev->sas_addr), phy_id, pc_resp[2]); + res = pc_resp[2]; + } kfree(pc_resp); kfree(pc_req); return res;
From: Gen Zhang blackgod016574@gmail.com
[ Upstream commit efa9ace68e487ddd29c2b4d6dd23242158f1f607 ]
In dlpar_parse_cc_property(), 'prop->name' is allocated by kstrdup(). kstrdup() may return NULL, so it should be checked and handle error. And prop should be freed if 'prop->name' is NULL.
Signed-off-by: Gen Zhang blackgod016574@gmail.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/platforms/pseries/dlpar.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c index f4e6565dd7a94..fb2876a84fbe6 100644 --- a/arch/powerpc/platforms/pseries/dlpar.c +++ b/arch/powerpc/platforms/pseries/dlpar.c @@ -63,6 +63,10 @@ static struct property *dlpar_parse_cc_property(struct cc_workarea *ccwa)
name = (char *)ccwa + be32_to_cpu(ccwa->name_offset); prop->name = kstrdup(name, GFP_KERNEL); + if (!prop->name) { + dlpar_free_cc_property(prop); + return NULL; + }
prop->length = be32_to_cpu(ccwa->prop_length); value = (char *)ccwa + be32_to_cpu(ccwa->prop_offset);
From: Boris Brezillon bbrezillon@kernel.org
[ Upstream commit bda2ab56356b9acdfab150f31c4bac9846253092 ]
Commit 2b6f0090a333 ("mtd: Check add_mtd_device() ret code") contained a leftover of the debug session that led to this bug fix. Remove this pr_info().
Fixes: 2b6f0090a333 ("mtd: Check add_mtd_device() ret code") Signed-off-by: Boris Brezillon bbrezillon@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mtd/mtdpart.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index 27d9785487d69..45626b0eed643 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c @@ -698,7 +698,6 @@ err_remove_part: mutex_unlock(&mtd_partitions_mutex);
free_partition(new); - pr_info("%s:%i\n", __func__, __LINE__);
return ret; }
From: Vlastimil Babka vbabka@suse.cz
The mainline commit 8fde12ca79af ("mm: prevent get_user_pages() from overflowing page refcount") was backported to 4.14.y stable as commit 04198de24771. The backport however missed that in 4.14, there are several arch-specific gup.c versions with fast gup implementations, so these do not prevent refcount overflow.
This stable-only commit fixes the s390 version, and is based on the backport in SUSE SLES/openSUSE 4.12-based kernels.
The remaining architectures with own gup.c are sparc, mips, sh. It's unlikely the known overflow scenario based on FUSE, which needs 140GB of RAM, is a problem for those architectures, and I don't feel confident enough to patch them.
Signed-off-by: Vlastimil Babka vbabka@suse.cz Signed-off-by: Sasha Levin sashal@kernel.org --- arch/s390/mm/gup.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/arch/s390/mm/gup.c b/arch/s390/mm/gup.c index 05c8abd864f1d..9bce54eac0b07 100644 --- a/arch/s390/mm/gup.c +++ b/arch/s390/mm/gup.c @@ -39,7 +39,8 @@ static inline int gup_pte_range(pmd_t *pmdp, pmd_t pmd, unsigned long addr, VM_BUG_ON(!pfn_valid(pte_pfn(pte))); page = pte_page(pte); head = compound_head(page); - if (!page_cache_get_speculative(head)) + if (unlikely(WARN_ON_ONCE(page_ref_count(head) < 0) + || !page_cache_get_speculative(head))) return 0; if (unlikely(pte_val(pte) != pte_val(*ptep))) { put_page(head); @@ -77,7 +78,8 @@ static inline int gup_huge_pmd(pmd_t *pmdp, pmd_t pmd, unsigned long addr, refs++; } while (addr += PAGE_SIZE, addr != end);
- if (!page_cache_add_speculative(head, refs)) { + if (unlikely(WARN_ON_ONCE(page_ref_count(head) < 0) + || !page_cache_add_speculative(head, refs))) { *nr -= refs; return 0; } @@ -151,7 +153,8 @@ static int gup_huge_pud(pud_t *pudp, pud_t pud, unsigned long addr, refs++; } while (addr += PAGE_SIZE, addr != end);
- if (!page_cache_add_speculative(head, refs)) { + if (unlikely(WARN_ON_ONCE(page_ref_count(head) < 0) + || !page_cache_add_speculative(head, refs))) { *nr -= refs; return 0; }
From: Eugen Hristev eugen.hristev@microchip.com
commit 263eaf8f172d9f44e15d6aca85fe40ec18d2c477 upstream.
The regmap update bits call was not selecting the proper mask, considering the bits which was updating. Update the mask from call to also include OSCBYPASS. Removed MOSCEN which was not updated.
Fixes: 1bdf02326b71 ("clk: at91: make use of syscon/regmap internally") Signed-off-by: Eugen Hristev eugen.hristev@microchip.com Link: https://lkml.kernel.org/r/1568042692-11784-1-git-send-email-eugen.hristev@mi... Acked-by: Alexandre Belloni alexandre.belloni@bootlin.com Reviewed-by: Claudiu Beznea claudiu.beznea@microchip.com Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Lee Jones lee.jones@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/clk/at91/clk-main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/clk/at91/clk-main.c +++ b/drivers/clk/at91/clk-main.c @@ -162,7 +162,7 @@ at91_clk_register_main_osc(struct regmap if (bypass) regmap_update_bits(regmap, AT91_CKGR_MOR, MOR_KEY_MASK | - AT91_PMC_MOSCEN, + AT91_PMC_OSCBYPASS, AT91_PMC_OSCBYPASS | AT91_PMC_KEY);
hw = &osc->hw;
From: Alexandre Belloni alexandre.belloni@bootlin.com
commit c1e4580a1d0ff510d56268c1fc7fcfeec366fe70 upstream.
Set gck->audio_pll_allowed in at91_clk_register_generated. This makes it easier to do it from code that is not parsing device tree.
Also, this fixes an issue where the resulting clk_hw can be dereferenced before being tested for error.
Fixes: 1a1a36d72e3d ("clk: at91: clk-generated: make gclk determine audio_pll rate") Signed-off-by: Alexandre Belloni alexandre.belloni@bootlin.com Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Lee Jones lee.jones@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/clk/at91/clk-generated.c | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-)
--- a/drivers/clk/at91/clk-generated.c +++ b/drivers/clk/at91/clk-generated.c @@ -284,7 +284,7 @@ static void clk_generated_startup(struct static struct clk_hw * __init at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock, const char *name, const char **parent_names, - u8 num_parents, u8 id, + u8 num_parents, u8 id, bool pll_audio, const struct clk_range *range) { struct clk_generated *gck; @@ -308,6 +308,7 @@ at91_clk_register_generated(struct regma gck->regmap = regmap; gck->lock = lock; gck->range = *range; + gck->audio_pll_allowed = pll_audio;
clk_generated_startup(gck); hw = &gck->hw; @@ -333,7 +334,6 @@ static void __init of_sama5d2_clk_genera struct device_node *gcknp; struct clk_range range = CLK_RANGE(0, 0); struct regmap *regmap; - struct clk_generated *gck;
num_parents = of_clk_get_parent_count(np); if (num_parents == 0 || num_parents > GENERATED_SOURCE_MAX) @@ -350,6 +350,8 @@ static void __init of_sama5d2_clk_genera return;
for_each_child_of_node(np, gcknp) { + bool pll_audio = false; + if (of_property_read_u32(gcknp, "reg", &id)) continue;
@@ -362,24 +364,14 @@ static void __init of_sama5d2_clk_genera of_at91_get_clk_range(gcknp, "atmel,clk-output-range", &range);
+ if (of_device_is_compatible(np, "atmel,sama5d2-clk-generated") && + (id == GCK_ID_I2S0 || id == GCK_ID_I2S1 || + id == GCK_ID_CLASSD)) + pll_audio = true; + hw = at91_clk_register_generated(regmap, &pmc_pcr_lock, name, parent_names, num_parents, - id, &range); - - gck = to_clk_generated(hw); - - if (of_device_is_compatible(np, - "atmel,sama5d2-clk-generated")) { - if (gck->id == GCK_ID_SSC0 || gck->id == GCK_ID_SSC1 || - gck->id == GCK_ID_I2S0 || gck->id == GCK_ID_I2S1 || - gck->id == GCK_ID_CLASSD) - gck->audio_pll_allowed = true; - else - gck->audio_pll_allowed = false; - } else { - gck->audio_pll_allowed = false; - } - + id, pll_audio, &range); if (IS_ERR(hw)) continue;
From: Pan Bian bianpan2016@163.com
commit b7aa39a2ed0112d07fc277ebd24a08a7b2368ab9 upstream.
The variable skb is released via kfree_skb() when the return value of _rtl92e_tx is not zero. However, after that, skb is accessed again to read its length, which may result in a use after free bug. This patch fixes the bug by moving the release operation to where skb is never used later.
Signed-off-by: Pan Bian bianpan2016@163.com Reviewed-by: Dan Carpenter dan.carpenter@oracle.com Cc: stable stable@vger.kernel.org Link: https://lore.kernel.org/r/1572965351-6745-1-git-send-email-bianpan2016@163.c... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/staging/rtl8192e/rtl8192e/rtl_core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
--- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -1630,14 +1630,15 @@ static void _rtl92e_hard_data_xmit(struc memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev)); skb_push(skb, priv->rtllib->tx_headroom); ret = _rtl92e_tx(dev, skb); - if (ret != 0) - kfree_skb(skb);
if (queue_index != MGNT_QUEUE) { priv->rtllib->stats.tx_bytes += (skb->len - priv->rtllib->tx_headroom); priv->rtllib->stats.tx_packets++; } + + if (ret != 0) + kfree_skb(skb); }
static int _rtl92e_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
From: Hans de Goede hdegoede@redhat.com
commit 2d9d2491530a156b9a5614adf9dc79285e35d55e upstream.
The driver only binds by SDIO device-ids, all the ACPI device-id does is causing the driver to load unnecessarily on devices where the DSDT contains a bogus OBDA8723 device.
Signed-off-by: Hans de Goede hdegoede@redhat.com Cc: stable stable@vger.kernel.org Link: https://lore.kernel.org/r/20191111113846.24940-2-hdegoede@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/staging/rtl8723bs/os_dep/sdio_intf.c | 6 ------ 1 file changed, 6 deletions(-)
--- a/drivers/staging/rtl8723bs/os_dep/sdio_intf.c +++ b/drivers/staging/rtl8723bs/os_dep/sdio_intf.c @@ -30,13 +30,7 @@ static const struct sdio_device_id sdio_ { SDIO_DEVICE(0x024c, 0xb723), }, { /* end: all zeroes */ }, }; -static const struct acpi_device_id acpi_ids[] = { - {"OBDA8723", 0x0000}, - {} -}; - MODULE_DEVICE_TABLE(sdio, sdio_ids); -MODULE_DEVICE_TABLE(acpi, acpi_ids);
static int rtw_drv_init(struct sdio_func *func, const struct sdio_device_id *id); static void rtw_dev_remove(struct sdio_func *func);
From: Hans de Goede hdegoede@redhat.com
commit 3d5f1eedbfd22ceea94b39989d6021b1958181f4 upstream.
Add 024c:0525 to the list of SDIO device-ids, based on a patch found in the Android X86 kernels. According to that patch this device id is used on the Alcatel Plus 10 device.
Reported-and-tested-by: youling257 youling257@gmail.com Signed-off-by: Hans de Goede hdegoede@redhat.com Cc: stable stable@vger.kernel.org Link: https://lore.kernel.org/r/20191111113846.24940-1-hdegoede@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/staging/rtl8723bs/os_dep/sdio_intf.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/staging/rtl8723bs/os_dep/sdio_intf.c +++ b/drivers/staging/rtl8723bs/os_dep/sdio_intf.c @@ -25,6 +25,7 @@ static const struct sdio_device_id sdio_ids[] = { { SDIO_DEVICE(0x024c, 0x0523), }, + { SDIO_DEVICE(0x024c, 0x0525), }, { SDIO_DEVICE(0x024c, 0x0623), }, { SDIO_DEVICE(0x024c, 0x0626), }, { SDIO_DEVICE(0x024c, 0xb723), },
From: Fabio D'Urso fabiodurso@hotmail.it
commit c1a1f273d0825774c80896b8deb1c9ea1d0b91e3 upstream.
This device presents itself as a USB hub with three attached devices: - An ACM serial port connected to the GPS module (not affected by this commit) - An FTDI serial port connected to the GPS module (1546:0502) - Another FTDI serial port connected to the ODIN-W2 radio module (1546:0503)
This commit registers U-Blox's VID and the PIDs of the second and third devices.
Datasheet: https://www.u-blox.com/sites/default/files/C099-F9P-AppBoard-Mbed-OS3-FW_Use...
Signed-off-by: Fabio D'Urso fabiodurso@hotmail.it Cc: stable stable@vger.kernel.org Signed-off-by: Johan Hovold johan@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/serial/ftdi_sio.c | 3 +++ drivers/usb/serial/ftdi_sio_ids.h | 7 +++++++ 2 files changed, 10 insertions(+)
--- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -1028,6 +1028,9 @@ static const struct usb_device_id id_tab /* Sienna devices */ { USB_DEVICE(FTDI_VID, FTDI_SIENNA_PID) }, { USB_DEVICE(ECHELON_VID, ECHELON_U20_PID) }, + /* U-Blox devices */ + { USB_DEVICE(UBLOX_VID, UBLOX_C099F9P_ZED_PID) }, + { USB_DEVICE(UBLOX_VID, UBLOX_C099F9P_ODIN_PID) }, { } /* Terminating entry */ };
--- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -1558,3 +1558,10 @@ */ #define UNJO_VID 0x22B7 #define UNJO_ISODEBUG_V1_PID 0x150D + +/* + * U-Blox products (http://www.u-blox.com). + */ +#define UBLOX_VID 0x1546 +#define UBLOX_C099F9P_ZED_PID 0x0502 +#define UBLOX_C099F9P_ODIN_PID 0x0503
From: Alexander Usyskin alexander.usyskin@intel.com
commit 7a2b9e6ec84588b0be65cc0ae45a65bac431496b upstream.
Add parent device name to the name of devices on bus to avoid device names collisions for same client UUID available from different MEI heads. Namely this prevents sysfs collision under /sys/bus/mei/device/
In the device part leave just UUID other parameters that are required for device matching are not required here and are just bloating the name.
Cc: stable@vger.kernel.org Signed-off-by: Alexander Usyskin alexander.usyskin@intel.com Signed-off-by: Tomas Winkler tomas.winkler@intel.com Link: https://lore.kernel.org/r/20191105150514.14010-1-tomas.winkler@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/misc/mei/bus.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
--- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c @@ -850,15 +850,16 @@ static const struct device_type mei_cl_d
/** * mei_cl_bus_set_name - set device name for me client device + * <controller>-<client device> + * Example: 0000:00:16.0-55213584-9a29-4916-badf-0fb7ed682aeb * * @cldev: me client device */ static inline void mei_cl_bus_set_name(struct mei_cl_device *cldev) { - dev_set_name(&cldev->dev, "mei:%s:%pUl:%02X", - cldev->name, - mei_me_cl_uuid(cldev->me_cl), - mei_me_cl_ver(cldev->me_cl)); + dev_set_name(&cldev->dev, "%s-%pUl", + dev_name(cldev->bus->dev), + mei_me_cl_uuid(cldev->me_cl)); }
/**
From: Steffen Klassert steffen.klassert@secunet.com
commit 86c6739eda7d2a03f2db30cbee67a5fb81afa8ba upstream.
We leak the page that we use to create skb page fragments when destroying the xfrm_state. Fix this by dropping a page reference if a page was assigned to the xfrm_state.
Fixes: cac2661c53f3 ("esp4: Avoid skb_cow_data whenever possible") Reported-by: JD jdtxs00@gmail.com Reported-by: Paul Wouters paul@nohats.ca Signed-off-by: Steffen Klassert steffen.klassert@secunet.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- net/xfrm/xfrm_state.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -449,6 +449,8 @@ static void xfrm_state_gc_destroy(struct x->type->destructor(x); xfrm_put_type(x->type); } + if (x->xfrag.page) + put_page(x->xfrag.page); xfrm_dev_state_free(x); security_xfrm_state_free(x); kfree(x);
From: Eugen Hristev eugen.hristev@microchip.com
commit a0816e5088baab82aa738d61a55513114a673c8e upstream.
Control DO_WHITE_BALANCE is a button, with read only and execute-on-write flags. Adding this control in the proper list in the fill function.
After adding it here, we can see output of v4l2-ctl -L do_white_balance 0x0098090d (button) : flags=write-only, execute-on-write
Signed-off-by: Eugen Hristev eugen.hristev@microchip.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+samsung@kernel.org Signed-off-by: Lee Jones lee.jones@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/media/v4l2-core/v4l2-ctrls.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ b/drivers/media/v4l2-core/v4l2-ctrls.c @@ -1014,6 +1014,7 @@ void v4l2_ctrl_fill(u32 id, const char * case V4L2_CID_FLASH_STROBE_STOP: case V4L2_CID_AUTO_FOCUS_START: case V4L2_CID_AUTO_FOCUS_STOP: + case V4L2_CID_DO_WHITE_BALANCE: *type = V4L2_CTRL_TYPE_BUTTON; *flags |= V4L2_CTRL_FLAG_WRITE_ONLY | V4L2_CTRL_FLAG_EXECUTE_ON_WRITE;
From: Luca Ceresoli luca@lucaceresoli.net
commit f413cbb332a0b5251a790f396d0eb4ebcade5dec upstream.
Errors are negative numbers. Using %u shows them as very large positive numbers such as 4294967277 that don't make sense. Use the %d format instead, and get a much nicer -19.
Signed-off-by: Luca Ceresoli luca@lucaceresoli.net Fixes: b48e0bab142f ("net: macb: Migrate to devm clock interface") Fixes: 93b31f48b3ba ("net/macb: unify clock management") Fixes: 421d9df0628b ("net/macb: merge at91_ether driver into macb driver") Fixes: aead88bd0e99 ("net: ethernet: macb: Add support for rx_clk") Fixes: f5473d1d44e4 ("net: macb: Support clock management for tsu_clk") Acked-by: Nicolas Ferre nicolas.ferre@microchip.com Reviewed-by: Andrew Lunn andrew@lunn.ch Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Lee Jones lee.jones@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/net/ethernet/cadence/macb_main.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
--- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -2822,7 +2822,7 @@ static int macb_clk_init(struct platform if (!err) err = -ENODEV;
- dev_err(&pdev->dev, "failed to get macb_clk (%u)\n", err); + dev_err(&pdev->dev, "failed to get macb_clk (%d)\n", err); return err; }
@@ -2831,7 +2831,7 @@ static int macb_clk_init(struct platform if (!err) err = -ENODEV;
- dev_err(&pdev->dev, "failed to get hclk (%u)\n", err); + dev_err(&pdev->dev, "failed to get hclk (%d)\n", err); return err; }
@@ -2845,25 +2845,25 @@ static int macb_clk_init(struct platform
err = clk_prepare_enable(*pclk); if (err) { - dev_err(&pdev->dev, "failed to enable pclk (%u)\n", err); + dev_err(&pdev->dev, "failed to enable pclk (%d)\n", err); return err; }
err = clk_prepare_enable(*hclk); if (err) { - dev_err(&pdev->dev, "failed to enable hclk (%u)\n", err); + dev_err(&pdev->dev, "failed to enable hclk (%d)\n", err); goto err_disable_pclk; }
err = clk_prepare_enable(*tx_clk); if (err) { - dev_err(&pdev->dev, "failed to enable tx_clk (%u)\n", err); + dev_err(&pdev->dev, "failed to enable tx_clk (%d)\n", err); goto err_disable_hclk; }
err = clk_prepare_enable(*rx_clk); if (err) { - dev_err(&pdev->dev, "failed to enable rx_clk (%u)\n", err); + dev_err(&pdev->dev, "failed to enable rx_clk (%d)\n", err); goto err_disable_txclk; }
@@ -3298,7 +3298,7 @@ static int at91ether_clk_init(struct pla
err = clk_prepare_enable(*pclk); if (err) { - dev_err(&pdev->dev, "failed to enable pclk (%u)\n", err); + dev_err(&pdev->dev, "failed to enable pclk (%d)\n", err); return err; }
From: Uwe Kleine-König u.kleine-koenig@pengutronix.de
commit e926b12c611c2095c7976e2ed31753ad6eb5ff1a upstream.
After a PWM is disposed by its user the per chip data becomes invalid. Clear the data in common code instead of the device drivers to get consistent behaviour. Before this patch only three of nine drivers cleaned up here.
Signed-off-by: Uwe Kleine-König u.kleine-koenig@pengutronix.de Signed-off-by: Thierry Reding thierry.reding@gmail.com Signed-off-by: Lee Jones lee.jones@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/pwm/core.c | 1 + drivers/pwm/pwm-berlin.c | 1 - drivers/pwm/pwm-pca9685.c | 1 - drivers/pwm/pwm-samsung.c | 1 - 4 files changed, 1 insertion(+), 3 deletions(-)
--- a/drivers/pwm/core.c +++ b/drivers/pwm/core.c @@ -874,6 +874,7 @@ void pwm_put(struct pwm_device *pwm) if (pwm->chip->ops->free) pwm->chip->ops->free(pwm->chip, pwm);
+ pwm_set_chip_data(pwm, NULL); pwm->label = NULL;
module_put(pwm->chip->ops->owner); --- a/drivers/pwm/pwm-berlin.c +++ b/drivers/pwm/pwm-berlin.c @@ -78,7 +78,6 @@ static void berlin_pwm_free(struct pwm_c { struct berlin_pwm_channel *channel = pwm_get_chip_data(pwm);
- pwm_set_chip_data(pwm, NULL); kfree(channel); }
--- a/drivers/pwm/pwm-pca9685.c +++ b/drivers/pwm/pwm-pca9685.c @@ -176,7 +176,6 @@ static void pca9685_pwm_gpio_free(struct pm_runtime_put(pca->chip.dev); mutex_lock(&pca->lock); pwm = &pca->chip.pwms[offset]; - pwm_set_chip_data(pwm, NULL); mutex_unlock(&pca->lock); }
--- a/drivers/pwm/pwm-samsung.c +++ b/drivers/pwm/pwm-samsung.c @@ -238,7 +238,6 @@ static int pwm_samsung_request(struct pw static void pwm_samsung_free(struct pwm_chip *chip, struct pwm_device *pwm) { devm_kfree(chip->dev, pwm_get_chip_data(pwm)); - pwm_set_chip_data(pwm, NULL); }
static int pwm_samsung_enable(struct pwm_chip *chip, struct pwm_device *pwm)
From: Eugen Hristev eugen.hristev@microchip.com
commit 1e4e25c4959c10728fbfcc6a286f9503d32dfe02 upstream.
The subsystem will free the asd memory on notifier cleanup, if the asd is added to the notifier. However the memory is freed using kfree. Thus, we cannot allocate the asd using devm_* This can lead to crashes and problems. To test this issue, just return an error at probe, but cleanup the notifier beforehand.
Fixes: 106267444f ("[media] atmel-isc: add the Image Sensor Controller code")
Signed-off-by: Eugen Hristev eugen.hristev@microchip.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+samsung@kernel.org Signed-off-by: Lee Jones lee.jones@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/media/platform/atmel/atmel-isc.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
--- a/drivers/media/platform/atmel/atmel-isc.c +++ b/drivers/media/platform/atmel/atmel-isc.c @@ -1722,8 +1722,11 @@ static int isc_parse_dt(struct device *d break; }
- subdev_entity->asd = devm_kzalloc(dev, - sizeof(*subdev_entity->asd), GFP_KERNEL); + /* asd will be freed by the subsystem once it's added to the + * notifier list + */ + subdev_entity->asd = kzalloc(sizeof(*subdev_entity->asd), + GFP_KERNEL); if (subdev_entity->asd == NULL) { of_node_put(rem); ret = -ENOMEM; @@ -1859,6 +1862,7 @@ static int atmel_isc_probe(struct platfo &subdev_entity->notifier); if (ret) { dev_err(dev, "fail to register async notifier\n"); + kfree(subdev_entity->asd); goto cleanup_subdev; }
From: Eugen Hristev eugen.hristev@microchip.com
commit 79199002db5c571e335131856b3ff057ffd9f3c0 upstream.
In case the completion function failes, unbind will be called which will call cancel_work for awb_work. This will trigger a WARN message from the workqueue. To avoid this, move the INIT_WORK call at the start of the completion function. This way the work is always initialized, which corresponds to the 'always canceled' unbind code.
Fixes: 93d4a26c3d ("[media] atmel-isc: add the isc pipeline function")
Signed-off-by: Eugen Hristev eugen.hristev@microchip.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+samsung@kernel.org Signed-off-by: Lee Jones lee.jones@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/media/platform/atmel/atmel-isc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/media/platform/atmel/atmel-isc.c +++ b/drivers/media/platform/atmel/atmel-isc.c @@ -1555,6 +1555,8 @@ static int isc_async_complete(struct v4l struct vb2_queue *q = &isc->vb2_vidq; int ret;
+ INIT_WORK(&isc->awb_work, isc_awb_work); + ret = v4l2_device_register_subdev_nodes(&isc->v4l2_dev); if (ret < 0) { v4l2_err(&isc->v4l2_dev, "Failed to register subdev nodes\n"); @@ -1614,8 +1616,6 @@ static int isc_async_complete(struct v4l return ret; }
- INIT_WORK(&isc->awb_work, isc_awb_work); - /* Register video device */ strlcpy(vdev->name, ATMEL_ISC_NAME, sizeof(vdev->name)); vdev->release = video_device_release_empty;
From: Menglong Dong dong.menglong@zte.com.cn
[ Upstream commit 1d7ea55668878bb350979c377fc72509dd6f5b21 ]
While enqueueing a broadcast skb to port->bc_queue, schedule_work() is called to add port->bc_work, which processes the skbs in bc_queue, to "events" work queue. If port->bc_queue is full, the skb will be discarded and schedule_work(&port->bc_work) won't be called. However, if port->bc_queue is full and port->bc_work is not running or pending, port->bc_queue will keep full and schedule_work() won't be called any more, and all broadcast skbs to macvlan will be discarded. This case can happen:
macvlan_process_broadcast() is the pending function of port->bc_work, it moves all the skbs in port->bc_queue to the queue "list", and processes the skbs in "list". During this, new skbs will keep being added to port->bc_queue in macvlan_broadcast_enqueue(), and port->bc_queue may already full when macvlan_process_broadcast() return. This may happen, especially when there are a lot of real-time threads and the process is preempted.
Fix this by calling schedule_work(&port->bc_work) even if port->bc_work is full in macvlan_broadcast_enqueue().
Fixes: 412ca1550cbe ("macvlan: Move broadcasts into a work queue") Signed-off-by: Menglong Dong dong.menglong@zte.com.cn Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/macvlan.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -363,10 +363,11 @@ static void macvlan_broadcast_enqueue(st } spin_unlock(&port->bc_queue.lock);
+ schedule_work(&port->bc_work); + if (err) goto free_nskb;
- schedule_work(&port->bc_work); return;
free_nskb:
From: Nikolay Aleksandrov nikolay@cumulusnetworks.com
[ Upstream commit 7eb9d7675c08937cd11d32b0b40442d4d731c5ee ]
We need to calculate the skb size correctly otherwise we risk triggering skb_over_panic[1]. The issue is that data_len is added to the skb in a nl attribute, but we don't account for its header size (nlattr 4 bytes) and alignment. We account for it when calculating the total size in the > PSAMPLE_MAX_PACKET_SIZE comparison correctly, but not when allocating after that. The fix is simple - use nla_total_size() for data_len when allocating.
To reproduce: $ tc qdisc add dev eth1 clsact $ tc filter add dev eth1 egress matchall action sample rate 1 group 1 trunc 129 $ mausezahn eth1 -b bcast -a rand -c 1 -p 129 < skb_over_panic BUG(), tail is 4 bytes past skb->end >
[1] Trace: [ 50.459526][ T3480] skbuff: skb_over_panic: text:(____ptrval____) len:196 put:136 head:(____ptrval____) data:(____ptrval____) tail:0xc4 end:0xc0 dev:<NULL> [ 50.474339][ T3480] ------------[ cut here ]------------ [ 50.481132][ T3480] kernel BUG at net/core/skbuff.c:108! [ 50.486059][ T3480] invalid opcode: 0000 [#1] PREEMPT SMP [ 50.489463][ T3480] CPU: 3 PID: 3480 Comm: mausezahn Not tainted 5.4.0-rc7 #108 [ 50.492844][ T3480] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-2.fc30 04/01/2014 [ 50.496551][ T3480] RIP: 0010:skb_panic+0x79/0x7b [ 50.498261][ T3480] Code: bc 00 00 00 41 57 4c 89 e6 48 c7 c7 90 29 9a 83 4c 8b 8b c0 00 00 00 50 8b 83 b8 00 00 00 50 ff b3 c8 00 00 00 e8 ae ef c0 fe <0f> 0b e8 2f df c8 fe 48 8b 55 08 44 89 f6 4c 89 e7 48 c7 c1 a0 22 [ 50.504111][ T3480] RSP: 0018:ffffc90000447a10 EFLAGS: 00010282 [ 50.505835][ T3480] RAX: 0000000000000087 RBX: ffff888039317d00 RCX: 0000000000000000 [ 50.507900][ T3480] RDX: 0000000000000000 RSI: ffffffff812716e1 RDI: 00000000ffffffff [ 50.509820][ T3480] RBP: ffffc90000447a60 R08: 0000000000000001 R09: 0000000000000000 [ 50.511735][ T3480] R10: ffffffff81d4f940 R11: 0000000000000000 R12: ffffffff834a22b0 [ 50.513494][ T3480] R13: ffffffff82c10433 R14: 0000000000000088 R15: ffffffff838a8084 [ 50.515222][ T3480] FS: 00007f3536462700(0000) GS:ffff88803eac0000(0000) knlGS:0000000000000000 [ 50.517135][ T3480] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 50.518583][ T3480] CR2: 0000000000442008 CR3: 000000003b222000 CR4: 00000000000006e0 [ 50.520723][ T3480] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 50.522709][ T3480] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 50.524450][ T3480] Call Trace: [ 50.525214][ T3480] skb_put.cold+0x1b/0x1b [ 50.526171][ T3480] psample_sample_packet+0x1d3/0x340 [ 50.527307][ T3480] tcf_sample_act+0x178/0x250 [ 50.528339][ T3480] tcf_action_exec+0xb1/0x190 [ 50.529354][ T3480] mall_classify+0x67/0x90 [ 50.530332][ T3480] tcf_classify+0x72/0x160 [ 50.531286][ T3480] __dev_queue_xmit+0x3db/0xd50 [ 50.532327][ T3480] dev_queue_xmit+0x18/0x20 [ 50.533299][ T3480] packet_sendmsg+0xee7/0x2090 [ 50.534331][ T3480] sock_sendmsg+0x54/0x70 [ 50.535271][ T3480] __sys_sendto+0x148/0x1f0 [ 50.536252][ T3480] ? tomoyo_file_ioctl+0x23/0x30 [ 50.537334][ T3480] ? ksys_ioctl+0x5e/0xb0 [ 50.540068][ T3480] __x64_sys_sendto+0x2a/0x30 [ 50.542810][ T3480] do_syscall_64+0x73/0x1f0 [ 50.545383][ T3480] entry_SYSCALL_64_after_hwframe+0x44/0xa9 [ 50.548477][ T3480] RIP: 0033:0x7f35357d6fb3 [ 50.551020][ T3480] Code: 48 8b 0d 18 90 20 00 f7 d8 64 89 01 48 83 c8 ff c3 66 0f 1f 44 00 00 83 3d f9 d3 20 00 00 75 13 49 89 ca b8 2c 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 34 c3 48 83 ec 08 e8 eb f6 ff ff 48 89 04 24 [ 50.558547][ T3480] RSP: 002b:00007ffe0c7212c8 EFLAGS: 00000246 ORIG_RAX: 000000000000002c [ 50.561870][ T3480] RAX: ffffffffffffffda RBX: 0000000001dac010 RCX: 00007f35357d6fb3 [ 50.565142][ T3480] RDX: 0000000000000082 RSI: 0000000001dac2a2 RDI: 0000000000000003 [ 50.568469][ T3480] RBP: 00007ffe0c7212f0 R08: 00007ffe0c7212d0 R09: 0000000000000014 [ 50.571731][ T3480] R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000082 [ 50.574961][ T3480] R13: 0000000001dac2a2 R14: 0000000000000001 R15: 0000000000000003 [ 50.578170][ T3480] Modules linked in: sch_ingress virtio_net [ 50.580976][ T3480] ---[ end trace 61a515626a595af6 ]---
CC: Yotam Gigi yotamg@mellanox.com CC: Jiri Pirko jiri@mellanox.com CC: Jamal Hadi Salim jhs@mojatatu.com CC: Simon Horman simon.horman@netronome.com CC: Roopa Prabhu roopa@cumulusnetworks.com Fixes: 6ae0a6286171 ("net: Introduce psample, a new genetlink channel for packet sampling") Signed-off-by: Nikolay Aleksandrov nikolay@cumulusnetworks.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/psample/psample.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/net/psample/psample.c +++ b/net/psample/psample.c @@ -223,7 +223,7 @@ void psample_sample_packet(struct psampl data_len = PSAMPLE_MAX_PACKET_SIZE - meta_len - NLA_HDRLEN - NLA_ALIGNTO;
- nl_skb = genlmsg_new(meta_len + data_len, GFP_ATOMIC); + nl_skb = genlmsg_new(meta_len + nla_total_size(data_len), GFP_ATOMIC); if (unlikely(!nl_skb)) return;
From: Paolo Abeni pabeni@redhat.com
[ Upstream commit 4e81c0b3fa93d07653e2415fa71656b080a112fd ]
When user-space sets the OVS_UFID_F_OMIT_* flags, and the relevant flow has no UFID, we can exceed the computed size, as ovs_nla_put_identifier() will always dump an OVS_FLOW_ATTR_KEY attribute. Take the above in account when computing the flow command message size.
Fixes: 74ed7ab9264c ("openvswitch: Add support for unique flow IDs.") Reported-by: Qi Jun Ding qding@redhat.com Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/openvswitch/datapath.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
--- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c @@ -724,9 +724,13 @@ static size_t ovs_flow_cmd_msg_size(cons { size_t len = NLMSG_ALIGN(sizeof(struct ovs_header));
- /* OVS_FLOW_ATTR_UFID */ + /* OVS_FLOW_ATTR_UFID, or unmasked flow key as fallback + * see ovs_nla_put_identifier() + */ if (sfid && ovs_identifier_is_ufid(sfid)) len += nla_total_size(sfid->ufid_len); + else + len += nla_total_size(ovs_key_attr_size());
/* OVS_FLOW_ATTR_KEY */ if (!sfid || should_fill_key(sfid, ufid_flags))
From: Jouni Hogander jouni.hogander@unikie.com
[ Upstream commit e58c1912418980f57ba2060017583067f5f71e52 ]
Slip_open doesn't clean-up device which registration failed from the slip_devs device list. On next open after failure this list is iterated and freed device is accessed. Fix this by calling sl_free_netdev in error path.
Here is the trace from the Syzbot:
__dump_stack lib/dump_stack.c:77 [inline] dump_stack+0x197/0x210 lib/dump_stack.c:118 print_address_description.constprop.0.cold+0xd4/0x30b mm/kasan/report.c:374 __kasan_report.cold+0x1b/0x41 mm/kasan/report.c:506 kasan_report+0x12/0x20 mm/kasan/common.c:634 __asan_report_load8_noabort+0x14/0x20 mm/kasan/generic_report.c:132 sl_sync drivers/net/slip/slip.c:725 [inline] slip_open+0xecd/0x11b7 drivers/net/slip/slip.c:801 tty_ldisc_open.isra.0+0xa3/0x110 drivers/tty/tty_ldisc.c:469 tty_set_ldisc+0x30e/0x6b0 drivers/tty/tty_ldisc.c:596 tiocsetd drivers/tty/tty_io.c:2334 [inline] tty_ioctl+0xe8d/0x14f0 drivers/tty/tty_io.c:2594 vfs_ioctl fs/ioctl.c:46 [inline] file_ioctl fs/ioctl.c:509 [inline] do_vfs_ioctl+0xdb6/0x13e0 fs/ioctl.c:696 ksys_ioctl+0xab/0xd0 fs/ioctl.c:713 __do_sys_ioctl fs/ioctl.c:720 [inline] __se_sys_ioctl fs/ioctl.c:718 [inline] __x64_sys_ioctl+0x73/0xb0 fs/ioctl.c:718 do_syscall_64+0xfa/0x760 arch/x86/entry/common.c:290 entry_SYSCALL_64_after_hwframe+0x49/0xbe
Fixes: 3b5a39979daf ("slip: Fix memory leak in slip_open error path") Reported-by: syzbot+4d5170758f3762109542@syzkaller.appspotmail.com Cc: David Miller davem@davemloft.net Cc: Oliver Hartkopp socketcan@hartkopp.net Cc: Lukas Bulwahn lukas.bulwahn@gmail.com Signed-off-by: Jouni Hogander jouni.hogander@unikie.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/slip/slip.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/net/slip/slip.c +++ b/drivers/net/slip/slip.c @@ -859,6 +859,7 @@ err_free_chan: sl->tty = NULL; tty->disc_data = NULL; clear_bit(SLF_INUSE, &sl->flags); + sl_free_netdev(sl->dev); free_netdev(sl->dev);
err_exit:
From: Paolo Abeni pabeni@redhat.com
[ Upstream commit 8ffeb03fbba3b599690b361467bfd2373e8c450f ]
All the callers of ovs_flow_cmd_build_info() already deal with error return code correctly, so we can handle the error condition in a more gracefull way. Still dump a warning to preserve debuggability.
v1 -> v2: - clarify the commit message - clean the skb and report the error (DaveM)
Fixes: ccb1352e76cf ("net: Add Open vSwitch kernel components.") Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/openvswitch/datapath.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
--- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c @@ -906,7 +906,10 @@ static struct sk_buff *ovs_flow_cmd_buil retval = ovs_flow_cmd_fill_info(flow, dp_ifindex, skb, info->snd_portid, info->snd_seq, 0, cmd, ufid_flags); - BUG_ON(retval < 0); + if (WARN_ON_ONCE(retval < 0)) { + kfree_skb(skb); + skb = ERR_PTR(retval); + } return skb; }
From: Paolo Abeni pabeni@redhat.com
[ Upstream commit 8a574f86652a4540a2433946ba826ccb87f398cc ]
If we can't build the flow del notification, we can simply delete the flow, no need to crash the kernel. Still keep a WARN_ON to preserve debuggability.
Note: the BUG_ON() predates the Fixes tag, but this change can be applied only after the mentioned commit.
v1 -> v2: - do not leak an skb on error
Fixes: aed067783e50 ("openvswitch: Minimize ovs_flow_cmd_del critical section.") Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/openvswitch/datapath.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
--- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c @@ -1372,7 +1372,10 @@ static int ovs_flow_cmd_del(struct sk_bu OVS_FLOW_CMD_DEL, ufid_flags); rcu_read_unlock(); - BUG_ON(err < 0); + if (WARN_ON_ONCE(err < 0)) { + kfree_skb(reply); + goto out_free; + }
ovs_notify(&dp_flow_genl_family, reply, info); } else { @@ -1380,6 +1383,7 @@ static int ovs_flow_cmd_del(struct sk_bu } }
+out_free: ovs_flow_free(flow, true); return 0; unlock:
From: John Rutherford john.rutherford@dektech.com.au
[ Upstream commit fd567ac20cb0377ff466d3337e6e9ac5d0cb15e4 ]
In commit 4f07b80c9733 ("tipc: check msg->req data len in tipc_nl_compat_bearer_disable") the same patch code was copied into routines: tipc_nl_compat_bearer_disable(), tipc_nl_compat_link_stat_dump() and tipc_nl_compat_link_reset_stats(). The two link routine occurrences should have been modified to check the maximum link name length and not bearer name length.
Fixes: 4f07b80c9733 ("tipc: check msg->reg data len in tipc_nl_compat_bearer_disable") Signed-off-by: John Rutherford john.rutherford@dektech.com.au Acked-by: Jon Maloy jon.maloy@ericsson.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/tipc/netlink_compat.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/net/tipc/netlink_compat.c +++ b/net/tipc/netlink_compat.c @@ -539,7 +539,7 @@ static int tipc_nl_compat_link_stat_dump if (len <= 0) return -EINVAL;
- len = min_t(int, len, TIPC_MAX_BEARER_NAME); + len = min_t(int, len, TIPC_MAX_LINK_NAME); if (!string_is_valid(name, len)) return -EINVAL;
@@ -821,7 +821,7 @@ static int tipc_nl_compat_link_reset_sta if (len <= 0) return -EINVAL;
- len = min_t(int, len, TIPC_MAX_BEARER_NAME); + len = min_t(int, len, TIPC_MAX_LINK_NAME); if (!string_is_valid(name, len)) return -EINVAL;
From: Xin Long lucien.xin@gmail.com
[ Upstream commit 312434617cb16be5166316cf9d08ba760b1042a1 ]
This patch is to fix a data-race reported by syzbot:
BUG: KCSAN: data-race in sctp_assoc_migrate / sctp_hash_obj
write to 0xffff8880b67c0020 of 8 bytes by task 18908 on cpu 1: sctp_assoc_migrate+0x1a6/0x290 net/sctp/associola.c:1091 sctp_sock_migrate+0x8aa/0x9b0 net/sctp/socket.c:9465 sctp_accept+0x3c8/0x470 net/sctp/socket.c:4916 inet_accept+0x7f/0x360 net/ipv4/af_inet.c:734 __sys_accept4+0x224/0x430 net/socket.c:1754 __do_sys_accept net/socket.c:1795 [inline] __se_sys_accept net/socket.c:1792 [inline] __x64_sys_accept+0x4e/0x60 net/socket.c:1792 do_syscall_64+0xcc/0x370 arch/x86/entry/common.c:290 entry_SYSCALL_64_after_hwframe+0x44/0xa9
read to 0xffff8880b67c0020 of 8 bytes by task 12003 on cpu 0: sctp_hash_obj+0x4f/0x2d0 net/sctp/input.c:894 rht_key_get_hash include/linux/rhashtable.h:133 [inline] rht_key_hashfn include/linux/rhashtable.h:159 [inline] rht_head_hashfn include/linux/rhashtable.h:174 [inline] head_hashfn lib/rhashtable.c:41 [inline] rhashtable_rehash_one lib/rhashtable.c:245 [inline] rhashtable_rehash_chain lib/rhashtable.c:276 [inline] rhashtable_rehash_table lib/rhashtable.c:316 [inline] rht_deferred_worker+0x468/0xab0 lib/rhashtable.c:420 process_one_work+0x3d4/0x890 kernel/workqueue.c:2269 worker_thread+0xa0/0x800 kernel/workqueue.c:2415 kthread+0x1d4/0x200 drivers/block/aoe/aoecmd.c:1253 ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:352
It was caused by rhashtable access asoc->base.sk when sctp_assoc_migrate is changing its value. However, what rhashtable wants is netns from asoc base.sk, and for an asoc, its netns won't change once set. So we can simply fix it by caching netns since created.
Fixes: d6c0256a60e6 ("sctp: add the rhashtable apis for sctp global transport hashtable") Reported-by: syzbot+e3b35fe7918ff0ee474e@syzkaller.appspotmail.com Signed-off-by: Xin Long lucien.xin@gmail.com Acked-by: Marcelo Ricardo Leitner marcelo.leitner@gmail.com Signed-off-by: Jakub Kicinski jakub.kicinski@netronome.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- include/net/sctp/structs.h | 3 +++ net/sctp/associola.c | 1 + net/sctp/endpointola.c | 1 + net/sctp/input.c | 4 ++-- 4 files changed, 7 insertions(+), 2 deletions(-)
--- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -1181,6 +1181,9 @@ struct sctp_ep_common { /* What socket does this endpoint belong to? */ struct sock *sk;
+ /* Cache netns and it won't change once set */ + struct net *net; + /* This is where we receive inbound chunks. */ struct sctp_inq inqueue;
--- a/net/sctp/associola.c +++ b/net/sctp/associola.c @@ -80,6 +80,7 @@ static struct sctp_association *sctp_ass /* Discarding const is appropriate here. */ asoc->ep = (struct sctp_endpoint *)ep; asoc->base.sk = (struct sock *)sk; + asoc->base.net = sock_net(sk);
sctp_endpoint_hold(asoc->ep); sock_hold(asoc->base.sk); --- a/net/sctp/endpointola.c +++ b/net/sctp/endpointola.c @@ -165,6 +165,7 @@ static struct sctp_endpoint *sctp_endpoi
/* Remember who we are attached to. */ ep->base.sk = sk; + ep->base.net = sock_net(sk); sock_hold(ep->base.sk);
return ep; --- a/net/sctp/input.c +++ b/net/sctp/input.c @@ -813,7 +813,7 @@ static inline int sctp_hash_cmp(struct r if (!sctp_transport_hold(t)) return err;
- if (!net_eq(sock_net(t->asoc->base.sk), x->net)) + if (!net_eq(t->asoc->base.net, x->net)) goto out; if (x->lport != htons(t->asoc->base.bind_addr.port)) goto out; @@ -828,7 +828,7 @@ static inline __u32 sctp_hash_obj(const { const struct sctp_transport *t = data; const union sctp_addr *paddr = &t->ipaddr; - const struct net *net = sock_net(t->asoc->base.sk); + const struct net *net = t->asoc->base.net; __be16 lport = htons(t->asoc->base.bind_addr.port); __u32 addr;
From: Dust Li dust.li@linux.alibaba.com
[ Upstream commit 14e54ab9143fa60794d13ea0a66c792a2046a8f3 ]
When a classful qdisc's child qdisc has set the flag TCQ_F_CPUSTATS (pfifo_fast for example), the child qdisc's cpu_bstats should be passed to gnet_stats_copy_basic(), but many classful qdisc didn't do that. As a result, `tc -s class show dev DEV` always return 0 for bytes and packets in this case.
Pass the child qdisc's cpu_bstats to gnet_stats_copy_basic() to fix this issue.
The qstats also has this problem, but it has been fixed in 5dd431b6b9 ("net: sched: introduce and use qstats read...") and bstats still remains buggy.
Fixes: 22e0f8b9322c ("net: sched: make bstats per cpu and estimator RCU safe") Signed-off-by: Dust Li dust.li@linux.alibaba.com Signed-off-by: Tony Lu tonylu@linux.alibaba.com Acked-by: Cong Wang xiyou.wangcong@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/sched/sch_mq.c | 3 ++- net/sched/sch_mqprio.c | 4 ++-- net/sched/sch_multiq.c | 2 +- net/sched/sch_prio.c | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-)
--- a/net/sched/sch_mq.c +++ b/net/sched/sch_mq.c @@ -191,7 +191,8 @@ static int mq_dump_class_stats(struct Qd struct netdev_queue *dev_queue = mq_queue_get(sch, cl);
sch = dev_queue->qdisc_sleeping; - if (gnet_stats_copy_basic(&sch->running, d, NULL, &sch->bstats) < 0 || + if (gnet_stats_copy_basic(&sch->running, d, sch->cpu_bstats, + &sch->bstats) < 0 || gnet_stats_copy_queue(d, NULL, &sch->qstats, sch->q.qlen) < 0) return -1; return 0; --- a/net/sched/sch_mqprio.c +++ b/net/sched/sch_mqprio.c @@ -366,8 +366,8 @@ static int mqprio_dump_class_stats(struc struct netdev_queue *dev_queue = mqprio_queue_get(sch, cl);
sch = dev_queue->qdisc_sleeping; - if (gnet_stats_copy_basic(qdisc_root_sleeping_running(sch), - d, NULL, &sch->bstats) < 0 || + if (gnet_stats_copy_basic(qdisc_root_sleeping_running(sch), d, + sch->cpu_bstats, &sch->bstats) < 0 || gnet_stats_copy_queue(d, NULL, &sch->qstats, sch->q.qlen) < 0) return -1; --- a/net/sched/sch_multiq.c +++ b/net/sched/sch_multiq.c @@ -340,7 +340,7 @@ static int multiq_dump_class_stats(struc
cl_q = q->queues[cl - 1]; if (gnet_stats_copy_basic(qdisc_root_sleeping_running(sch), - d, NULL, &cl_q->bstats) < 0 || + d, cl_q->cpu_bstats, &cl_q->bstats) < 0 || gnet_stats_copy_queue(d, NULL, &cl_q->qstats, cl_q->q.qlen) < 0) return -1;
--- a/net/sched/sch_prio.c +++ b/net/sched/sch_prio.c @@ -298,7 +298,7 @@ static int prio_dump_class_stats(struct
cl_q = q->queues[cl - 1]; if (gnet_stats_copy_basic(qdisc_root_sleeping_running(sch), - d, NULL, &cl_q->bstats) < 0 || + d, cl_q->cpu_bstats, &cl_q->bstats) < 0 || gnet_stats_copy_queue(d, NULL, &cl_q->qstats, cl_q->q.qlen) < 0) return -1;
From: Theodore Ts'o tytso@mit.edu
commit 4ea99936a1630f51fc3a2d61a58ec4a1c4b7d55a upstream.
It's possible to specify a non-zero s_want_extra_isize via debugging option, and this can cause bad things(tm) to happen when using a file system with an inode size of 128 bytes.
Add better checking when the file system is mounted, as well as when we are actually doing the trying to do the inode expansion.
Link: https://lore.kernel.org/r/20191110121510.GH23325@mit.edu Reported-by: syzbot+f8d6f8386ceacdbfff57@syzkaller.appspotmail.com Reported-by: syzbot+33d7ea72e47de3bdf4e1@syzkaller.appspotmail.com Reported-by: syzbot+44b6763edfc17144296f@syzkaller.appspotmail.com Signed-off-by: Theodore Ts'o tytso@mit.edu Cc: stable@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/ext4/inode.c | 15 +++++++++++++++ fs/ext4/super.c | 21 ++++++++++++--------- 2 files changed, 27 insertions(+), 9 deletions(-)
--- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -5751,8 +5751,23 @@ static int __ext4_expand_extra_isize(str { struct ext4_inode *raw_inode; struct ext4_xattr_ibody_header *header; + unsigned int inode_size = EXT4_INODE_SIZE(inode->i_sb); + struct ext4_inode_info *ei = EXT4_I(inode); int error;
+ /* this was checked at iget time, but double check for good measure */ + if ((EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize > inode_size) || + (ei->i_extra_isize & 3)) { + EXT4_ERROR_INODE(inode, "bad extra_isize %u (inode size %u)", + ei->i_extra_isize, + EXT4_INODE_SIZE(inode->i_sb)); + return -EFSCORRUPTED; + } + if ((new_extra_isize < ei->i_extra_isize) || + (new_extra_isize < 4) || + (new_extra_isize > inode_size - EXT4_GOOD_OLD_INODE_SIZE)) + return -EINVAL; /* Should never happen */ + raw_inode = ext4_raw_inode(iloc);
header = IHDR(inode, raw_inode); --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -3458,12 +3458,15 @@ static void ext4_clamp_want_extra_isize( { struct ext4_sb_info *sbi = EXT4_SB(sb); struct ext4_super_block *es = sbi->s_es; + unsigned def_extra_isize = sizeof(struct ext4_inode) - + EXT4_GOOD_OLD_INODE_SIZE;
- /* determine the minimum size of new large inodes, if present */ - if (sbi->s_inode_size > EXT4_GOOD_OLD_INODE_SIZE && - sbi->s_want_extra_isize == 0) { - sbi->s_want_extra_isize = sizeof(struct ext4_inode) - - EXT4_GOOD_OLD_INODE_SIZE; + if (sbi->s_inode_size == EXT4_GOOD_OLD_INODE_SIZE) { + sbi->s_want_extra_isize = 0; + return; + } + if (sbi->s_want_extra_isize < 4) { + sbi->s_want_extra_isize = def_extra_isize; if (ext4_has_feature_extra_isize(sb)) { if (sbi->s_want_extra_isize < le16_to_cpu(es->s_want_extra_isize)) @@ -3476,10 +3479,10 @@ static void ext4_clamp_want_extra_isize( } } /* Check if enough inode space is available */ - if (EXT4_GOOD_OLD_INODE_SIZE + sbi->s_want_extra_isize > - sbi->s_inode_size) { - sbi->s_want_extra_isize = sizeof(struct ext4_inode) - - EXT4_GOOD_OLD_INODE_SIZE; + if ((sbi->s_want_extra_isize > sbi->s_inode_size) || + (EXT4_GOOD_OLD_INODE_SIZE + sbi->s_want_extra_isize > + sbi->s_inode_size)) { + sbi->s_want_extra_isize = def_extra_isize; ext4_msg(sb, KERN_INFO, "required extra inode space not available"); }
From: Eugen Hristev eugen.hristev@microchip.com
commit 8632944841d41a36d77dd1fa88d4201b5291100f upstream.
WDD value must be always set to max (0xFFF) otherwise the hardware block will reset the board on the first ping of the watchdog.
Signed-off-by: Eugen Hristev eugen.hristev@microchip.com Reviewed-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Wim Van Sebroeck wim@linux-watchdog.org Signed-off-by: Lee Jones lee.jones@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/watchdog/sama5d4_wdt.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
--- a/drivers/watchdog/sama5d4_wdt.c +++ b/drivers/watchdog/sama5d4_wdt.c @@ -111,9 +111,7 @@ static int sama5d4_wdt_set_timeout(struc u32 value = WDT_SEC2TICKS(timeout);
wdt->mr &= ~AT91_WDT_WDV; - wdt->mr &= ~AT91_WDT_WDD; wdt->mr |= AT91_WDT_SET_WDV(value); - wdt->mr |= AT91_WDT_SET_WDD(value);
/* * WDDIS has to be 0 when updating WDD/WDV. The datasheet states: When @@ -255,7 +253,7 @@ static int sama5d4_wdt_probe(struct plat
timeout = WDT_SEC2TICKS(wdd->timeout);
- wdt->mr |= AT91_WDT_SET_WDD(timeout); + wdt->mr |= AT91_WDT_SET_WDD(WDT_SEC2TICKS(MAX_WDT_TIMEOUT)); wdt->mr |= AT91_WDT_SET_WDV(timeout);
ret = sama5d4_wdt_init(wdt);
From: Harini Katakam harini.katakam@xilinx.com
commit 7ad342bc58cc5197cd2f12a3c30b3949528c6d83 upstream.
The subns increment register has 24 bits as follows: RegBit[15:0] = Subns[23:8]; RegBit[31:24] = Subns[7:0]
Fix the same in the driver and increase sub ns resolution to the best capable, 24 bits. This should be the case on all GEM versions that this PTP driver supports.
Signed-off-by: Harini Katakam harini.katakam@xilinx.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Lee Jones lee.jones@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/net/ethernet/cadence/macb.h | 6 +++++- drivers/net/ethernet/cadence/macb_ptp.c | 5 ++++- 2 files changed, 9 insertions(+), 2 deletions(-)
--- a/drivers/net/ethernet/cadence/macb.h +++ b/drivers/net/ethernet/cadence/macb.h @@ -457,7 +457,11 @@
/* Bitfields in TISUBN */ #define GEM_SUBNSINCR_OFFSET 0 -#define GEM_SUBNSINCR_SIZE 16 +#define GEM_SUBNSINCRL_OFFSET 24 +#define GEM_SUBNSINCRL_SIZE 8 +#define GEM_SUBNSINCRH_OFFSET 0 +#define GEM_SUBNSINCRH_SIZE 16 +#define GEM_SUBNSINCR_SIZE 24
/* Bitfields in TI */ #define GEM_NSINCR_OFFSET 0 --- a/drivers/net/ethernet/cadence/macb_ptp.c +++ b/drivers/net/ethernet/cadence/macb_ptp.c @@ -115,7 +115,10 @@ static int gem_tsu_incr_set(struct macb * to take effect. */ spin_lock_irqsave(&bp->tsu_clk_lock, flags); - gem_writel(bp, TISUBN, GEM_BF(SUBNSINCR, incr_spec->sub_ns)); + /* RegBit[15:0] = Subns[23:8]; RegBit[31:24] = Subns[7:0] */ + gem_writel(bp, TISUBN, GEM_BF(SUBNSINCRL, incr_spec->sub_ns) | + GEM_BF(SUBNSINCRH, (incr_spec->sub_ns >> + GEM_SUBNSINCRL_SIZE))); gem_writel(bp, TI, GEM_BF(NSINCR, incr_spec->ns)); spin_unlock_irqrestore(&bp->tsu_clk_lock, flags);
From: Paul Thomas pthomas8589@gmail.com
commit a62520473f15750cd1432d36b377a06cd7cff8d2 upstream.
Make sure SKBTX_HW_TSTAMP (i.e. SOF_TIMESTAMPING_TX_HARDWARE) has been enabled for this skb. It does fix the issue where normal socks that aren't expecting a timestamp will not wake up on select, but when a user does want a SOF_TIMESTAMPING_TX_HARDWARE it does work.
Signed-off-by: Paul Thomas pthomas8589@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Lee Jones lee.jones@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/net/ethernet/cadence/macb_main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
--- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -852,7 +852,9 @@ static void macb_tx_interrupt(struct mac
/* First, update TX stats if needed */ if (skb) { - if (gem_ptp_do_txstamp(queue, skb, desc) == 0) { + if (unlikely(skb_shinfo(skb)->tx_flags & + SKBTX_HW_TSTAMP) && + gem_ptp_do_txstamp(queue, skb, desc) == 0) { /* skb now belongs to timestamp buffer * and will be removed later */
From: Miquel Raynal miquel.raynal@bootlin.com
commit e39bb786816453788836c367caefd72eceea380c upstream.
Wrong copy/paste from the previous block, the error message should refer to #size-cells instead of #address-cells.
Fixes: f88fc122cc34 ("mtd: nand: Cleanup/rework the atmel_nand driver") Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Reviewed-by: Tudor Ambarus tudor.ambarus@microchip.com Signed-off-by: Lee Jones lee.jones@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/mtd/nand/atmel/nand-controller.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/mtd/nand/atmel/nand-controller.c +++ b/drivers/mtd/nand/atmel/nand-controller.c @@ -1888,7 +1888,7 @@ static int atmel_nand_controller_add_nan
ret = of_property_read_u32(np, "#size-cells", &val); if (ret) { - dev_err(dev, "missing #address-cells property\n"); + dev_err(dev, "missing #size-cells property\n"); return ret; }
From: Wen Yang yellowriver2010@hotmail.com
commit a12085d13997ed15f745f33a0e01002541160179 upstream.
of_find_device_by_node() takes a reference to the struct device when it finds a match via get_device, there is no need to call get_device() twice. We also should make sure to drop the reference to the device taken by of_find_device_by_node() on driver unbind.
Fixes: f88fc122cc34 ("mtd: nand: Cleanup/rework the atmel_nand driver") Signed-off-by: Wen Yang yellowriver2010@hotmail.com Suggested-by: Boris Brezillon bbrezillon@kernel.org Reviewed-by: Boris Brezillon bbrezillon@kernel.org Reviewed-by: Miquel Raynal miquel.raynal@bootlin.com Acked-by: Miquel Raynal miquel.raynal@bootlin.com Cc: Tudor Ambarus tudor.ambarus@microchip.com Cc: Boris Brezillon bbrezillon@kernel.org Cc: Miquel Raynal miquel.raynal@bootlin.com Cc: Richard Weinberger richard@nod.at Cc: David Woodhouse dwmw2@infradead.org Cc: Brian Norris computersforpeace@gmail.com Cc: Marek Vasut marek.vasut@gmail.com Cc: Nicolas Ferre nicolas.ferre@microchip.com Cc: Alexandre Belloni alexandre.belloni@bootlin.com Cc: Ludovic Desroches ludovic.desroches@microchip.com Cc: linux-mtd@lists.infradead.org Cc: linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Signed-off-by: Lee Jones lee.jones@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/mtd/nand/atmel/pmecc.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-)
--- a/drivers/mtd/nand/atmel/pmecc.c +++ b/drivers/mtd/nand/atmel/pmecc.c @@ -875,23 +875,32 @@ static struct atmel_pmecc *atmel_pmecc_g { struct platform_device *pdev; struct atmel_pmecc *pmecc, **ptr; + int ret;
pdev = of_find_device_by_node(np); - if (!pdev || !platform_get_drvdata(pdev)) + if (!pdev) return ERR_PTR(-EPROBE_DEFER); + pmecc = platform_get_drvdata(pdev); + if (!pmecc) { + ret = -EPROBE_DEFER; + goto err_put_device; + }
ptr = devres_alloc(devm_atmel_pmecc_put, sizeof(*ptr), GFP_KERNEL); - if (!ptr) - return ERR_PTR(-ENOMEM); - - get_device(&pdev->dev); - pmecc = platform_get_drvdata(pdev); + if (!ptr) { + ret = -ENOMEM; + goto err_put_device; + }
*ptr = pmecc;
devres_add(userdev, ptr);
return pmecc; + +err_put_device: + put_device(&pdev->dev); + return ERR_PTR(ret); }
static const int atmel_pmecc_strengths[] = { 2, 4, 8, 12, 24, 32 };
From: huijin.park huijin.park@samsung.com
commit 84a1c2109d23df3543d96231c4fee1757299bb1a upstream.
The "params->size" is defined as "u64". And "info->sector_size" and "info->n_sectors" are defined as unsigned int and u16. Thus, u64 data might have strange data(loss data) if the result overflows an unsigned int. This patch casts "info->sector_size" to an u64.
Signed-off-by: huijin.park huijin.park@samsung.com Reviewed-by: Geert Uytterhoeven geert+renesas@glider.be Signed-off-by: Boris Brezillon boris.brezillon@bootlin.com Signed-off-by: Lee Jones lee.jones@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/mtd/spi-nor/spi-nor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -2382,7 +2382,7 @@ static int spi_nor_init_params(struct sp memset(params, 0, sizeof(*params));
/* Set SPI NOR sizes. */ - params->size = info->sector_size * info->n_sectors; + params->size = (u64)info->sector_size * info->n_sectors; params->page_size = info->page_size;
/* (Fast) Read settings. */
From: Arnd Bergmann arnd@arndb.de
commit 04e7712f4460585e5eed5b853fd8b82a9943958f upstream.
We are going to share the compat_sys_futex() handler between 64-bit architectures and 32-bit architectures that need to deal with both 32-bit and 64-bit time_t, and this is easier if both entry points are in the same file.
In fact, most other system call handlers do the same thing these days, so let's follow the trend here and merge all of futex_compat.c into futex.c.
In the process, a few minor changes have to be done to make sure everything still makes sense: handle_futex_death() and futex_cmpxchg_enabled() become local symbol, and the compat version of the fetch_robust_entry() function gets renamed to compat_fetch_robust_entry() to avoid a symbol clash.
This is intended as a purely cosmetic patch, no behavior should change.
Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- include/linux/futex.h | 8 - kernel/Makefile | 3 kernel/futex.c | 195 +++++++++++++++++++++++++++++++++++++++++++++++- kernel/futex_compat.c | 202 -------------------------------------------------- 4 files changed, 192 insertions(+), 216 deletions(-)
--- a/include/linux/futex.h +++ b/include/linux/futex.h @@ -12,9 +12,6 @@ struct task_struct; long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout, u32 __user *uaddr2, u32 val2, u32 val3);
-extern int -handle_futex_death(u32 __user *uaddr, struct task_struct *curr, int pi); - /* * Futexes are matched on equal values of this key. * The key type depends on whether it's a shared or private mapping. @@ -55,11 +52,6 @@ union futex_key {
#ifdef CONFIG_FUTEX extern void exit_robust_list(struct task_struct *curr); -#ifdef CONFIG_HAVE_FUTEX_CMPXCHG -#define futex_cmpxchg_enabled 1 -#else -extern int futex_cmpxchg_enabled; -#endif #else static inline void exit_robust_list(struct task_struct *curr) { --- a/kernel/Makefile +++ b/kernel/Makefile @@ -49,9 +49,6 @@ obj-$(CONFIG_PROFILING) += profile.o obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-y += time/ obj-$(CONFIG_FUTEX) += futex.o -ifeq ($(CONFIG_COMPAT),y) -obj-$(CONFIG_FUTEX) += futex_compat.o -endif obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o obj-$(CONFIG_SMP) += smp.o ifneq ($(CONFIG_SMP),y) --- a/kernel/futex.c +++ b/kernel/futex.c @@ -44,6 +44,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include <linux/compat.h> #include <linux/slab.h> #include <linux/poll.h> #include <linux/fs.h> @@ -173,8 +174,10 @@ * double_lock_hb() and double_unlock_hb(), respectively. */
-#ifndef CONFIG_HAVE_FUTEX_CMPXCHG -int __read_mostly futex_cmpxchg_enabled; +#ifdef CONFIG_HAVE_FUTEX_CMPXCHG +#define futex_cmpxchg_enabled 1 +#else +static int __read_mostly futex_cmpxchg_enabled; #endif
/* @@ -3476,7 +3479,7 @@ err_unlock: * Process a futex-list entry, check whether it's owned by the * dying task, and do notification if so: */ -int handle_futex_death(u32 __user *uaddr, struct task_struct *curr, int pi) +static int handle_futex_death(u32 __user *uaddr, struct task_struct *curr, int pi) { u32 uval, uninitialized_var(nval), mval; int err; @@ -3723,6 +3726,192 @@ SYSCALL_DEFINE6(futex, u32 __user *, uad return do_futex(uaddr, op, val, tp, uaddr2, val2, val3); }
+#ifdef CONFIG_COMPAT +/* + * Fetch a robust-list pointer. Bit 0 signals PI futexes: + */ +static inline int +compat_fetch_robust_entry(compat_uptr_t *uentry, struct robust_list __user **entry, + compat_uptr_t __user *head, unsigned int *pi) +{ + if (get_user(*uentry, head)) + return -EFAULT; + + *entry = compat_ptr((*uentry) & ~1); + *pi = (unsigned int)(*uentry) & 1; + + return 0; +} + +static void __user *futex_uaddr(struct robust_list __user *entry, + compat_long_t futex_offset) +{ + compat_uptr_t base = ptr_to_compat(entry); + void __user *uaddr = compat_ptr(base + futex_offset); + + return uaddr; +} + +/* + * Walk curr->robust_list (very carefully, it's a userspace list!) + * and mark any locks found there dead, and notify any waiters. + * + * We silently return on any sign of list-walking problem. + */ +void compat_exit_robust_list(struct task_struct *curr) +{ + struct compat_robust_list_head __user *head = curr->compat_robust_list; + struct robust_list __user *entry, *next_entry, *pending; + unsigned int limit = ROBUST_LIST_LIMIT, pi, pip; + unsigned int uninitialized_var(next_pi); + compat_uptr_t uentry, next_uentry, upending; + compat_long_t futex_offset; + int rc; + + if (!futex_cmpxchg_enabled) + return; + + /* + * Fetch the list head (which was registered earlier, via + * sys_set_robust_list()): + */ + if (compat_fetch_robust_entry(&uentry, &entry, &head->list.next, &pi)) + return; + /* + * Fetch the relative futex offset: + */ + if (get_user(futex_offset, &head->futex_offset)) + return; + /* + * Fetch any possibly pending lock-add first, and handle it + * if it exists: + */ + if (compat_fetch_robust_entry(&upending, &pending, + &head->list_op_pending, &pip)) + return; + + next_entry = NULL; /* avoid warning with gcc */ + while (entry != (struct robust_list __user *) &head->list) { + /* + * Fetch the next entry in the list before calling + * handle_futex_death: + */ + rc = compat_fetch_robust_entry(&next_uentry, &next_entry, + (compat_uptr_t __user *)&entry->next, &next_pi); + /* + * A pending lock might already be on the list, so + * dont process it twice: + */ + if (entry != pending) { + void __user *uaddr = futex_uaddr(entry, futex_offset); + + if (handle_futex_death(uaddr, curr, pi)) + return; + } + if (rc) + return; + uentry = next_uentry; + entry = next_entry; + pi = next_pi; + /* + * Avoid excessively long or circular lists: + */ + if (!--limit) + break; + + cond_resched(); + } + if (pending) { + void __user *uaddr = futex_uaddr(pending, futex_offset); + + handle_futex_death(uaddr, curr, pip); + } +} + +COMPAT_SYSCALL_DEFINE2(set_robust_list, + struct compat_robust_list_head __user *, head, + compat_size_t, len) +{ + if (!futex_cmpxchg_enabled) + return -ENOSYS; + + if (unlikely(len != sizeof(*head))) + return -EINVAL; + + current->compat_robust_list = head; + + return 0; +} + +COMPAT_SYSCALL_DEFINE3(get_robust_list, int, pid, + compat_uptr_t __user *, head_ptr, + compat_size_t __user *, len_ptr) +{ + struct compat_robust_list_head __user *head; + unsigned long ret; + struct task_struct *p; + + if (!futex_cmpxchg_enabled) + return -ENOSYS; + + rcu_read_lock(); + + ret = -ESRCH; + if (!pid) + p = current; + else { + p = find_task_by_vpid(pid); + if (!p) + goto err_unlock; + } + + ret = -EPERM; + if (!ptrace_may_access(p, PTRACE_MODE_READ_REALCREDS)) + goto err_unlock; + + head = p->compat_robust_list; + rcu_read_unlock(); + + if (put_user(sizeof(*head), len_ptr)) + return -EFAULT; + return put_user(ptr_to_compat(head), head_ptr); + +err_unlock: + rcu_read_unlock(); + + return ret; +} + +COMPAT_SYSCALL_DEFINE6(futex, u32 __user *, uaddr, int, op, u32, val, + struct compat_timespec __user *, utime, u32 __user *, uaddr2, + u32, val3) +{ + struct timespec ts; + ktime_t t, *tp = NULL; + int val2 = 0; + int cmd = op & FUTEX_CMD_MASK; + + if (utime && (cmd == FUTEX_WAIT || cmd == FUTEX_LOCK_PI || + cmd == FUTEX_WAIT_BITSET || + cmd == FUTEX_WAIT_REQUEUE_PI)) { + if (compat_get_timespec(&ts, utime)) + return -EFAULT; + if (!timespec_valid(&ts)) + return -EINVAL; + + t = timespec_to_ktime(ts); + if (cmd == FUTEX_WAIT) + t = ktime_add_safe(ktime_get(), t); + tp = &t; + } + if (cmd == FUTEX_REQUEUE || cmd == FUTEX_CMP_REQUEUE || + cmd == FUTEX_CMP_REQUEUE_PI || cmd == FUTEX_WAKE_OP) + val2 = (int) (unsigned long) utime; + + return do_futex(uaddr, op, val, tp, uaddr2, val2, val3); +} +#endif /* CONFIG_COMPAT */ + static void __init futex_detect_cmpxchg(void) { #ifndef CONFIG_HAVE_FUTEX_CMPXCHG --- a/kernel/futex_compat.c +++ /dev/null @@ -1,202 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * linux/kernel/futex_compat.c - * - * Futex compatibililty routines. - * - * Copyright 2006, Red Hat, Inc., Ingo Molnar - */ - -#include <linux/linkage.h> -#include <linux/compat.h> -#include <linux/nsproxy.h> -#include <linux/futex.h> -#include <linux/ptrace.h> -#include <linux/syscalls.h> - -#include <linux/uaccess.h> - - -/* - * Fetch a robust-list pointer. Bit 0 signals PI futexes: - */ -static inline int -fetch_robust_entry(compat_uptr_t *uentry, struct robust_list __user **entry, - compat_uptr_t __user *head, unsigned int *pi) -{ - if (get_user(*uentry, head)) - return -EFAULT; - - *entry = compat_ptr((*uentry) & ~1); - *pi = (unsigned int)(*uentry) & 1; - - return 0; -} - -static void __user *futex_uaddr(struct robust_list __user *entry, - compat_long_t futex_offset) -{ - compat_uptr_t base = ptr_to_compat(entry); - void __user *uaddr = compat_ptr(base + futex_offset); - - return uaddr; -} - -/* - * Walk curr->robust_list (very carefully, it's a userspace list!) - * and mark any locks found there dead, and notify any waiters. - * - * We silently return on any sign of list-walking problem. - */ -void compat_exit_robust_list(struct task_struct *curr) -{ - struct compat_robust_list_head __user *head = curr->compat_robust_list; - struct robust_list __user *entry, *next_entry, *pending; - unsigned int limit = ROBUST_LIST_LIMIT, pi, pip; - unsigned int uninitialized_var(next_pi); - compat_uptr_t uentry, next_uentry, upending; - compat_long_t futex_offset; - int rc; - - if (!futex_cmpxchg_enabled) - return; - - /* - * Fetch the list head (which was registered earlier, via - * sys_set_robust_list()): - */ - if (fetch_robust_entry(&uentry, &entry, &head->list.next, &pi)) - return; - /* - * Fetch the relative futex offset: - */ - if (get_user(futex_offset, &head->futex_offset)) - return; - /* - * Fetch any possibly pending lock-add first, and handle it - * if it exists: - */ - if (fetch_robust_entry(&upending, &pending, - &head->list_op_pending, &pip)) - return; - - next_entry = NULL; /* avoid warning with gcc */ - while (entry != (struct robust_list __user *) &head->list) { - /* - * Fetch the next entry in the list before calling - * handle_futex_death: - */ - rc = fetch_robust_entry(&next_uentry, &next_entry, - (compat_uptr_t __user *)&entry->next, &next_pi); - /* - * A pending lock might already be on the list, so - * dont process it twice: - */ - if (entry != pending) { - void __user *uaddr = futex_uaddr(entry, futex_offset); - - if (handle_futex_death(uaddr, curr, pi)) - return; - } - if (rc) - return; - uentry = next_uentry; - entry = next_entry; - pi = next_pi; - /* - * Avoid excessively long or circular lists: - */ - if (!--limit) - break; - - cond_resched(); - } - if (pending) { - void __user *uaddr = futex_uaddr(pending, futex_offset); - - handle_futex_death(uaddr, curr, pip); - } -} - -COMPAT_SYSCALL_DEFINE2(set_robust_list, - struct compat_robust_list_head __user *, head, - compat_size_t, len) -{ - if (!futex_cmpxchg_enabled) - return -ENOSYS; - - if (unlikely(len != sizeof(*head))) - return -EINVAL; - - current->compat_robust_list = head; - - return 0; -} - -COMPAT_SYSCALL_DEFINE3(get_robust_list, int, pid, - compat_uptr_t __user *, head_ptr, - compat_size_t __user *, len_ptr) -{ - struct compat_robust_list_head __user *head; - unsigned long ret; - struct task_struct *p; - - if (!futex_cmpxchg_enabled) - return -ENOSYS; - - rcu_read_lock(); - - ret = -ESRCH; - if (!pid) - p = current; - else { - p = find_task_by_vpid(pid); - if (!p) - goto err_unlock; - } - - ret = -EPERM; - if (!ptrace_may_access(p, PTRACE_MODE_READ_REALCREDS)) - goto err_unlock; - - head = p->compat_robust_list; - rcu_read_unlock(); - - if (put_user(sizeof(*head), len_ptr)) - return -EFAULT; - return put_user(ptr_to_compat(head), head_ptr); - -err_unlock: - rcu_read_unlock(); - - return ret; -} - -COMPAT_SYSCALL_DEFINE6(futex, u32 __user *, uaddr, int, op, u32, val, - struct compat_timespec __user *, utime, u32 __user *, uaddr2, - u32, val3) -{ - struct timespec ts; - ktime_t t, *tp = NULL; - int val2 = 0; - int cmd = op & FUTEX_CMD_MASK; - - if (utime && (cmd == FUTEX_WAIT || cmd == FUTEX_LOCK_PI || - cmd == FUTEX_WAIT_BITSET || - cmd == FUTEX_WAIT_REQUEUE_PI)) { - if (compat_get_timespec(&ts, utime)) - return -EFAULT; - if (!timespec_valid(&ts)) - return -EINVAL; - - t = timespec_to_ktime(ts); - if (cmd == FUTEX_WAIT) - t = ktime_add_safe(ktime_get(), t); - tp = &t; - } - if (cmd == FUTEX_REQUEUE || cmd == FUTEX_CMP_REQUEUE || - cmd == FUTEX_CMP_REQUEUE_PI || cmd == FUTEX_WAKE_OP) - val2 = (int) (unsigned long) utime; - - return do_futex(uaddr, op, val, tp, uaddr2, val2, val3); -}
From: Yang Tao yang.tao172@zte.com.cn
commit ca16d5bee59807bf04deaab0a8eccecd5061528c upstream.
Robust futexes utilize the robust_list mechanism to allow the kernel to release futexes which are held when a task exits. The exit can be voluntary or caused by a signal or fault. This prevents that waiters block forever.
The futex operations in user space store a pointer to the futex they are either locking or unlocking in the op_pending member of the per task robust list.
After a lock operation has succeeded the futex is queued in the robust list linked list and the op_pending pointer is cleared.
After an unlock operation has succeeded the futex is removed from the robust list linked list and the op_pending pointer is cleared.
The robust list exit code checks for the pending operation and any futex which is queued in the linked list. It carefully checks whether the futex value is the TID of the exiting task. If so, it sets the OWNER_DIED bit and tries to wake up a potential waiter.
This is race free for the lock operation but unlock has two race scenarios where waiters might not be woken up. These issues can be observed with regular robust pthread mutexes. PI aware pthread mutexes are not affected.
(1) Unlocking task is killed after unlocking the futex value in user space before being able to wake a waiter.
pthread_mutex_unlock() | V atomic_exchange_rel (&mutex->__data.__lock, 0) <------------------------killed lll_futex_wake () | | |(__lock = 0) |(enter kernel) | V do_exit() exit_mm() mm_release() exit_robust_list() handle_futex_death() | |(__lock = 0) |(uval = 0) | V if ((uval & FUTEX_TID_MASK) != task_pid_vnr(curr)) return 0;
The sanity check which ensures that the user space futex is owned by the exiting task prevents the wakeup of waiters which in consequence block infinitely.
(2) Waiting task is killed after a wakeup and before it can acquire the futex in user space.
OWNER WAITER futex_wait() pthread_mutex_unlock() | | | |(__lock = 0) | | | V | futex_wake() ------------> wakeup() | |(return to userspace) |(__lock = 0) | V oldval = mutex->__data.__lock <-----------------killed atomic_compare_and_exchange_val_acq (&mutex->__data.__lock, | id | assume_other_futex_waiters, 0) | | | (enter kernel)| | V do_exit() | | V handle_futex_death() | |(__lock = 0) |(uval = 0) | V if ((uval & FUTEX_TID_MASK) != task_pid_vnr(curr)) return 0;
The sanity check which ensures that the user space futex is owned by the exiting task prevents the wakeup of waiters, which seems to be correct as the exiting task does not own the futex value, but the consequence is that other waiters wont be woken up and block infinitely.
In both scenarios the following conditions are true:
- task->robust_list->list_op_pending != NULL - user space futex value == 0 - Regular futex (not PI)
If these conditions are met then it is reasonably safe to wake up a potential waiter in order to prevent the above problems.
As this might be a false positive it can cause spurious wakeups, but the waiter side has to handle other types of unrelated wakeups, e.g. signals gracefully anyway. So such a spurious wakeup will not affect the correctness of these operations.
This workaround must not touch the user space futex value and cannot set the OWNER_DIED bit because the lock value is 0, i.e. uncontended. Setting OWNER_DIED in this case would result in inconsistent state and subsequently in malfunction of the owner died handling in user space.
The rest of the user space state is still consistent as no other task can observe the list_op_pending entry in the exiting tasks robust list.
The eventually woken up waiter will observe the uncontended lock value and take it over.
[ tglx: Massaged changelog and comment. Made the return explicit and not depend on the subsequent check and added constants to hand into handle_futex_death() instead of plain numbers. Fixed a few coding style issues. ]
Fixes: 0771dfefc9e5 ("[PATCH] lightweight robust futexes: core") Signed-off-by: Yang Tao yang.tao172@zte.com.cn Signed-off-by: Yi Wang wang.yi59@zte.com.cn Signed-off-by: Thomas Gleixner tglx@linutronix.de Reviewed-by: Ingo Molnar mingo@kernel.org Acked-by: Peter Zijlstra (Intel) peterz@infradead.org Cc: stable@vger.kernel.org Link: https://lkml.kernel.org/r/1573010582-35297-1-git-send-email-wang.yi59@zte.co... Link: https://lkml.kernel.org/r/20191106224555.943191378@linutronix.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- kernel/futex.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 51 insertions(+), 7 deletions(-)
--- a/kernel/futex.c +++ b/kernel/futex.c @@ -3475,11 +3475,16 @@ err_unlock: return ret; }
+/* Constants for the pending_op argument of handle_futex_death */ +#define HANDLE_DEATH_PENDING true +#define HANDLE_DEATH_LIST false + /* * Process a futex-list entry, check whether it's owned by the * dying task, and do notification if so: */ -static int handle_futex_death(u32 __user *uaddr, struct task_struct *curr, int pi) +static int handle_futex_death(u32 __user *uaddr, struct task_struct *curr, + bool pi, bool pending_op) { u32 uval, uninitialized_var(nval), mval; int err; @@ -3492,6 +3497,42 @@ retry: if (get_user(uval, uaddr)) return -1;
+ /* + * Special case for regular (non PI) futexes. The unlock path in + * user space has two race scenarios: + * + * 1. The unlock path releases the user space futex value and + * before it can execute the futex() syscall to wake up + * waiters it is killed. + * + * 2. A woken up waiter is killed before it can acquire the + * futex in user space. + * + * In both cases the TID validation below prevents a wakeup of + * potential waiters which can cause these waiters to block + * forever. + * + * In both cases the following conditions are met: + * + * 1) task->robust_list->list_op_pending != NULL + * @pending_op == true + * 2) User space futex value == 0 + * 3) Regular futex: @pi == false + * + * If these conditions are met, it is safe to attempt waking up a + * potential waiter without touching the user space futex value and + * trying to set the OWNER_DIED bit. The user space futex value is + * uncontended and the rest of the user space mutex state is + * consistent, so a woken waiter will just take over the + * uncontended futex. Setting the OWNER_DIED bit would create + * inconsistent state and malfunction of the user space owner died + * handling. + */ + if (pending_op && !pi && !uval) { + futex_wake(uaddr, 1, 1, FUTEX_BITSET_MATCH_ANY); + return 0; + } + if ((uval & FUTEX_TID_MASK) != task_pid_vnr(curr)) return 0;
@@ -3611,10 +3652,11 @@ void exit_robust_list(struct task_struct * A pending lock might already be on the list, so * don't process it twice: */ - if (entry != pending) + if (entry != pending) { if (handle_futex_death((void __user *)entry + futex_offset, - curr, pi)) + curr, pi, HANDLE_DEATH_LIST)) return; + } if (rc) return; entry = next_entry; @@ -3628,9 +3670,10 @@ void exit_robust_list(struct task_struct cond_resched(); }
- if (pending) + if (pending) { handle_futex_death((void __user *)pending + futex_offset, - curr, pip); + curr, pip, HANDLE_DEATH_PENDING); + } }
long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout, @@ -3805,7 +3848,8 @@ void compat_exit_robust_list(struct task if (entry != pending) { void __user *uaddr = futex_uaddr(entry, futex_offset);
- if (handle_futex_death(uaddr, curr, pi)) + if (handle_futex_death(uaddr, curr, pi, + HANDLE_DEATH_LIST)) return; } if (rc) @@ -3824,7 +3868,7 @@ void compat_exit_robust_list(struct task if (pending) { void __user *uaddr = futex_uaddr(pending, futex_offset);
- handle_futex_death(uaddr, curr, pip); + handle_futex_death(uaddr, curr, pip, HANDLE_DEATH_PENDING); } }
From: Thomas Gleixner tglx@linutronix.de
commit ba31c1a48538992316cc71ce94fa9cd3e7b427c0 upstream.
The futex exit handling is #ifdeffed into mm_release() which is not pretty to begin with. But upcoming changes to address futex exit races need to add more functionality to this exit code.
Split it out into a function, move it into futex code and make the various futex exit functions static.
Preparatory only and no functional change.
Folded build fix from Borislav.
Signed-off-by: Thomas Gleixner tglx@linutronix.de Reviewed-by: Ingo Molnar mingo@kernel.org Acked-by: Peter Zijlstra (Intel) peterz@infradead.org Link: https://lkml.kernel.org/r/20191106224556.049705556@linutronix.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- include/linux/compat.h | 2 -- include/linux/futex.h | 25 ++++++++++++++++--------- kernel/fork.c | 25 +++---------------------- kernel/futex.c | 33 +++++++++++++++++++++++++++++---- 4 files changed, 48 insertions(+), 37 deletions(-)
--- a/include/linux/compat.h +++ b/include/linux/compat.h @@ -324,8 +324,6 @@ struct compat_kexec_segment; struct compat_mq_attr; struct compat_msgbuf;
-extern void compat_exit_robust_list(struct task_struct *curr); - asmlinkage long compat_sys_set_robust_list(struct compat_robust_list_head __user *head, compat_size_t len); --- a/include/linux/futex.h +++ b/include/linux/futex.h @@ -2,7 +2,9 @@ #ifndef _LINUX_FUTEX_H #define _LINUX_FUTEX_H
+#include <linux/sched.h> #include <linux/ktime.h> + #include <uapi/linux/futex.h>
struct inode; @@ -51,19 +53,24 @@ union futex_key { #define FUTEX_KEY_INIT (union futex_key) { .both = { .ptr = NULL } }
#ifdef CONFIG_FUTEX -extern void exit_robust_list(struct task_struct *curr); -#else -static inline void exit_robust_list(struct task_struct *curr) + +static inline void futex_init_task(struct task_struct *tsk) { -} + tsk->robust_list = NULL; +#ifdef CONFIG_COMPAT + tsk->compat_robust_list = NULL; #endif + INIT_LIST_HEAD(&tsk->pi_state_list); + tsk->pi_state_cache = NULL; +}
-#ifdef CONFIG_FUTEX_PI -extern void exit_pi_state_list(struct task_struct *curr); +void futex_mm_release(struct task_struct *tsk); + +long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout, + u32 __user *uaddr2, u32 val2, u32 val3); #else -static inline void exit_pi_state_list(struct task_struct *curr) -{ -} +static inline void futex_init_task(struct task_struct *tsk) { } +static inline void futex_mm_release(struct task_struct *tsk) { } #endif
#endif --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1135,20 +1135,7 @@ static int wait_for_vfork_done(struct ta void mm_release(struct task_struct *tsk, struct mm_struct *mm) { /* Get rid of any futexes when releasing the mm */ -#ifdef CONFIG_FUTEX - if (unlikely(tsk->robust_list)) { - exit_robust_list(tsk); - tsk->robust_list = NULL; - } -#ifdef CONFIG_COMPAT - if (unlikely(tsk->compat_robust_list)) { - compat_exit_robust_list(tsk); - tsk->compat_robust_list = NULL; - } -#endif - if (unlikely(!list_empty(&tsk->pi_state_list))) - exit_pi_state_list(tsk); -#endif + futex_mm_release(tsk);
uprobe_free_utask(tsk);
@@ -1796,14 +1783,8 @@ static __latent_entropy struct task_stru #ifdef CONFIG_BLOCK p->plug = NULL; #endif -#ifdef CONFIG_FUTEX - p->robust_list = NULL; -#ifdef CONFIG_COMPAT - p->compat_robust_list = NULL; -#endif - INIT_LIST_HEAD(&p->pi_state_list); - p->pi_state_cache = NULL; -#endif + futex_init_task(p); + /* * sigaltstack should be cleared when sharing the same VM */ --- a/kernel/futex.c +++ b/kernel/futex.c @@ -341,6 +341,12 @@ static inline bool should_fail_futex(boo } #endif /* CONFIG_FAIL_FUTEX */
+#ifdef CONFIG_COMPAT +static void compat_exit_robust_list(struct task_struct *curr); +#else +static inline void compat_exit_robust_list(struct task_struct *curr) { } +#endif + static inline void futex_get_mm(union futex_key *key) { mmgrab(key->private.mm); @@ -890,7 +896,7 @@ static struct task_struct *futex_find_ge * Kernel cleans up PI-state, but userspace is likely hosed. * (Robust-futex cleanup is separate and might save the day for userspace.) */ -void exit_pi_state_list(struct task_struct *curr) +static void exit_pi_state_list(struct task_struct *curr) { struct list_head *next, *head = &curr->pi_state_list; struct futex_pi_state *pi_state; @@ -960,7 +966,8 @@ void exit_pi_state_list(struct task_stru } raw_spin_unlock_irq(&curr->pi_lock); } - +#else +static inline void exit_pi_state_list(struct task_struct *curr) { } #endif
/* @@ -3611,7 +3618,7 @@ static inline int fetch_robust_entry(str * * We silently return on any sign of list-walking problem. */ -void exit_robust_list(struct task_struct *curr) +static void exit_robust_list(struct task_struct *curr) { struct robust_list_head __user *head = curr->robust_list; struct robust_list __user *entry, *next_entry, *pending; @@ -3676,6 +3683,24 @@ void exit_robust_list(struct task_struct } }
+void futex_mm_release(struct task_struct *tsk) +{ + if (unlikely(tsk->robust_list)) { + exit_robust_list(tsk); + tsk->robust_list = NULL; + } + +#ifdef CONFIG_COMPAT + if (unlikely(tsk->compat_robust_list)) { + compat_exit_robust_list(tsk); + tsk->compat_robust_list = NULL; + } +#endif + + if (unlikely(!list_empty(&tsk->pi_state_list))) + exit_pi_state_list(tsk); +} + long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout, u32 __user *uaddr2, u32 val2, u32 val3) { @@ -3801,7 +3826,7 @@ static void __user *futex_uaddr(struct r * * We silently return on any sign of list-walking problem. */ -void compat_exit_robust_list(struct task_struct *curr) +static void compat_exit_robust_list(struct task_struct *curr) { struct compat_robust_list_head __user *head = curr->compat_robust_list; struct robust_list __user *entry, *next_entry, *pending;
From: Thomas Gleixner tglx@linutronix.de
commit 3d4775df0a89240f671861c6ab6e8d59af8e9e41 upstream.
The futex exit handling relies on PF_ flags. That's suboptimal as it requires a smp_mb() and an ugly lock/unlock of the exiting tasks pi_lock in the middle of do_exit() to enforce the observability of PF_EXITING in the futex code.
Add a futex_state member to task_struct and convert the PF_EXITPIDONE logic over to the new state. The PF_EXITING dependency will be cleaned up in a later step.
This prepares for handling various futex exit issues later.
Signed-off-by: Thomas Gleixner tglx@linutronix.de Reviewed-by: Ingo Molnar mingo@kernel.org Acked-by: Peter Zijlstra (Intel) peterz@infradead.org Link: https://lkml.kernel.org/r/20191106224556.149449274@linutronix.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- include/linux/futex.h | 33 +++++++++++++++++++++++++++++++++ include/linux/sched.h | 2 +- kernel/exit.c | 18 ++---------------- kernel/futex.c | 25 +++++++++++++------------ 4 files changed, 49 insertions(+), 29 deletions(-)
--- a/include/linux/futex.h +++ b/include/linux/futex.h @@ -53,6 +53,10 @@ union futex_key { #define FUTEX_KEY_INIT (union futex_key) { .both = { .ptr = NULL } }
#ifdef CONFIG_FUTEX +enum { + FUTEX_STATE_OK, + FUTEX_STATE_DEAD, +};
static inline void futex_init_task(struct task_struct *tsk) { @@ -62,6 +66,34 @@ static inline void futex_init_task(struc #endif INIT_LIST_HEAD(&tsk->pi_state_list); tsk->pi_state_cache = NULL; + tsk->futex_state = FUTEX_STATE_OK; +} + +/** + * futex_exit_done - Sets the tasks futex state to FUTEX_STATE_DEAD + * @tsk: task to set the state on + * + * Set the futex exit state of the task lockless. The futex waiter code + * observes that state when a task is exiting and loops until the task has + * actually finished the futex cleanup. The worst case for this is that the + * waiter runs through the wait loop until the state becomes visible. + * + * This has two callers: + * + * - futex_mm_release() after the futex exit cleanup has been done + * + * - do_exit() from the recursive fault handling path. + * + * In case of a recursive fault this is best effort. Either the futex exit + * code has run already or not. If the OWNER_DIED bit has been set on the + * futex then the waiter can take it over. If not, the problem is pushed + * back to user space. If the futex exit code did not run yet, then an + * already queued waiter might block forever, but there is nothing which + * can be done about that. + */ +static inline void futex_exit_done(struct task_struct *tsk) +{ + tsk->futex_state = FUTEX_STATE_DEAD; }
void futex_mm_release(struct task_struct *tsk); @@ -71,6 +103,7 @@ long do_futex(u32 __user *uaddr, int op, #else static inline void futex_init_task(struct task_struct *tsk) { } static inline void futex_mm_release(struct task_struct *tsk) { } +static inline void futex_exit_done(struct task_struct *tsk) { } #endif
#endif --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -959,6 +959,7 @@ struct task_struct { #endif struct list_head pi_state_list; struct futex_pi_state *pi_state_cache; + unsigned int futex_state; #endif #ifdef CONFIG_PERF_EVENTS struct perf_event_context *perf_event_ctxp[perf_nr_task_contexts]; @@ -1334,7 +1335,6 @@ extern struct pid *cad_pid; */ #define PF_IDLE 0x00000002 /* I am an IDLE thread */ #define PF_EXITING 0x00000004 /* Getting shut down */ -#define PF_EXITPIDONE 0x00000008 /* PI exit done on shut down */ #define PF_VCPU 0x00000010 /* I'm a virtual CPU */ #define PF_WQ_WORKER 0x00000020 /* I'm a workqueue worker */ #define PF_FORKNOEXEC 0x00000040 /* Forked but didn't exec */ --- a/kernel/exit.c +++ b/kernel/exit.c @@ -803,16 +803,7 @@ void __noreturn do_exit(long code) */ if (unlikely(tsk->flags & PF_EXITING)) { pr_alert("Fixing recursive fault but reboot is needed!\n"); - /* - * We can do this unlocked here. The futex code uses - * this flag just to verify whether the pi state - * cleanup has been done or not. In the worst case it - * loops once more. We pretend that the cleanup was - * done as there is no way to return. Either the - * OWNER_DIED bit is set by now or we push the blocked - * task into the wait for ever nirwana as well. - */ - tsk->flags |= PF_EXITPIDONE; + futex_exit_done(tsk); set_current_state(TASK_UNINTERRUPTIBLE); schedule(); } @@ -902,12 +893,7 @@ void __noreturn do_exit(long code) * Make sure we are holding no locks: */ debug_check_no_locks_held(); - /* - * We can do this unlocked here. The futex code uses this flag - * just to verify whether the pi state cleanup has been done - * or not. In the worst case it loops once more. - */ - tsk->flags |= PF_EXITPIDONE; + futex_exit_done(tsk);
if (tsk->io_context) exit_io_context(tsk); --- a/kernel/futex.c +++ b/kernel/futex.c @@ -1182,9 +1182,10 @@ static int handle_exit_race(u32 __user * u32 uval2;
/* - * If PF_EXITPIDONE is not yet set, then try again. + * If the futex exit state is not yet FUTEX_STATE_DEAD, wait + * for it to finish. */ - if (tsk && !(tsk->flags & PF_EXITPIDONE)) + if (tsk && tsk->futex_state != FUTEX_STATE_DEAD) return -EAGAIN;
/* @@ -1203,8 +1204,9 @@ static int handle_exit_race(u32 __user * * *uaddr = 0xC0000000; tsk = get_task(PID); * } if (!tsk->flags & PF_EXITING) { * ... attach(); - * tsk->flags |= PF_EXITPIDONE; } else { - * if (!(tsk->flags & PF_EXITPIDONE)) + * tsk->futex_state = } else { + * FUTEX_STATE_DEAD; if (tsk->futex_state != + * FUTEX_STATE_DEAD) * return -EAGAIN; * return -ESRCH; <--- FAIL * } @@ -1260,17 +1262,16 @@ static int attach_to_pi_owner(u32 __user }
/* - * We need to look at the task state flags to figure out, - * whether the task is exiting. To protect against the do_exit - * change of the task flags, we do this protected by - * p->pi_lock: + * We need to look at the task state to figure out, whether the + * task is exiting. To protect against the change of the task state + * in futex_exit_release(), we do this protected by p->pi_lock: */ raw_spin_lock_irq(&p->pi_lock); - if (unlikely(p->flags & PF_EXITING)) { + if (unlikely(p->futex_state != FUTEX_STATE_OK)) { /* - * The task is on the way out. When PF_EXITPIDONE is - * set, we know that the task has finished the - * cleanup: + * The task is on the way out. When the futex state is + * FUTEX_STATE_DEAD, we know that the task has finished + * the cleanup: */ int ret = handle_exit_race(uaddr, uval, p);
From: Thomas Gleixner tglx@linutronix.de
commit 4610ba7ad877fafc0a25a30c6c82015304120426 upstream.
mm_release() contains the futex exit handling. mm_release() is called from do_exit()->exit_mm() and from exec()->exec_mm().
In the exit_mm() case PF_EXITING and the futex state is updated. In the exec_mm() case these states are not touched.
As the futex exit code needs further protections against exit races, this needs to be split into two functions.
Preparatory only, no functional change.
Signed-off-by: Thomas Gleixner tglx@linutronix.de Reviewed-by: Ingo Molnar mingo@kernel.org Acked-by: Peter Zijlstra (Intel) peterz@infradead.org Link: https://lkml.kernel.org/r/20191106224556.240518241@linutronix.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/exec.c | 2 +- include/linux/sched/mm.h | 6 ++++-- kernel/exit.c | 2 +- kernel/fork.c | 12 +++++++++++- 4 files changed, 17 insertions(+), 5 deletions(-)
--- a/fs/exec.c +++ b/fs/exec.c @@ -1007,7 +1007,7 @@ static int exec_mmap(struct mm_struct *m /* Notify parent that we're no longer interested in the old VM */ tsk = current; old_mm = current->mm; - mm_release(tsk, old_mm); + exec_mm_release(tsk, old_mm);
if (old_mm) { sync_mm_rss(old_mm); --- a/include/linux/sched/mm.h +++ b/include/linux/sched/mm.h @@ -125,8 +125,10 @@ extern struct mm_struct *get_task_mm(str * succeeds. */ extern struct mm_struct *mm_access(struct task_struct *task, unsigned int mode); -/* Remove the current tasks stale references to the old mm_struct */ -extern void mm_release(struct task_struct *, struct mm_struct *); +/* Remove the current tasks stale references to the old mm_struct on exit() */ +extern void exit_mm_release(struct task_struct *, struct mm_struct *); +/* Remove the current tasks stale references to the old mm_struct on exec() */ +extern void exec_mm_release(struct task_struct *, struct mm_struct *);
#ifdef CONFIG_MEMCG extern void mm_update_next_owner(struct mm_struct *mm); --- a/kernel/exit.c +++ b/kernel/exit.c @@ -497,7 +497,7 @@ static void exit_mm(void) struct mm_struct *mm = current->mm; struct core_state *core_state;
- mm_release(current, mm); + exit_mm_release(current, mm); if (!mm) return; sync_mm_rss(mm); --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1132,7 +1132,7 @@ static int wait_for_vfork_done(struct ta * restoring the old one. . . * Eric Biederman 10 January 1998 */ -void mm_release(struct task_struct *tsk, struct mm_struct *mm) +static void mm_release(struct task_struct *tsk, struct mm_struct *mm) { /* Get rid of any futexes when releasing the mm */ futex_mm_release(tsk); @@ -1169,6 +1169,16 @@ void mm_release(struct task_struct *tsk, complete_vfork_done(tsk); }
+void exit_mm_release(struct task_struct *tsk, struct mm_struct *mm) +{ + mm_release(tsk, mm); +} + +void exec_mm_release(struct task_struct *tsk, struct mm_struct *mm) +{ + mm_release(tsk, mm); +} + /* * Allocate a new mm structure and copy contents from the * mm structure of the passed in task structure.
From: Thomas Gleixner tglx@linutronix.de
commit 150d71584b12809144b8145b817e83b81158ae5f upstream.
To allow separate handling of the futex exit state in the futex exit code for exit and exec, split futex_mm_release() into two functions and invoke them from the corresponding exit/exec_mm_release() callsites.
Preparatory only, no functional change.
Signed-off-by: Thomas Gleixner tglx@linutronix.de Reviewed-by: Ingo Molnar mingo@kernel.org Acked-by: Peter Zijlstra (Intel) peterz@infradead.org Link: https://lkml.kernel.org/r/20191106224556.332094221@linutronix.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- include/linux/futex.h | 6 ++++-- kernel/fork.c | 5 ++--- kernel/futex.c | 7 ++++++- 3 files changed, 12 insertions(+), 6 deletions(-)
--- a/include/linux/futex.h +++ b/include/linux/futex.h @@ -96,14 +96,16 @@ static inline void futex_exit_done(struc tsk->futex_state = FUTEX_STATE_DEAD; }
-void futex_mm_release(struct task_struct *tsk); +void futex_exit_release(struct task_struct *tsk); +void futex_exec_release(struct task_struct *tsk);
long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout, u32 __user *uaddr2, u32 val2, u32 val3); #else static inline void futex_init_task(struct task_struct *tsk) { } -static inline void futex_mm_release(struct task_struct *tsk) { } static inline void futex_exit_done(struct task_struct *tsk) { } +static inline void futex_exit_release(struct task_struct *tsk) { } +static inline void futex_exec_release(struct task_struct *tsk) { } #endif
#endif --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1134,9 +1134,6 @@ static int wait_for_vfork_done(struct ta */ static void mm_release(struct task_struct *tsk, struct mm_struct *mm) { - /* Get rid of any futexes when releasing the mm */ - futex_mm_release(tsk); - uprobe_free_utask(tsk);
/* Get rid of any cached register state */ @@ -1171,11 +1168,13 @@ static void mm_release(struct task_struc
void exit_mm_release(struct task_struct *tsk, struct mm_struct *mm) { + futex_exit_release(tsk); mm_release(tsk, mm); }
void exec_mm_release(struct task_struct *tsk, struct mm_struct *mm) { + futex_exec_release(tsk); mm_release(tsk, mm); }
--- a/kernel/futex.c +++ b/kernel/futex.c @@ -3684,7 +3684,7 @@ static void exit_robust_list(struct task } }
-void futex_mm_release(struct task_struct *tsk) +void futex_exec_release(struct task_struct *tsk) { if (unlikely(tsk->robust_list)) { exit_robust_list(tsk); @@ -3702,6 +3702,11 @@ void futex_mm_release(struct task_struct exit_pi_state_list(tsk); }
+void futex_exit_release(struct task_struct *tsk) +{ + futex_exec_release(tsk); +} + long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout, u32 __user *uaddr2, u32 val2, u32 val3) {
From: Thomas Gleixner tglx@linutronix.de
commit f24f22435dcc11389acc87e5586239c1819d217c upstream.
Setting task::futex_state in do_exit() is rather arbitrarily placed for no reason. Move it into the futex code.
Note, this is only done for the exit cleanup as the exec cleanup cannot set the state to FUTEX_STATE_DEAD because the task struct is still in active use.
Signed-off-by: Thomas Gleixner tglx@linutronix.de Reviewed-by: Ingo Molnar mingo@kernel.org Acked-by: Peter Zijlstra (Intel) peterz@infradead.org Link: https://lkml.kernel.org/r/20191106224556.439511191@linutronix.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- kernel/exit.c | 1 - kernel/futex.c | 1 + 2 files changed, 1 insertion(+), 1 deletion(-)
--- a/kernel/exit.c +++ b/kernel/exit.c @@ -893,7 +893,6 @@ void __noreturn do_exit(long code) * Make sure we are holding no locks: */ debug_check_no_locks_held(); - futex_exit_done(tsk);
if (tsk->io_context) exit_io_context(tsk); --- a/kernel/futex.c +++ b/kernel/futex.c @@ -3705,6 +3705,7 @@ void futex_exec_release(struct task_stru void futex_exit_release(struct task_struct *tsk) { futex_exec_release(tsk); + futex_exit_done(tsk); }
long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout,
From: Thomas Gleixner tglx@linutronix.de
commit 18f694385c4fd77a09851fd301236746ca83f3cb upstream.
Instead of relying on PF_EXITING use an explicit state for the futex exit and set it in the futex exit function. This moves the smp barrier and the lock/unlock serialization into the futex code.
As with the DEAD state this is restricted to the exit path as exec continues to use the same task struct.
This allows to simplify that logic in a next step.
Signed-off-by: Thomas Gleixner tglx@linutronix.de Reviewed-by: Ingo Molnar mingo@kernel.org Acked-by: Peter Zijlstra (Intel) peterz@infradead.org Link: https://lkml.kernel.org/r/20191106224556.539409004@linutronix.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- include/linux/futex.h | 31 +++---------------------------- kernel/exit.c | 13 +------------ kernel/futex.c | 37 ++++++++++++++++++++++++++++++++++++- 3 files changed, 40 insertions(+), 41 deletions(-)
--- a/include/linux/futex.h +++ b/include/linux/futex.h @@ -55,6 +55,7 @@ union futex_key { #ifdef CONFIG_FUTEX enum { FUTEX_STATE_OK, + FUTEX_STATE_EXITING, FUTEX_STATE_DEAD, };
@@ -69,33 +70,7 @@ static inline void futex_init_task(struc tsk->futex_state = FUTEX_STATE_OK; }
-/** - * futex_exit_done - Sets the tasks futex state to FUTEX_STATE_DEAD - * @tsk: task to set the state on - * - * Set the futex exit state of the task lockless. The futex waiter code - * observes that state when a task is exiting and loops until the task has - * actually finished the futex cleanup. The worst case for this is that the - * waiter runs through the wait loop until the state becomes visible. - * - * This has two callers: - * - * - futex_mm_release() after the futex exit cleanup has been done - * - * - do_exit() from the recursive fault handling path. - * - * In case of a recursive fault this is best effort. Either the futex exit - * code has run already or not. If the OWNER_DIED bit has been set on the - * futex then the waiter can take it over. If not, the problem is pushed - * back to user space. If the futex exit code did not run yet, then an - * already queued waiter might block forever, but there is nothing which - * can be done about that. - */ -static inline void futex_exit_done(struct task_struct *tsk) -{ - tsk->futex_state = FUTEX_STATE_DEAD; -} - +void futex_exit_recursive(struct task_struct *tsk); void futex_exit_release(struct task_struct *tsk); void futex_exec_release(struct task_struct *tsk);
@@ -103,7 +78,7 @@ long do_futex(u32 __user *uaddr, int op, u32 __user *uaddr2, u32 val2, u32 val3); #else static inline void futex_init_task(struct task_struct *tsk) { } -static inline void futex_exit_done(struct task_struct *tsk) { } +static inline void futex_exit_recursive(struct task_struct *tsk) { } static inline void futex_exit_release(struct task_struct *tsk) { } static inline void futex_exec_release(struct task_struct *tsk) { } #endif --- a/kernel/exit.c +++ b/kernel/exit.c @@ -803,23 +803,12 @@ void __noreturn do_exit(long code) */ if (unlikely(tsk->flags & PF_EXITING)) { pr_alert("Fixing recursive fault but reboot is needed!\n"); - futex_exit_done(tsk); + futex_exit_recursive(tsk); set_current_state(TASK_UNINTERRUPTIBLE); schedule(); }
exit_signals(tsk); /* sets PF_EXITING */ - /* - * Ensure that all new tsk->pi_lock acquisitions must observe - * PF_EXITING. Serializes against futex.c:attach_to_pi_owner(). - */ - smp_mb(); - /* - * Ensure that we must observe the pi_state in exit_mm() -> - * mm_release() -> exit_pi_state_list(). - */ - raw_spin_lock_irq(&tsk->pi_lock); - raw_spin_unlock_irq(&tsk->pi_lock);
if (unlikely(in_atomic())) { pr_info("note: %s[%d] exited with preempt_count %d\n", --- a/kernel/futex.c +++ b/kernel/futex.c @@ -3702,10 +3702,45 @@ void futex_exec_release(struct task_stru exit_pi_state_list(tsk); }
+/** + * futex_exit_recursive - Set the tasks futex state to FUTEX_STATE_DEAD + * @tsk: task to set the state on + * + * Set the futex exit state of the task lockless. The futex waiter code + * observes that state when a task is exiting and loops until the task has + * actually finished the futex cleanup. The worst case for this is that the + * waiter runs through the wait loop until the state becomes visible. + * + * This is called from the recursive fault handling path in do_exit(). + * + * This is best effort. Either the futex exit code has run already or + * not. If the OWNER_DIED bit has been set on the futex then the waiter can + * take it over. If not, the problem is pushed back to user space. If the + * futex exit code did not run yet, then an already queued waiter might + * block forever, but there is nothing which can be done about that. + */ +void futex_exit_recursive(struct task_struct *tsk) +{ + tsk->futex_state = FUTEX_STATE_DEAD; +} + void futex_exit_release(struct task_struct *tsk) { + tsk->futex_state = FUTEX_STATE_EXITING; + /* + * Ensure that all new tsk->pi_lock acquisitions must observe + * FUTEX_STATE_EXITING. Serializes against attach_to_pi_owner(). + */ + smp_mb(); + /* + * Ensure that we must observe the pi_state in exit_pi_state_list(). + */ + raw_spin_lock_irq(&tsk->pi_lock); + raw_spin_unlock_irq(&tsk->pi_lock); + futex_exec_release(tsk); - futex_exit_done(tsk); + + tsk->futex_state = FUTEX_STATE_DEAD; }
long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout,
From: Thomas Gleixner tglx@linutronix.de
commit 4a8e991b91aca9e20705d434677ac013974e0e30 upstream.
Instead of having a smp_mb() and an empty lock/unlock of task::pi_lock move the state setting into to the lock section.
Signed-off-by: Thomas Gleixner tglx@linutronix.de Reviewed-by: Ingo Molnar mingo@kernel.org Acked-by: Peter Zijlstra (Intel) peterz@infradead.org Link: https://lkml.kernel.org/r/20191106224556.645603214@linutronix.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- kernel/futex.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-)
--- a/kernel/futex.c +++ b/kernel/futex.c @@ -3726,16 +3726,19 @@ void futex_exit_recursive(struct task_st
void futex_exit_release(struct task_struct *tsk) { - tsk->futex_state = FUTEX_STATE_EXITING; - /* - * Ensure that all new tsk->pi_lock acquisitions must observe - * FUTEX_STATE_EXITING. Serializes against attach_to_pi_owner(). - */ - smp_mb(); /* - * Ensure that we must observe the pi_state in exit_pi_state_list(). + * Switch the state to FUTEX_STATE_EXITING under tsk->pi_lock. + * + * This ensures that all subsequent checks of tsk->futex_state in + * attach_to_pi_owner() must observe FUTEX_STATE_EXITING with + * tsk->pi_lock held. + * + * It guarantees also that a pi_state which was queued right before + * the state change under tsk->pi_lock by a concurrent waiter must + * be observed in exit_pi_state_list(). */ raw_spin_lock_irq(&tsk->pi_lock); + tsk->futex_state = FUTEX_STATE_EXITING; raw_spin_unlock_irq(&tsk->pi_lock);
futex_exec_release(tsk);
From: Thomas Gleixner tglx@linutronix.de
commit af8cbda2cfcaa5515d61ec500498d46e9a8247e2 upstream.
exec() attempts to handle potentially held futexes gracefully by running the futex exit handling code like exit() does.
The current implementation has no protection against concurrent incoming waiters. The reason is that the futex state cannot be set to FUTEX_STATE_DEAD after the cleanup because the task struct is still active and just about to execute the new binary.
While its arguably buggy when a task holds a futex over exec(), for consistency sake the state handling can at least cover the actual futex exit cleanup section. This provides state consistency protection accross the cleanup. As the futex state of the task becomes FUTEX_STATE_OK after the cleanup has been finished, this cannot prevent subsequent attempts to attach to the task in case that the cleanup was not successfull in mopping up all leftovers.
Signed-off-by: Thomas Gleixner tglx@linutronix.de Reviewed-by: Ingo Molnar mingo@kernel.org Acked-by: Peter Zijlstra (Intel) peterz@infradead.org Link: https://lkml.kernel.org/r/20191106224556.753355618@linutronix.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- kernel/futex.c | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-)
--- a/kernel/futex.c +++ b/kernel/futex.c @@ -3684,7 +3684,7 @@ static void exit_robust_list(struct task } }
-void futex_exec_release(struct task_struct *tsk) +static void futex_cleanup(struct task_struct *tsk) { if (unlikely(tsk->robust_list)) { exit_robust_list(tsk); @@ -3724,7 +3724,7 @@ void futex_exit_recursive(struct task_st tsk->futex_state = FUTEX_STATE_DEAD; }
-void futex_exit_release(struct task_struct *tsk) +static void futex_cleanup_begin(struct task_struct *tsk) { /* * Switch the state to FUTEX_STATE_EXITING under tsk->pi_lock. @@ -3740,10 +3740,40 @@ void futex_exit_release(struct task_stru raw_spin_lock_irq(&tsk->pi_lock); tsk->futex_state = FUTEX_STATE_EXITING; raw_spin_unlock_irq(&tsk->pi_lock); +}
- futex_exec_release(tsk); +static void futex_cleanup_end(struct task_struct *tsk, int state) +{ + /* + * Lockless store. The only side effect is that an observer might + * take another loop until it becomes visible. + */ + tsk->futex_state = state; +}
- tsk->futex_state = FUTEX_STATE_DEAD; +void futex_exec_release(struct task_struct *tsk) +{ + /* + * The state handling is done for consistency, but in the case of + * exec() there is no way to prevent futher damage as the PID stays + * the same. But for the unlikely and arguably buggy case that a + * futex is held on exec(), this provides at least as much state + * consistency protection which is possible. + */ + futex_cleanup_begin(tsk); + futex_cleanup(tsk); + /* + * Reset the state to FUTEX_STATE_OK. The task is alive and about + * exec a new binary. + */ + futex_cleanup_end(tsk, FUTEX_STATE_OK); +} + +void futex_exit_release(struct task_struct *tsk) +{ + futex_cleanup_begin(tsk); + futex_cleanup(tsk); + futex_cleanup_end(tsk, FUTEX_STATE_DEAD); }
long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout,
From: Thomas Gleixner tglx@linutronix.de
commit 3f186d974826847a07bc7964d79ec4eded475ad9 upstream.
The mutex will be used in subsequent changes to replace the busy looping of a waiter when the futex owner is currently executing the exit cleanup to prevent a potential live lock.
Signed-off-by: Thomas Gleixner tglx@linutronix.de Reviewed-by: Ingo Molnar mingo@kernel.org Acked-by: Peter Zijlstra (Intel) peterz@infradead.org Link: https://lkml.kernel.org/r/20191106224556.845798895@linutronix.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- include/linux/futex.h | 1 + include/linux/sched.h | 1 + kernel/futex.c | 16 ++++++++++++++++ 3 files changed, 18 insertions(+)
--- a/include/linux/futex.h +++ b/include/linux/futex.h @@ -68,6 +68,7 @@ static inline void futex_init_task(struc INIT_LIST_HEAD(&tsk->pi_state_list); tsk->pi_state_cache = NULL; tsk->futex_state = FUTEX_STATE_OK; + mutex_init(&tsk->futex_exit_mutex); }
void futex_exit_recursive(struct task_struct *tsk); --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -959,6 +959,7 @@ struct task_struct { #endif struct list_head pi_state_list; struct futex_pi_state *pi_state_cache; + struct mutex futex_exit_mutex; unsigned int futex_state; #endif #ifdef CONFIG_PERF_EVENTS --- a/kernel/futex.c +++ b/kernel/futex.c @@ -3721,12 +3721,23 @@ static void futex_cleanup(struct task_st */ void futex_exit_recursive(struct task_struct *tsk) { + /* If the state is FUTEX_STATE_EXITING then futex_exit_mutex is held */ + if (tsk->futex_state == FUTEX_STATE_EXITING) + mutex_unlock(&tsk->futex_exit_mutex); tsk->futex_state = FUTEX_STATE_DEAD; }
static void futex_cleanup_begin(struct task_struct *tsk) { /* + * Prevent various race issues against a concurrent incoming waiter + * including live locks by forcing the waiter to block on + * tsk->futex_exit_mutex when it observes FUTEX_STATE_EXITING in + * attach_to_pi_owner(). + */ + mutex_lock(&tsk->futex_exit_mutex); + + /* * Switch the state to FUTEX_STATE_EXITING under tsk->pi_lock. * * This ensures that all subsequent checks of tsk->futex_state in @@ -3749,6 +3760,11 @@ static void futex_cleanup_end(struct tas * take another loop until it becomes visible. */ tsk->futex_state = state; + /* + * Drop the exit protection. This unblocks waiters which observed + * FUTEX_STATE_EXITING to reevaluate the state. + */ + mutex_unlock(&tsk->futex_exit_mutex); }
void futex_exec_release(struct task_struct *tsk)
From: Thomas Gleixner tglx@linutronix.de
commit ac31c7ff8624409ba3c4901df9237a616c187a5d upstream.
attach_to_pi_owner() returns -EAGAIN for various cases:
- Owner task is exiting - Futex value has changed
The caller drops the held locks (hash bucket, mmap_sem) and retries the operation. In case of the owner task exiting this can result in a live lock.
As a preparatory step for seperating those cases, provide a distinct return value (EBUSY) for the owner exiting case.
No functional change.
Signed-off-by: Thomas Gleixner tglx@linutronix.de Reviewed-by: Ingo Molnar mingo@kernel.org Acked-by: Peter Zijlstra (Intel) peterz@infradead.org Link: https://lkml.kernel.org/r/20191106224556.935606117@linutronix.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- kernel/futex.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
--- a/kernel/futex.c +++ b/kernel/futex.c @@ -1182,11 +1182,11 @@ static int handle_exit_race(u32 __user * u32 uval2;
/* - * If the futex exit state is not yet FUTEX_STATE_DEAD, wait - * for it to finish. + * If the futex exit state is not yet FUTEX_STATE_DEAD, tell the + * caller that the alleged owner is busy. */ if (tsk && tsk->futex_state != FUTEX_STATE_DEAD) - return -EAGAIN; + return -EBUSY;
/* * Reread the user space value to handle the following situation: @@ -2093,12 +2093,13 @@ retry_private: if (!ret) goto retry; goto out; + case -EBUSY: case -EAGAIN: /* * Two reasons for this: - * - Owner is exiting and we just wait for the + * - EBUSY: Owner is exiting and we just wait for the * exit to complete. - * - The user space value changed. + * - EAGAIN: The user space value changed. */ double_unlock_hb(hb1, hb2); hb_waiters_dec(hb2); @@ -2859,12 +2860,13 @@ retry_private: goto out_unlock_put_key; case -EFAULT: goto uaddr_faulted; + case -EBUSY: case -EAGAIN: /* * Two reasons for this: - * - Task is exiting and we just wait for the + * - EBUSY: Task is exiting and we just wait for the * exit to complete. - * - The user space value changed. + * - EAGAIN: The user space value changed. */ queue_unlock(hb); put_futex_key(&q.key);
From: Thomas Gleixner tglx@linutronix.de
commit 3ef240eaff36b8119ac9e2ea17cbf41179c930ba upstream.
Oleg provided the following test case:
int main(void) { struct sched_param sp = {};
sp.sched_priority = 2; assert(sched_setscheduler(0, SCHED_FIFO, &sp) == 0);
int lock = vfork(); if (!lock) { sp.sched_priority = 1; assert(sched_setscheduler(0, SCHED_FIFO, &sp) == 0); _exit(0); }
syscall(__NR_futex, &lock, FUTEX_LOCK_PI, 0,0,0); return 0; }
This creates an unkillable RT process spinning in futex_lock_pi() on a UP machine or if the process is affine to a single CPU. The reason is:
parent child
set FIFO prio 2
vfork() -> set FIFO prio 1 implies wait_for_child() sched_setscheduler(...) exit() do_exit() .... mm_release() tsk->futex_state = FUTEX_STATE_EXITING; exit_futex(); (NOOP in this case) complete() --> wakes parent sys_futex() loop infinite because tsk->futex_state == FUTEX_STATE_EXITING
The same problem can happen just by regular preemption as well:
task holds futex ... do_exit() tsk->futex_state = FUTEX_STATE_EXITING;
--> preemption (unrelated wakeup of some other higher prio task, e.g. timer)
switch_to(other_task)
return to user sys_futex() loop infinite as above
Just for the fun of it the futex exit cleanup could trigger the wakeup itself before the task sets its futex state to DEAD.
To cure this, the handling of the exiting owner is changed so:
- A refcount is held on the task
- The task pointer is stored in a caller visible location
- The caller drops all locks (hash bucket, mmap_sem) and blocks on task::futex_exit_mutex. When the mutex is acquired then the exiting task has completed the cleanup and the state is consistent and can be reevaluated.
This is not a pretty solution, but there is no choice other than returning an error code to user space, which would break the state consistency guarantee and open another can of problems including regressions.
For stable backports the preparatory commits ac31c7ff8624 .. ba31c1a48538 are required as well, but for anything older than 5.3.y the backports are going to be provided when this hits mainline as the other dependencies for those kernels are definitely not stable material.
Fixes: 778e9a9c3e71 ("pi-futex: fix exit races and locking problems") Reported-by: Oleg Nesterov oleg@redhat.com Signed-off-by: Thomas Gleixner tglx@linutronix.de Reviewed-by: Ingo Molnar mingo@kernel.org Acked-by: Peter Zijlstra (Intel) peterz@infradead.org Cc: Stable Team stable@vger.kernel.org Link: https://lkml.kernel.org/r/20191106224557.041676471@linutronix.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- kernel/futex.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 91 insertions(+), 15 deletions(-)
--- a/kernel/futex.c +++ b/kernel/futex.c @@ -1176,6 +1176,36 @@ out_error: return ret; }
+/** + * wait_for_owner_exiting - Block until the owner has exited + * @exiting: Pointer to the exiting task + * + * Caller must hold a refcount on @exiting. + */ +static void wait_for_owner_exiting(int ret, struct task_struct *exiting) +{ + if (ret != -EBUSY) { + WARN_ON_ONCE(exiting); + return; + } + + if (WARN_ON_ONCE(ret == -EBUSY && !exiting)) + return; + + mutex_lock(&exiting->futex_exit_mutex); + /* + * No point in doing state checking here. If the waiter got here + * while the task was in exec()->exec_futex_release() then it can + * have any FUTEX_STATE_* value when the waiter has acquired the + * mutex. OK, if running, EXITING or DEAD if it reached exit() + * already. Highly unlikely and not a problem. Just one more round + * through the futex maze. + */ + mutex_unlock(&exiting->futex_exit_mutex); + + put_task_struct(exiting); +} + static int handle_exit_race(u32 __user *uaddr, u32 uval, struct task_struct *tsk) { @@ -1237,7 +1267,8 @@ static int handle_exit_race(u32 __user * * it after doing proper sanity checks. */ static int attach_to_pi_owner(u32 __user *uaddr, u32 uval, union futex_key *key, - struct futex_pi_state **ps) + struct futex_pi_state **ps, + struct task_struct **exiting) { pid_t pid = uval & FUTEX_TID_MASK; struct futex_pi_state *pi_state; @@ -1276,7 +1307,19 @@ static int attach_to_pi_owner(u32 __user int ret = handle_exit_race(uaddr, uval, p);
raw_spin_unlock_irq(&p->pi_lock); - put_task_struct(p); + /* + * If the owner task is between FUTEX_STATE_EXITING and + * FUTEX_STATE_DEAD then store the task pointer and keep + * the reference on the task struct. The calling code will + * drop all locks, wait for the task to reach + * FUTEX_STATE_DEAD and then drop the refcount. This is + * required to prevent a live lock when the current task + * preempted the exiting task between the two states. + */ + if (ret == -EBUSY) + *exiting = p; + else + put_task_struct(p); return ret; }
@@ -1315,7 +1358,8 @@ static int attach_to_pi_owner(u32 __user
static int lookup_pi_state(u32 __user *uaddr, u32 uval, struct futex_hash_bucket *hb, - union futex_key *key, struct futex_pi_state **ps) + union futex_key *key, struct futex_pi_state **ps, + struct task_struct **exiting) { struct futex_q *top_waiter = futex_top_waiter(hb, key);
@@ -1330,7 +1374,7 @@ static int lookup_pi_state(u32 __user *u * We are the first waiter - try to look up the owner based on * @uval and attach to it. */ - return attach_to_pi_owner(uaddr, uval, key, ps); + return attach_to_pi_owner(uaddr, uval, key, ps, exiting); }
static int lock_pi_update_atomic(u32 __user *uaddr, u32 uval, u32 newval) @@ -1358,6 +1402,8 @@ static int lock_pi_update_atomic(u32 __u * lookup * @task: the task to perform the atomic lock work for. This will * be "current" except in the case of requeue pi. + * @exiting: Pointer to store the task pointer of the owner task + * which is in the middle of exiting * @set_waiters: force setting the FUTEX_WAITERS bit (1) or not (0) * * Return: @@ -1366,11 +1412,17 @@ static int lock_pi_update_atomic(u32 __u * - <0 - error * * The hb->lock and futex_key refs shall be held by the caller. + * + * @exiting is only set when the return value is -EBUSY. If so, this holds + * a refcount on the exiting task on return and the caller needs to drop it + * after waiting for the exit to complete. */ static int futex_lock_pi_atomic(u32 __user *uaddr, struct futex_hash_bucket *hb, union futex_key *key, struct futex_pi_state **ps, - struct task_struct *task, int set_waiters) + struct task_struct *task, + struct task_struct **exiting, + int set_waiters) { u32 uval, newval, vpid = task_pid_vnr(task); struct futex_q *top_waiter; @@ -1440,7 +1492,7 @@ static int futex_lock_pi_atomic(u32 __us * attach to the owner. If that fails, no harm done, we only * set the FUTEX_WAITERS bit in the user space variable. */ - return attach_to_pi_owner(uaddr, newval, key, ps); + return attach_to_pi_owner(uaddr, newval, key, ps, exiting); }
/** @@ -1859,6 +1911,8 @@ void requeue_pi_wake_futex(struct futex_ * @key1: the from futex key * @key2: the to futex key * @ps: address to store the pi_state pointer + * @exiting: Pointer to store the task pointer of the owner task + * which is in the middle of exiting * @set_waiters: force setting the FUTEX_WAITERS bit (1) or not (0) * * Try and get the lock on behalf of the top waiter if we can do it atomically. @@ -1866,16 +1920,20 @@ void requeue_pi_wake_futex(struct futex_ * then direct futex_lock_pi_atomic() to force setting the FUTEX_WAITERS bit. * hb1 and hb2 must be held by the caller. * + * @exiting is only set when the return value is -EBUSY. If so, this holds + * a refcount on the exiting task on return and the caller needs to drop it + * after waiting for the exit to complete. + * * Return: * - 0 - failed to acquire the lock atomically; * - >0 - acquired the lock, return value is vpid of the top_waiter * - <0 - error */ -static int futex_proxy_trylock_atomic(u32 __user *pifutex, - struct futex_hash_bucket *hb1, - struct futex_hash_bucket *hb2, - union futex_key *key1, union futex_key *key2, - struct futex_pi_state **ps, int set_waiters) +static int +futex_proxy_trylock_atomic(u32 __user *pifutex, struct futex_hash_bucket *hb1, + struct futex_hash_bucket *hb2, union futex_key *key1, + union futex_key *key2, struct futex_pi_state **ps, + struct task_struct **exiting, int set_waiters) { struct futex_q *top_waiter = NULL; u32 curval; @@ -1912,7 +1970,7 @@ static int futex_proxy_trylock_atomic(u3 */ vpid = task_pid_vnr(top_waiter->task); ret = futex_lock_pi_atomic(pifutex, hb2, key2, ps, top_waiter->task, - set_waiters); + exiting, set_waiters); if (ret == 1) { requeue_pi_wake_futex(top_waiter, key2, hb2); return vpid; @@ -2041,6 +2099,8 @@ retry_private: }
if (requeue_pi && (task_count - nr_wake < nr_requeue)) { + struct task_struct *exiting = NULL; + /* * Attempt to acquire uaddr2 and wake the top waiter. If we * intend to requeue waiters, force setting the FUTEX_WAITERS @@ -2048,7 +2108,8 @@ retry_private: * faults rather in the requeue loop below. */ ret = futex_proxy_trylock_atomic(uaddr2, hb1, hb2, &key1, - &key2, &pi_state, nr_requeue); + &key2, &pi_state, + &exiting, nr_requeue);
/* * At this point the top_waiter has either taken uaddr2 or is @@ -2075,7 +2136,8 @@ retry_private: * If that call succeeds then we have pi_state and an * initial refcount on it. */ - ret = lookup_pi_state(uaddr2, ret, hb2, &key2, &pi_state); + ret = lookup_pi_state(uaddr2, ret, hb2, &key2, + &pi_state, &exiting); }
switch (ret) { @@ -2105,6 +2167,12 @@ retry_private: hb_waiters_dec(hb2); put_futex_key(&key2); put_futex_key(&key1); + /* + * Handle the case where the owner is in the middle of + * exiting. Wait for the exit to complete otherwise + * this task might loop forever, aka. live lock. + */ + wait_for_owner_exiting(ret, exiting); cond_resched(); goto retry; default: @@ -2820,6 +2888,7 @@ static int futex_lock_pi(u32 __user *uad { struct hrtimer_sleeper timeout, *to = NULL; struct futex_pi_state *pi_state = NULL; + struct task_struct *exiting = NULL; struct rt_mutex_waiter rt_waiter; struct futex_hash_bucket *hb; struct futex_q q = futex_q_init; @@ -2847,7 +2916,8 @@ retry: retry_private: hb = queue_lock(&q);
- ret = futex_lock_pi_atomic(uaddr, hb, &q.key, &q.pi_state, current, 0); + ret = futex_lock_pi_atomic(uaddr, hb, &q.key, &q.pi_state, current, + &exiting, 0); if (unlikely(ret)) { /* * Atomic work succeeded and we got the lock, @@ -2870,6 +2940,12 @@ retry_private: */ queue_unlock(hb); put_futex_key(&q.key); + /* + * Handle the case where the owner is in the middle of + * exiting. Wait for the exit to complete otherwise + * this task might loop forever, aka. live lock. + */ + wait_for_owner_exiting(ret, exiting); cond_resched(); goto retry; default:
From: Candle Sun candle.sun@unisoc.com
commit 1cb0d2aee26335d0bccf29100c7bed00ebece851 upstream.
Upstream commit 58e75155009c ("HID: core: move Usage Page concatenation to Main item") adds support for Usage Page item after Usage ID items (such as keyboards manufactured by Primax).
Usage Page concatenation in Main item works well for following report descriptor patterns:
USAGE_PAGE (Keyboard) 05 07 USAGE_MINIMUM (Keyboard LeftControl) 19 E0 USAGE_MAXIMUM (Keyboard Right GUI) 29 E7 LOGICAL_MINIMUM (0) 15 00 LOGICAL_MAXIMUM (1) 25 01 REPORT_SIZE (1) 75 01 REPORT_COUNT (8) 95 08 INPUT (Data,Var,Abs) 81 02
-------------
USAGE_MINIMUM (Keyboard LeftControl) 19 E0 USAGE_MAXIMUM (Keyboard Right GUI) 29 E7 LOGICAL_MINIMUM (0) 15 00 LOGICAL_MAXIMUM (1) 25 01 REPORT_SIZE (1) 75 01 REPORT_COUNT (8) 95 08 USAGE_PAGE (Keyboard) 05 07 INPUT (Data,Var,Abs) 81 02
But it makes the parser act wrong for the following report descriptor pattern(such as some Gamepads):
USAGE_PAGE (Button) 05 09 USAGE (Button 1) 09 01 USAGE (Button 2) 09 02 USAGE (Button 4) 09 04 USAGE (Button 5) 09 05 USAGE (Button 7) 09 07 USAGE (Button 8) 09 08 USAGE (Button 14) 09 0E USAGE (Button 15) 09 0F USAGE (Button 13) 09 0D USAGE_PAGE (Consumer Devices) 05 0C USAGE (Back) 0a 24 02 USAGE (HomePage) 0a 23 02 LOGICAL_MINIMUM (0) 15 00 LOGICAL_MAXIMUM (1) 25 01 REPORT_SIZE (1) 75 01 REPORT_COUNT (11) 95 0B INPUT (Data,Var,Abs) 81 02
With Usage Page concatenation in Main item, parser recognizes all the 11 Usages as consumer keys, it is not the HID device's real intention.
This patch checks whether Usage Page is really defined after Usage ID items by comparing usage page using status.
Usage Page concatenation on currently defined Usage Page will always do in local parsing when Usage ID items encountered.
When Main item is parsing, concatenation will do again with last defined Usage Page if this page has not been used in the previous usages concatenation.
Signed-off-by: Candle Sun candle.sun@unisoc.com Signed-off-by: Nianfu Bai nianfu.bai@unisoc.com Cc: Benjamin Tissoires benjamin.tissoires@redhat.com Signed-off-by: Jiri Kosina jkosina@suse.cz Cc: Siarhei Vishniakou svv@google.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/hid/hid-core.c | 51 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 45 insertions(+), 6 deletions(-)
--- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -196,6 +196,18 @@ static unsigned hid_lookup_collection(st }
/* + * Concatenate usage which defines 16 bits or less with the + * currently defined usage page to form a 32 bit usage + */ + +static void complete_usage(struct hid_parser *parser, unsigned int index) +{ + parser->local.usage[index] &= 0xFFFF; + parser->local.usage[index] |= + (parser->global.usage_page & 0xFFFF) << 16; +} + +/* * Add a usage to the temporary parser table. */
@@ -206,6 +218,14 @@ static int hid_add_usage(struct hid_pars return -1; } parser->local.usage[parser->local.usage_index] = usage; + + /* + * If Usage item only includes usage id, concatenate it with + * currently defined usage page + */ + if (size <= 2) + complete_usage(parser, parser->local.usage_index); + parser->local.usage_size[parser->local.usage_index] = size; parser->local.collection_index[parser->local.usage_index] = parser->collection_stack_ptr ? @@ -522,13 +542,32 @@ static int hid_parser_local(struct hid_p * usage value." */
-static void hid_concatenate_usage_page(struct hid_parser *parser) +static void hid_concatenate_last_usage_page(struct hid_parser *parser) { int i; + unsigned int usage_page; + unsigned int current_page; + + if (!parser->local.usage_index) + return;
- for (i = 0; i < parser->local.usage_index; i++) - if (parser->local.usage_size[i] <= 2) - parser->local.usage[i] += parser->global.usage_page << 16; + usage_page = parser->global.usage_page; + + /* + * Concatenate usage page again only if last declared Usage Page + * has not been already used in previous usages concatenation + */ + for (i = parser->local.usage_index - 1; i >= 0; i--) { + if (parser->local.usage_size[i] > 2) + /* Ignore extended usages */ + continue; + + current_page = parser->local.usage[i] >> 16; + if (current_page == usage_page) + break; + + complete_usage(parser, i); + } }
/* @@ -540,7 +579,7 @@ static int hid_parser_main(struct hid_pa __u32 data; int ret;
- hid_concatenate_usage_page(parser); + hid_concatenate_last_usage_page(parser);
data = item_udata(item);
@@ -751,7 +790,7 @@ static int hid_scan_main(struct hid_pars __u32 data; int i;
- hid_concatenate_usage_page(parser); + hid_concatenate_last_usage_page(parser);
data = item_udata(item);
From: Lionel Debieve lionel.debieve@st.com
commit 0acabecebc912b3ba06289e4ef40476acc499a37 upstream.
Correct condition for the second hmac loop. Key must be only set in the first loop. Initial condition was wrong, HMAC_KEY flag was not properly checked.
Signed-off-by: Lionel Debieve lionel.debieve@st.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/crypto/stm32/stm32-hash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/crypto/stm32/stm32-hash.c +++ b/drivers/crypto/stm32/stm32-hash.c @@ -361,7 +361,7 @@ static int stm32_hash_xmit_cpu(struct st return -ETIMEDOUT;
if ((hdev->flags & HASH_FLAGS_HMAC) && - (hdev->flags & ~HASH_FLAGS_HMAC_KEY)) { + (!(hdev->flags & HASH_FLAGS_HMAC_KEY))) { hdev->flags |= HASH_FLAGS_HMAC_KEY; stm32_hash_write_key(hdev); if (stm32_hash_wait_busy(hdev))
From: Hugues Fruchet hugues.fruchet@st.com
commit b3ce6f6ff3c260ee53b0f2236e5fd950d46957da upstream.
Avoid call of dmaengine_terminate_all() between dmaengine_prep_slave_single() and dmaengine_submit() by locking the whole DMA submission sequence.
Signed-off-by: Hugues Fruchet hugues.fruchet@st.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+samsung@kernel.org Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/media/platform/stm32/stm32-dcmi.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
--- a/drivers/media/platform/stm32/stm32-dcmi.c +++ b/drivers/media/platform/stm32/stm32-dcmi.c @@ -161,6 +161,9 @@ struct stm32_dcmi { u32 misr; int errors_count; int buffers_count; + + /* Ensure DMA operations atomicity */ + struct mutex dma_lock; };
static inline struct stm32_dcmi *notifier_to_dcmi(struct v4l2_async_notifier *n) @@ -291,6 +294,13 @@ static int dcmi_start_dma(struct stm32_d return ret; }
+ /* + * Avoid call of dmaengine_terminate_all() between + * dmaengine_prep_slave_single() and dmaengine_submit() + * by locking the whole DMA submission sequence + */ + mutex_lock(&dcmi->dma_lock); + /* Prepare a DMA transaction */ desc = dmaengine_prep_slave_single(dcmi->dma_chan, buf->paddr, buf->size, @@ -298,6 +308,7 @@ static int dcmi_start_dma(struct stm32_d if (!desc) { dev_err(dcmi->dev, "%s: DMA dmaengine_prep_slave_single failed for buffer size %zu\n", __func__, buf->size); + mutex_unlock(&dcmi->dma_lock); return -EINVAL; }
@@ -309,9 +320,12 @@ static int dcmi_start_dma(struct stm32_d dcmi->dma_cookie = dmaengine_submit(desc); if (dma_submit_error(dcmi->dma_cookie)) { dev_err(dcmi->dev, "%s: DMA submission failed\n", __func__); + mutex_unlock(&dcmi->dma_lock); return -ENXIO; }
+ mutex_unlock(&dcmi->dma_lock); + dma_async_issue_pending(dcmi->dma_chan);
return 0; @@ -690,7 +704,9 @@ static void dcmi_stop_streaming(struct v spin_unlock_irq(&dcmi->irqlock);
/* Stop all pending DMA operations */ + mutex_lock(&dcmi->dma_lock); dmaengine_terminate_all(dcmi->dma_chan); + mutex_unlock(&dcmi->dma_lock);
clk_disable(dcmi->mclk);
@@ -1662,6 +1678,7 @@ static int dcmi_probe(struct platform_de
spin_lock_init(&dcmi->irqlock); mutex_init(&dcmi->lock); + mutex_init(&dcmi->dma_lock); init_completion(&dcmi->complete); INIT_LIST_HEAD(&dcmi->buffers);
From: Lionel Debieve lionel.debieve@st.com
commit af0d4442dd6813de6e77309063beb064fa8e89ae upstream.
No remove function implemented yet in the driver. Without remove function, the pm_runtime implementation complains when removing and probing again the driver.
Signed-off-by: Lionel Debieve lionel.debieve@st.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/char/hw_random/stm32-rng.c | 8 ++++++++ 1 file changed, 8 insertions(+)
--- a/drivers/char/hw_random/stm32-rng.c +++ b/drivers/char/hw_random/stm32-rng.c @@ -166,6 +166,13 @@ static int stm32_rng_probe(struct platfo return devm_hwrng_register(dev, &priv->rng); }
+static int stm32_rng_remove(struct platform_device *ofdev) +{ + pm_runtime_disable(&ofdev->dev); + + return 0; +} + #ifdef CONFIG_PM static int stm32_rng_runtime_suspend(struct device *dev) { @@ -202,6 +209,7 @@ static struct platform_driver stm32_rng_ .of_match_table = stm32_rng_match, }, .probe = stm32_rng_probe, + .remove = stm32_rng_remove, };
module_platform_driver(stm32_rng_driver);
From: Fabien Dessenne fabien.dessenne@st.com
commit 6899b4f7c99c72968e58e502f96084f74f6e5e86 upstream.
Fix null pointer issue if resource_size is called with no ioresource.
Signed-off-by: Ludovic Barre ludovic.barre@st.com Signed-off-by: Fabien Dessenne fabien.dessenne@st.com Signed-off-by: Jassi Brar jaswinder.singh@linaro.org Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/mailbox/mailbox-test.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
--- a/drivers/mailbox/mailbox-test.c +++ b/drivers/mailbox/mailbox-test.c @@ -363,22 +363,24 @@ static int mbox_test_probe(struct platfo
/* It's okay for MMIO to be NULL */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - size = resource_size(res); tdev->tx_mmio = devm_ioremap_resource(&pdev->dev, res); - if (PTR_ERR(tdev->tx_mmio) == -EBUSY) + if (PTR_ERR(tdev->tx_mmio) == -EBUSY) { /* if reserved area in SRAM, try just ioremap */ + size = resource_size(res); tdev->tx_mmio = devm_ioremap(&pdev->dev, res->start, size); - else if (IS_ERR(tdev->tx_mmio)) + } else if (IS_ERR(tdev->tx_mmio)) { tdev->tx_mmio = NULL; + }
/* If specified, second reg entry is Rx MMIO */ res = platform_get_resource(pdev, IORESOURCE_MEM, 1); - size = resource_size(res); tdev->rx_mmio = devm_ioremap_resource(&pdev->dev, res); - if (PTR_ERR(tdev->rx_mmio) == -EBUSY) + if (PTR_ERR(tdev->rx_mmio) == -EBUSY) { + size = resource_size(res); tdev->rx_mmio = devm_ioremap(&pdev->dev, res->start, size); - else if (IS_ERR(tdev->rx_mmio)) + } else if (IS_ERR(tdev->rx_mmio)) { tdev->rx_mmio = tdev->tx_mmio; + }
tdev->tx_channel = mbox_test_request_channel(pdev, "tx"); tdev->rx_channel = mbox_test_request_channel(pdev, "rx");
From: Alexandre Torgue alexandre.torgue@st.com
commit cd8c9b5a49576bf28990237715bc2cb2210ac80a upstream.
configs is allocated by pinconf_generic_parse_dt_config(), pinctrl_utils_add_map_configs() duplicates configs so it can and has to be freed to prevent memory leaks.
Signed-off-by: Alexandre Torgue alexandre.torgue@st.com Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/pinctrl/stm32/pinctrl-stm32.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-)
--- a/drivers/pinctrl/stm32/pinctrl-stm32.c +++ b/drivers/pinctrl/stm32/pinctrl-stm32.c @@ -403,7 +403,7 @@ static int stm32_pctrl_dt_subnode_to_map unsigned int num_configs; bool has_config = 0; unsigned reserve = 0; - int num_pins, num_funcs, maps_per_pin, i, err; + int num_pins, num_funcs, maps_per_pin, i, err = 0;
pctl = pinctrl_dev_get_drvdata(pctldev);
@@ -430,41 +430,45 @@ static int stm32_pctrl_dt_subnode_to_map if (has_config && num_pins >= 1) maps_per_pin++;
- if (!num_pins || !maps_per_pin) - return -EINVAL; + if (!num_pins || !maps_per_pin) { + err = -EINVAL; + goto exit; + }
reserve = num_pins * maps_per_pin;
err = pinctrl_utils_reserve_map(pctldev, map, reserved_maps, num_maps, reserve); if (err) - return err; + goto exit;
for (i = 0; i < num_pins; i++) { err = of_property_read_u32_index(node, "pinmux", i, &pinfunc); if (err) - return err; + goto exit;
pin = STM32_GET_PIN_NO(pinfunc); func = STM32_GET_PIN_FUNC(pinfunc);
if (!stm32_pctrl_is_function_valid(pctl, pin, func)) { dev_err(pctl->dev, "invalid function.\n"); - return -EINVAL; + err = -EINVAL; + goto exit; }
grp = stm32_pctrl_find_group_by_pin(pctl, pin); if (!grp) { dev_err(pctl->dev, "unable to match pin %d to group\n", pin); - return -EINVAL; + err = -EINVAL; + goto exit; }
err = stm32_pctrl_dt_node_to_map_func(pctl, pin, func, grp, map, reserved_maps, num_maps); if (err) - return err; + goto exit;
if (has_config) { err = pinctrl_utils_add_map_configs(pctldev, map, @@ -472,11 +476,13 @@ static int stm32_pctrl_dt_subnode_to_map configs, num_configs, PIN_MAP_TYPE_CONFIGS_GROUP); if (err) - return err; + goto exit; } }
- return 0; +exit: + kfree(configs); + return err; }
static int stm32_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
From: Olivier Moysan olivier.moysan@st.com
commit 1ac2bd16448997d9ec01922423486e1e85535eda upstream.
DMA configuration is not balanced on start/stop. Move DMA configuration to trigger callback.
Signed-off-by: Olivier Moysan olivier.moysan@st.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- sound/soc/stm/stm32_i2s.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
--- a/sound/soc/stm/stm32_i2s.c +++ b/sound/soc/stm/stm32_i2s.c @@ -488,7 +488,7 @@ static int stm32_i2s_configure(struct sn { struct stm32_i2s_data *i2s = snd_soc_dai_get_drvdata(cpu_dai); int format = params_width(params); - u32 cfgr, cfgr_mask, cfg1, cfg1_mask; + u32 cfgr, cfgr_mask, cfg1; unsigned int fthlv; int ret;
@@ -529,15 +529,11 @@ static int stm32_i2s_configure(struct sn if (ret < 0) return ret;
- cfg1 = I2S_CFG1_RXDMAEN | I2S_CFG1_TXDMAEN; - cfg1_mask = cfg1; - fthlv = STM32_I2S_FIFO_SIZE * I2S_FIFO_TH_ONE_QUARTER / 4; - cfg1 |= I2S_CFG1_FTHVL_SET(fthlv - 1); - cfg1_mask |= I2S_CFG1_FTHVL_MASK; + cfg1 = I2S_CFG1_FTHVL_SET(fthlv - 1);
return regmap_update_bits(i2s->regmap, STM32_I2S_CFG1_REG, - cfg1_mask, cfg1); + I2S_CFG1_FTHVL_MASK, cfg1); }
static int stm32_i2s_startup(struct snd_pcm_substream *substream, @@ -589,6 +585,10 @@ static int stm32_i2s_trigger(struct snd_ /* Enable i2s */ dev_dbg(cpu_dai->dev, "start I2S\n");
+ cfg1_mask = I2S_CFG1_RXDMAEN | I2S_CFG1_TXDMAEN; + regmap_update_bits(i2s->regmap, STM32_I2S_CFG1_REG, + cfg1_mask, cfg1_mask); + ret = regmap_update_bits(i2s->regmap, STM32_I2S_CR1_REG, I2S_CR1_SPE, I2S_CR1_SPE); if (ret < 0) {
From: Olivier Moysan olivier.moysan@st.com
commit 0c4c68d6fa1bae74d450e50823c24fcc3cd0b171 upstream.
I2S supports 16 bits data in 32 channel length. However the expected driver behavior, is to set channel length to 16 bits when data format is 16 bits.
Signed-off-by: Olivier Moysan olivier.moysan@st.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- sound/soc/stm/stm32_i2s.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/sound/soc/stm/stm32_i2s.c +++ b/sound/soc/stm/stm32_i2s.c @@ -501,7 +501,7 @@ static int stm32_i2s_configure(struct sn switch (format) { case 16: cfgr = I2S_CGFR_DATLEN_SET(I2S_I2SMOD_DATLEN_16); - cfgr_mask = I2S_CGFR_DATLEN_MASK; + cfgr_mask = I2S_CGFR_DATLEN_MASK | I2S_CGFR_CHLEN; break; case 32: cfgr = I2S_CGFR_DATLEN_SET(I2S_I2SMOD_DATLEN_32) |
From: Olivier Moysan olivier.moysan@st.com
commit 8ba3c5215d69c09f5c39783ff3b78347769822ad upstream.
Because of regmap cache, interrupts may not be cleared as expected. Declare IFCR register as write only and make writings to IFCR register unconditional.
Signed-off-by: Olivier Moysan olivier.moysan@st.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- sound/soc/stm/stm32_i2s.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
--- a/sound/soc/stm/stm32_i2s.c +++ b/sound/soc/stm/stm32_i2s.c @@ -246,8 +246,8 @@ static irqreturn_t stm32_i2s_isr(int irq return IRQ_NONE; }
- regmap_update_bits(i2s->regmap, STM32_I2S_IFCR_REG, - I2S_IFCR_MASK, flags); + regmap_write_bits(i2s->regmap, STM32_I2S_IFCR_REG, + I2S_IFCR_MASK, flags);
if (flags & I2S_SR_OVR) { dev_dbg(&pdev->dev, "Overrun\n"); @@ -276,7 +276,6 @@ static bool stm32_i2s_readable_reg(struc case STM32_I2S_CFG2_REG: case STM32_I2S_IER_REG: case STM32_I2S_SR_REG: - case STM32_I2S_IFCR_REG: case STM32_I2S_TXDR_REG: case STM32_I2S_RXDR_REG: case STM32_I2S_CGFR_REG: @@ -547,8 +546,8 @@ static int stm32_i2s_startup(struct snd_ i2s->refcount++; spin_unlock(&i2s->lock_fd);
- return regmap_update_bits(i2s->regmap, STM32_I2S_IFCR_REG, - I2S_IFCR_MASK, I2S_IFCR_MASK); + return regmap_write_bits(i2s->regmap, STM32_I2S_IFCR_REG, + I2S_IFCR_MASK, I2S_IFCR_MASK); }
static int stm32_i2s_hw_params(struct snd_pcm_substream *substream, @@ -603,8 +602,8 @@ static int stm32_i2s_trigger(struct snd_ return ret; }
- regmap_update_bits(i2s->regmap, STM32_I2S_IFCR_REG, - I2S_IFCR_MASK, I2S_IFCR_MASK); + regmap_write_bits(i2s->regmap, STM32_I2S_IFCR_REG, + I2S_IFCR_MASK, I2S_IFCR_MASK);
if (playback_flg) { ier = I2S_IER_UDRIE;
From: Hans de Goede hdegoede@redhat.com
commit 16245db1489cd9aa579506f64afeeeb13d825a93 upstream.
The HP WMI calls may take up to 128 bytes of data as input, and the AML methods implementing the WMI calls, declare a couple of fields for accessing input in different sizes, specifycally the HWMC method contains:
CreateField (Arg1, 0x80, 0x0400, D128)
Even though we do not use any of the WMI command-types which need a buffer of this size, the APCI interpreter still tries to create it as it is declared in generoc code at the top of the HWMC method which runs before the code looks at which command-type is requested.
This results in many of these errors on many different HP laptop models:
[ 14.459261] ACPI Error: Field [D128] at 1152 exceeds Buffer [NULL] size 160 (bits) (20170303/dsopcode-236) [ 14.459268] ACPI Error: Method parse/execution failed [\HWMC] (Node ffff8edcc61507f8), AE_AML_BUFFER_LIMIT (20170303/psparse-543) [ 14.459279] ACPI Error: Method parse/execution failed [_SB.WMID.WMAA] (Node ffff8edcc61523c0), AE_AML_BUFFER_LIMIT (20170303/psparse-543)
This commit increases the size of the data element of the bios_args struct to 128 bytes fixing these errors.
Cc: stable@vger.kernel.org BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=197007 BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=201981 BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1520703 Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/platform/x86/hp-wmi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
--- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c @@ -78,7 +78,7 @@ struct bios_args { u32 command; u32 commandtype; u32 datasize; - u32 data; + u8 data[128]; };
enum hp_wmi_commandtype { @@ -229,7 +229,7 @@ static int hp_wmi_perform_query(int quer .command = command, .commandtype = query, .datasize = insize, - .data = 0, + .data = { 0 }, }; struct acpi_buffer input = { sizeof(struct bios_args), &args }; struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; @@ -241,7 +241,7 @@ static int hp_wmi_perform_query(int quer
if (WARN_ON(insize > sizeof(args.data))) return -EINVAL; - memcpy(&args.data, buffer, insize); + memcpy(&args.data[0], buffer, insize);
wmi_evaluate_method(HPWMI_BIOS_GUID, 0, mid, &input, &output);
From: Hans de Goede hdegoede@redhat.com
commit f3e4f3fc8ee9729c4b1b27a478c68b713df53c0c upstream.
The AML code implementing the WMI methods creates a variable length field to hold the input data we pass like this:
CreateDWordField (Arg1, 0x0C, DSZI) Local5 = DSZI /* \HWMC.DSZI */ CreateField (Arg1, 0x80, (Local5 * 0x08), DAIN)
If we pass 0 as bios_args.datasize argument then (Local5 * 0x08) is 0 which results in these errors:
[ 71.973305] ACPI BIOS Error (bug): Attempt to CreateField of length zero (20190816/dsopcode-133) [ 71.973332] ACPI Error: Aborting method \HWMC due to previous error (AE_AML_OPERAND_VALUE) (20190816/psparse-529) [ 71.973413] ACPI Error: Aborting method _SB.WMID.WMAA due to previous error (AE_AML_OPERAND_VALUE) (20190816/psparse-529)
And in our HPWMI_WIRELESS2_QUERY calls always failing. for read commands like HPWMI_WIRELESS2_QUERY the DSZI value is not used / checked, except for read commands where extra input is needed to specify exactly what to read.
So for HPWMI_WIRELESS2_QUERY we can safely pass the size of the expected output as insize to hp_wmi_perform_query(), as we are already doing for all other HPWMI_READ commands we send. Doing so fixes these errors.
Cc: stable@vger.kernel.org BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=197007 BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=201981 BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1520703 Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/platform/x86/hp-wmi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c @@ -393,7 +393,7 @@ static int hp_wmi_rfkill2_refresh(void) int err, i;
err = hp_wmi_perform_query(HPWMI_WIRELESS2_QUERY, HPWMI_READ, &state, - 0, sizeof(state)); + sizeof(state), sizeof(state)); if (err) return err;
@@ -790,7 +790,7 @@ static int __init hp_wmi_rfkill2_setup(s int err, i;
err = hp_wmi_perform_query(HPWMI_WIRELESS2_QUERY, HPWMI_READ, &state, - 0, sizeof(state)); + sizeof(state), sizeof(state)); if (err) return err < 0 ? err : -EINVAL;
From: Chuhong Yuan hslester96@gmail.com
commit a31eda65ba210741b598044d045480494d0ed52a upstream.
pm_runtime_put_autosuspend in probe will call runtime suspend to disable clks automatically if CONFIG_PM is defined. (If CONFIG_PM is not defined, its implementation will be empty, then runtime suspend will not be called.)
Therefore, we can call pm_runtime_get_sync to runtime resume it first to enable clks, which matches the runtime suspend. (Only when CONFIG_PM is defined, otherwise pm_runtime_get_sync will also be empty, then runtime resume will not be called.)
Then it is fine to disable clks without causing clock count mis-match.
Fixes: c43eab3eddb4 ("net: fec: add missed clk_disable_unprepare in remove") Signed-off-by: Chuhong Yuan hslester96@gmail.com Acked-by: Fugang Duan fugang.duan@nxp.com Signed-off-by: David S. Miller davem@davemloft.net Cc: Nobuhiro Iwamatsu nobuhiro1.iwamatsu@toshiba.co.jp Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/net/ethernet/freescale/fec_main.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
--- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -3565,6 +3565,11 @@ fec_drv_remove(struct platform_device *p struct net_device *ndev = platform_get_drvdata(pdev); struct fec_enet_private *fep = netdev_priv(ndev); struct device_node *np = pdev->dev.of_node; + int ret; + + ret = pm_runtime_get_sync(&pdev->dev); + if (ret < 0) + return ret;
cancel_work_sync(&fep->tx_timeout_work); fec_ptp_stop(pdev); @@ -3572,15 +3577,17 @@ fec_drv_remove(struct platform_device *p fec_enet_mii_remove(fep); if (fep->reg_phy) regulator_disable(fep->reg_phy); - pm_runtime_put(&pdev->dev); - pm_runtime_disable(&pdev->dev); - clk_disable_unprepare(fep->clk_ahb); - clk_disable_unprepare(fep->clk_ipg); + if (of_phy_is_fixed_link(np)) of_phy_deregister_fixed_link(np); of_node_put(fep->phy_node); free_netdev(ndev);
+ clk_disable_unprepare(fep->clk_ahb); + clk_disable_unprepare(fep->clk_ipg); + pm_runtime_put_noidle(&pdev->dev); + pm_runtime_disable(&pdev->dev); + return 0; }
On Wed, 4 Dec 2019 at 23:33, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 4.14.158 release. There are 209 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, 06 Dec 2019 17:50:10 +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/v4.x/stable-review/patch-4.14.158-rc... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.14.y and the diffstat can be found below.
thanks,
greg k-h
Results from Linaro’s test farm. No regressions on arm64, arm, x86_64, and i386.
Summary ------------------------------------------------------------------------
kernel: 4.14.158-rc1 git repo: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git git branch: linux-4.14.y git commit: ce267d7b1d71f10d722fd3c8a729ccca53830262 git describe: v4.14.157-210-gce267d7b1d71 Test details: https://qa-reports.linaro.org/lkft/linux-stable-rc-4.14-oe/build/v4.14.157-2...
No regressions (compared to build v4.14.157)
No fixes (compared to build v4.14.157)
Ran 24134 total tests in the following environments and test suites.
Environments -------------- - dragonboard-410c - arm64 - hi6220-hikey - arm64 - i386 - juno-r2 - arm64 - qemu_arm - qemu_arm64 - qemu_i386 - qemu_x86_64 - x15 - arm - x86_64
Test Suites ----------- * build * install-android-platform-tools-r2600 * kselftest * libhugetlbfs * linux-log-parser * ltp-containers-tests * ltp-cve-tests * ltp-dio-tests * ltp-fs-tests * ltp-io-tests * spectre-meltdown-checker-test * ltp-commands-tests * ltp-hugetlb-tests * ltp-ipc-tests * ltp-math-tests * ltp-mm-tests * ltp-cap_bounds-tests * ltp-cpuhotplug-tests * ltp-fcntl-locktests-tests * ltp-filecaps-tests * ltp-fs_bind-tests * ltp-fs_perms_simple-tests * ltp-fsx-tests * ltp-nptl-tests * ltp-open-posix-tests * ltp-pty-tests * ltp-sched-tests * ltp-securebits-tests * ltp-syscalls-tests * network-basic-tests * perf * v4l2-compliance * kvm-unit-tests * kselftest-vsyscall-mode-native * kselftest-vsyscall-mode-none * ssuite
On Thu, Dec 05, 2019 at 10:47:43AM +0530, Naresh Kamboju wrote:
On Wed, 4 Dec 2019 at 23:33, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 4.14.158 release. There are 209 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, 06 Dec 2019 17:50:10 +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/v4.x/stable-review/patch-4.14.158-rc... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.14.y and the diffstat can be found below.
thanks,
greg k-h
Results from Linaro’s test farm. No regressions on arm64, arm, x86_64, and i386.
Thanks for testing all of these and letting me know.
greg k-h
On 04/12/2019 17:53, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 4.14.158 release. There are 209 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, 06 Dec 2019 17:50:10 +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/v4.x/stable-review/patch-4.14.158-rc... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.14.y and the diffstat can be found below.
thanks,
greg k-h
All tests are passing for Tegra ...
Test results for stable-v4.14: 8 builds: 8 pass, 0 fail 16 boots: 16 pass, 0 fail 24 tests: 24 pass, 0 fail
Linux version: 4.14.158-rc1-gce267d7b1d71 Boards tested: tegra124-jetson-tk1, tegra20-ventana, tegra210-p2371-2180, tegra30-cardhu-a04
Cheers Jon
On Thu, Dec 05, 2019 at 06:59:55AM +0000, Jon Hunter wrote:
On 04/12/2019 17:53, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 4.14.158 release. There are 209 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, 06 Dec 2019 17:50:10 +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/v4.x/stable-review/patch-4.14.158-rc... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.14.y and the diffstat can be found below.
thanks,
greg k-h
All tests are passing for Tegra ...
Test results for stable-v4.14: 8 builds: 8 pass, 0 fail 16 boots: 16 pass, 0 fail 24 tests: 24 pass, 0 fail
Linux version: 4.14.158-rc1-gce267d7b1d71 Boards tested: tegra124-jetson-tk1, tegra20-ventana, tegra210-p2371-2180, tegra30-cardhu-a04
Thanks for testing all of these and letting me know.
greg k-h
On 12/4/19 9:53 AM, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 4.14.158 release. There are 209 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, 06 Dec 2019 17:50:10 +0000. Anything received after that time might be too late.
Build results: total: 172 pass: 172 fail: 0 Qemu test results: total: 372 pass: 372 fail: 0
Guenter
On Thu, Dec 05, 2019 at 06:14:08AM -0800, Guenter Roeck wrote:
On 12/4/19 9:53 AM, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 4.14.158 release. There are 209 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, 06 Dec 2019 17:50:10 +0000. Anything received after that time might be too late.
Build results: total: 172 pass: 172 fail: 0 Qemu test results: total: 372 pass: 372 fail: 0
Great, thanks for testing and letting me know.
greg k-h
On 12/4/19 10:53 AM, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 4.14.158 release. There are 209 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, 06 Dec 2019 17:50:10 +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/v4.x/stable-review/patch-4.14.158-rc... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.14.y and the diffstat can be found below.
thanks,
greg k-h
Starting with Linux 4.14.157, 4.9.204, and 4.4.204 stables stopped booting on my system. It can't find the root disk. No config changes in between.
I have been bisecting 4.14 and 4.9 with no luck so far. I updated to Ubuntu 19.10 in between.
The only other thing I see is CONFIG_GCC_VERSION which is supported starting 4.18. I don't this boot failing issue on 4.19 + up. I am also chasing any links between this config and scripts and tools that generate the initramfs.
I am still debugging ... Serious for me since I can no longer test older stables. :(
thanks, -- Shuah
On Fri, Dec 06, 2019 at 08:24:36AM -0700, shuah wrote:
On 12/4/19 10:53 AM, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 4.14.158 release. There are 209 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, 06 Dec 2019 17:50:10 +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/v4.x/stable-review/patch-4.14.158-rc... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.14.y and the diffstat can be found below.
thanks,
greg k-h
Starting with Linux 4.14.157, 4.9.204, and 4.4.204 stables stopped booting on my system. It can't find the root disk. No config changes in between.
I have been bisecting 4.14 and 4.9 with no luck so far. I updated to Ubuntu 19.10 in between.
The only other thing I see is CONFIG_GCC_VERSION which is supported starting 4.18. I don't this boot failing issue on 4.19 + up. I am also chasing any links between this config and scripts and tools that generate the initramfs.
Did you also upgrade your version of gcc? I know I build those older kernels with the latest version of gcc for build tests, but I do not boot them. I think everyone who still uses them uses older versions of gcc.
I am still debugging ... Serious for me since I can no longer test older stables. :(
Ick, not good, sorry. If you find anything bisecting, please let me know.
thanks,
greg k-h
On 12/6/19 8:28 AM, Greg Kroah-Hartman wrote:
On Fri, Dec 06, 2019 at 08:24:36AM -0700, shuah wrote:
On 12/4/19 10:53 AM, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 4.14.158 release. There are 209 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, 06 Dec 2019 17:50:10 +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/v4.x/stable-review/patch-4.14.158-rc... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.14.y and the diffstat can be found below.
thanks,
greg k-h
Starting with Linux 4.14.157, 4.9.204, and 4.4.204 stables stopped booting on my system. It can't find the root disk. No config changes in between.
I have been bisecting 4.14 and 4.9 with no luck so far. I updated to Ubuntu 19.10 in between.
The only other thing I see is CONFIG_GCC_VERSION which is supported starting 4.18. I don't this boot failing issue on 4.19 + up. I am also chasing any links between this config and scripts and tools that generate the initramfs.
Did you also upgrade your version of gcc? I know I build those older kernels with the latest version of gcc for build tests, but I do not boot them. I think everyone who still uses them uses older versions of gcc.
Yes. gcc version changed. That has been my strong suspect since I started poking around the CONFIG_GCC_VERSION.
I will try to force it to use older gcc and see if things improve.
I am still debugging ... Serious for me since I can no longer test older stables. :(
Ick, not good, sorry. If you find anything bisecting, please let me know.
Will do.
thanks, -- Shuah
On 12/6/19 7:35 AM, shuah wrote:
On 12/6/19 8:28 AM, Greg Kroah-Hartman wrote:
On Fri, Dec 06, 2019 at 08:24:36AM -0700, shuah wrote:
On 12/4/19 10:53 AM, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 4.14.158 release. There are 209 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, 06 Dec 2019 17:50:10 +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/v4.x/stable-review/patch-4.14.158-rc... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.14.y and the diffstat can be found below.
thanks,
greg k-h
Starting with Linux 4.14.157, 4.9.204, and 4.4.204 stables stopped booting on my system. It can't find the root disk. No config changes in between.
I have been bisecting 4.14 and 4.9 with no luck so far. I updated to Ubuntu 19.10 in between.
The only other thing I see is CONFIG_GCC_VERSION which is supported starting 4.18. I don't this boot failing issue on 4.19 + up. I am also chasing any links between this config and scripts and tools that generate the initramfs.
Did you also upgrade your version of gcc? I know I build those older kernels with the latest version of gcc for build tests, but I do not boot them. I think everyone who still uses them uses older versions of gcc.
Yes. gcc version changed. That has been my strong suspect since I started poking around the CONFIG_GCC_VERSION.
What version of gcc are you using ? I currently use gcc 8.3.0 for all qemu boot tests (except for 3.16 which doesn't support it, or at least it didn't when I last checked), and have not observed any problems.
Thanks, Guenter
On 12/6/19 9:10 AM, Guenter Roeck wrote:
On 12/6/19 7:35 AM, shuah wrote:
On 12/6/19 8:28 AM, Greg Kroah-Hartman wrote:
On Fri, Dec 06, 2019 at 08:24:36AM -0700, shuah wrote:
On 12/4/19 10:53 AM, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 4.14.158 release. There are 209 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, 06 Dec 2019 17:50:10 +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/v4.x/stable-review/patch-4.14.158-rc...
or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.14.y and the diffstat can be found below.
thanks,
greg k-h
Starting with Linux 4.14.157, 4.9.204, and 4.4.204 stables stopped booting on my system. It can't find the root disk. No config changes in between.
I have been bisecting 4.14 and 4.9 with no luck so far. I updated to Ubuntu 19.10 in between.
The only other thing I see is CONFIG_GCC_VERSION which is supported starting 4.18. I don't this boot failing issue on 4.19 + up. I am also chasing any links between this config and scripts and tools that generate the initramfs.
Did you also upgrade your version of gcc? I know I build those older kernels with the latest version of gcc for build tests, but I do not boot them. I think everyone who still uses them uses older versions of gcc.
Yes. gcc version changed. That has been my strong suspect since I started poking around the CONFIG_GCC_VERSION.
What version of gcc are you using ? I currently use gcc 8.3.0 for all qemu boot tests (except for 3.16 which doesn't support it, or at least it didn't when I last checked), and have not observed any problems.
With the upgrade gcc version went from 8.3.0 to 9.2.1
Interestingly enough all the older 4.14, 4.9, and 4.4 kernel I have on the system boot just fine. It fails when build newer rcs with new gcc, boot fails.
I would really like to understand it just in case something in our kbuild scrips is the issue.
thanks, -- Shuah
On 12/6/19 8:23 AM, shuah wrote:
On 12/6/19 9:10 AM, Guenter Roeck wrote:
On 12/6/19 7:35 AM, shuah wrote:
On 12/6/19 8:28 AM, Greg Kroah-Hartman wrote:
On Fri, Dec 06, 2019 at 08:24:36AM -0700, shuah wrote:
On 12/4/19 10:53 AM, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 4.14.158 release. There are 209 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, 06 Dec 2019 17:50:10 +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/v4.x/stable-review/patch-4.14.158-rc... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.14.y and the diffstat can be found below.
thanks,
greg k-h
Starting with Linux 4.14.157, 4.9.204, and 4.4.204 stables stopped booting on my system. It can't find the root disk. No config changes in between.
I have been bisecting 4.14 and 4.9 with no luck so far. I updated to Ubuntu 19.10 in between.
The only other thing I see is CONFIG_GCC_VERSION which is supported starting 4.18. I don't this boot failing issue on 4.19 + up. I am also chasing any links between this config and scripts and tools that generate the initramfs.
Did you also upgrade your version of gcc? I know I build those older kernels with the latest version of gcc for build tests, but I do not boot them. I think everyone who still uses them uses older versions of gcc.
Yes. gcc version changed. That has been my strong suspect since I started poking around the CONFIG_GCC_VERSION.
What version of gcc are you using ? I currently use gcc 8.3.0 for all qemu boot tests (except for 3.16 which doesn't support it, or at least it didn't when I last checked), and have not observed any problems.
With the upgrade gcc version went from 8.3.0 to 9.2.1
Interestingly enough all the older 4.14, 4.9, and 4.4 kernel I have on the system boot just fine. It fails when build newer rcs with new gcc, boot fails.
I would really like to understand it just in case something in our kbuild scrips is the issue.
v4.4.206 boots for me into qemu when compiled with gcc 9.2.0 (9.2.1 does not appear to be an official release). So at least it isn't that simple. Let me know if I can test anything else.
Thanks, Guenter
On 12/6/19 9:56 AM, Guenter Roeck wrote:
On 12/6/19 8:23 AM, shuah wrote:
On 12/6/19 9:10 AM, Guenter Roeck wrote:
On 12/6/19 7:35 AM, shuah wrote:
On 12/6/19 8:28 AM, Greg Kroah-Hartman wrote:
On Fri, Dec 06, 2019 at 08:24:36AM -0700, shuah wrote:
On 12/4/19 10:53 AM, Greg Kroah-Hartman wrote: > This is the start of the stable review cycle for the 4.14.158 > release. > There are 209 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, 06 Dec 2019 17:50:10 +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/v4.x/stable-review/patch-4.14.158-rc... > > or in the git tree and branch at: > git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git > linux-4.14.y > and the diffstat can be found below. > > thanks, > > greg k-h >
Starting with Linux 4.14.157, 4.9.204, and 4.4.204 stables stopped booting on my system. It can't find the root disk. No config changes in between.
I have been bisecting 4.14 and 4.9 with no luck so far. I updated to Ubuntu 19.10 in between.
The only other thing I see is CONFIG_GCC_VERSION which is supported starting 4.18. I don't this boot failing issue on 4.19 + up. I am also chasing any links between this config and scripts and tools that generate the initramfs.
Did you also upgrade your version of gcc? I know I build those older kernels with the latest version of gcc for build tests, but I do not boot them. I think everyone who still uses them uses older versions of gcc.
Yes. gcc version changed. That has been my strong suspect since I started poking around the CONFIG_GCC_VERSION.
What version of gcc are you using ? I currently use gcc 8.3.0 for all qemu boot tests (except for 3.16 which doesn't support it, or at least it didn't when I last checked), and have not observed any problems.
With the upgrade gcc version went from 8.3.0 to 9.2.1
Interestingly enough all the older 4.14, 4.9, and 4.4 kernel I have on the system boot just fine. It fails when build newer rcs with new gcc, boot fails.
I would really like to understand it just in case something in our kbuild scrips is the issue.
v4.4.206 boots for me into qemu when compiled with gcc 9.2.0 (9.2.1 does not appear to be an official release). So at least it isn't that simple. Let me know if I can test anything else.
Update on this. I managed to boot 4.14.158 by installing stripping modules INSTALL_MOD_STRIP=1. I also disabled KASAN.
The above doesn't work on Linux 4.9.206 or Linux 4.4.206. Investigating still.
thanks, -- Shuah
linux-stable-mirror@lists.linaro.org