This is the start of the stable review cycle for the 5.2.5 release. There are 215 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed 31 Jul 2019 07:05:01 PM UTC. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.2.5-rc1.g... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.2.y and the diffstat can be found below.
thanks,
greg k-h
------------- Pseudo-Shortlog of commits:
Greg Kroah-Hartman gregkh@linuxfoundation.org Linux 5.2.5-rc1
Jens Axboe axboe@kernel.dk io_uring: don't use iov_iter_advance() for fixed buffers
Zhengyuan Liu liuzhengyuan@kylinos.cn io_uring: fix counter inc/dec mismatch in async_list
Jens Axboe axboe@kernel.dk io_uring: ensure ->list is initialized for poll commands
Zhengyuan Liu liuzhengyuan@kylinos.cn io_uring: add a memory barrier before atomic_read
Linus Torvalds torvalds@linux-foundation.org access: avoid the RCU grace period for the temporary subjective credentials
Chris Wilson chris@chris-wilson.co.uk drm/i915: Make the semaphore saturation mask global
Arnd Bergmann arnd@arndb.de structleak: disable STRUCTLEAK_BYREF in combination with KASAN_STACK
Dan Williams dan.j.williams@intel.com libnvdimm/bus: Stop holding nvdimm_bus_list_mutex over __nd_ioctl()
Dan Williams dan.j.williams@intel.com libnvdimm/region: Register badblocks before namespaces
Dan Williams dan.j.williams@intel.com libnvdimm/bus: Prevent duplicate device_unregister() calls
Dan Williams dan.j.williams@intel.com drivers/base: Introduce kill_device()
Joerg Roedel jroedel@suse.de iommu/iova: Fix compilation error with !CONFIG_IOMMU_IOVA
Chris Wilson chris@chris-wilson.co.uk iommu/iova: Remove stale cached32_node
Dmitry Safonov dima@arista.com iommu/vt-d: Don't queue_iova() if there is no flush queue
Zhengyuan Liu liuzhengyuan@kylinos.cn io_uring: fix the sequence comparison in io_sequence_defer
Suraj Jitindar Singh sjitindarsingh@gmail.com powerpc/pmu: Set pmcregs_in_use in paca when running as LPAR
Michael Neuling mikey@neuling.org powerpc/tm: Fix oops on sigreturn on systems without TM
Suraj Jitindar Singh sjitindarsingh@gmail.com powerpc/mm: Limit rma_size to 1TB when running without HV mode
Gautham R. Shenoy ego@linux.vnet.ibm.com powerpc/xive: Fix loop exit-condition in xive_find_target_in_mask()
Shawn Anastasio shawn@anastas.io powerpc/dma: Fix invalid DMA mmap behavior
Hui Wang hui.wang@canonical.com ALSA: hda - Add a conexant codec entry to let mute led work
Takashi Iwai tiwai@suse.de ALSA: hda - Fix intermittent CORB/RIRB stall on Intel chips
Takashi Iwai tiwai@suse.de ALSA: pcm: Fix refcount_inc() on zero usage
Kai-Heng Feng kai.heng.feng@canonical.com ALSA: line6: Fix wrong altsetting for LINE6_PODHD500_1
Ding Xiang dingxiang@cmss.chinamobile.com ALSA: ac97: Fix double free of ac97_codec_device
Sébastien Szymanski sebastien.szymanski@armadeus.com drm/panel: Add support for Armadeus ST0700 Adapt
Kefeng Wang wangkefeng.wang@huawei.com hpet: Fix division by zero in hpet_time_div()
Arseny Solokha asolokha@kb.kras.ru eeprom: make older eeprom drivers select NVMEM_SYSFS
Alexander Usyskin alexander.usyskin@intel.com mei: me: add mule creek canyon (EHL) device ids
YueHaibing yuehaibing@huawei.com fpga-manager: altera-ps-spi: Fix build error
Hridya Valsaraju hridya@google.com binder: prevent transactions to context manager from its own process.
Martijn Coenen maco@android.com binder: Set end of SG buffer area properly.
Eiichi Tsukata devel@etsukata.com x86/stacktrace: Prevent access_ok() warnings in arch_stack_walk_user()
Zhenzhong Duan zhenzhong.duan@oracle.com x86/speculation/mds: Apply more accurate check on hypervisor platform
Hans de Goede hdegoede@redhat.com x86/sysfb_efi: Add quirks for some devices with swapped width and height
Ondrej Mosnacek omosnace@redhat.com selinux: check sidtab limit before adding a new entry
Qu Wenruo wqu@suse.com btrfs: inode: Don't compress if NODATASUM or NODATACOW set
Hans Verkuil hverkuil@xs4all.nl media: videodev2.h: change V4L2_PIX_FMT_BGRA444 define: fourcc was already in use
Cédric Le Goater clg@kaod.org KVM: PPC: Book3S HV: XIVE: fix rollback when kvmppc_xive_create fails
Suraj Jitindar Singh sjitindarsingh@gmail.com KVM: PPC: Book3S HV: Save and restore guest visible PSSCR bits on pseries
Suraj Jitindar Singh sjitindarsingh@gmail.com KVM: PPC: Book3S HV: Always save guest pmu for guest capable of nesting
Wanpeng Li wanpengli@tencent.com KVM: X86: Fix fpu state crash in kvm guest
Lucas Stach l.stach@pengutronix.de usb: usb251xb: Reallow swap-dx-lanes to apply to the upstream port
Lucas Stach l.stach@pengutronix.de Revert "usb: usb251xb: Add US port lanes inversion property"
Lucas Stach l.stach@pengutronix.de Revert "usb: usb251xb: Add US lanes inversion dts-bindings"
Ryan Kennedy ryan5544@gmail.com usb: pci-quirks: Correct AMD PLL quirk detection
Phong Tran tranmanphong@gmail.com usb: wusbcore: fix unbalanced get/put cluster_id
Yoshihiro Shimoda yoshihiro.shimoda.uh@renesas.com usb-storage: Add a limitation for blk_queue_max_hw_sectors()
Mathias Nyman mathias.nyman@linux.intel.com xhci: Fix crash if scatter gather is used with Immediate Data Transfer (IDT).
Arnd Bergmann arnd@arndb.de locking/lockdep: Hide unused 'class' variable
Huang Ying ying.huang@intel.com mm, swap: fix race between swapoff and some swap operations
Konstantin Khlebnikov khlebnikov@yandex-team.ru mm: use down_read_killable for locking mmap_sem in access_remote_vm
Yuyang Du duyuyang@gmail.com locking/lockdep: Fix lock used or unused stats error
Konstantin Khlebnikov khlebnikov@yandex-team.ru proc: use down_read_killable mmap_sem for /proc/pid/maps
Arnd Bergmann arnd@arndb.de cxgb4: reduce kernel stack usage in cudbg_collect_mem_region()
Konstantin Khlebnikov khlebnikov@yandex-team.ru proc: use down_read_killable mmap_sem for /proc/pid/map_files
Konstantin Khlebnikov khlebnikov@yandex-team.ru proc: use down_read_killable mmap_sem for /proc/pid/clear_refs
Konstantin Khlebnikov khlebnikov@yandex-team.ru proc: use down_read_killable mmap_sem for /proc/pid/pagemap
Konstantin Khlebnikov khlebnikov@yandex-team.ru proc: use down_read_killable mmap_sem for /proc/pid/smaps_rollup
Jean-Philippe Brucker jean-philippe.brucker@arm.com mm/mmu_notifier: use hlist_add_head_rcu()
Shakeel Butt shakeelb@google.com memcg, fsnotify: no oom-kill for remote memcg charging
Andy Lutomirski luto@kernel.org mm/gup.c: remove some BUG_ONs from get_gate_page()
Guenter Roeck linux@roeck-us.net mm/gup.c: mark undo_dev_pagemap as __maybe_unused
Huang Ying ying.huang@intel.com mm/mincore.c: fix race between swapoff and mincore
Christoph Hellwig hch@lst.de 9p: pass the correct prototype to read_cache_page
Dmitry Vyukov dvyukov@google.com mm/kmemleak.c: fix check for softirq context
Sam Ravnborg sam@ravnborg.org sh: prevent warnings when using iounmap
Minwoo Im minwoo.im.dev@gmail.com nvme: fix NULL deref for fabrics options
Wenwen Wang wenwen@cs.uga.edu block/bio-integrity: fix a memory leak bug
YueHaibing yuehaibing@huawei.com platform/x86: Fix PCENGINES_APU2 Kconfig warning
Oliver O'Halloran oohall@gmail.com powerpc/eeh: Handle hugepages in ioremap space
David Windsor dwindsor@redhat.com dlm: check if workqueues are NULL before flushing/destroying
morten petersen morten_bp@live.dk mailbox: handle failed named mailbox channel request
Ocean Chen oceanchen@google.com f2fs: avoid out-of-range memory access
Heng Xiao heng.xiao@unisoc.com f2fs: fix to avoid long latency during umount
Gerd Rausch gerd.rausch@oracle.com rds: Accept peer connection reject messages due to incompatible version
Josef Bacik josef@toxicpanda.com block: init flush rq ref count to 1
Masahiro Yamada yamada.masahiro@socionext.com powerpc/boot: add {get, put}_unaligned_be32 to xz_config.h
Michael Ellerman mpe@ellerman.id.au powerpc/irq: Don't WARN continuously in arch_local_irq_restore()
Mikhail Skorzhinskii mskorzhinskiy@solarflare.com nvme-tcp: set the STABLE_WRITES flag when data digests are enabled
Jackie Liu liuyun01@kylinos.cn io_uring: fix io_sq_thread_stop running in front of io_sq_thread
Mikhail Skorzhinskii mskorzhinskiy@solarflare.com nvme-tcp: don't use sendpage for SLAB pages
Christoph Hellwig hch@lst.de nvme-pci: limit max_hw_sectors based on the DMA max mapping size
Alan Mikhak alan.mikhak@sifive.com nvme-pci: check for NULL return from pci_alloc_p2pmem()
Dag Moxnes dag.moxnes@oracle.com RDMA/core: Fix race when resolving IP address
Leo Yan leo.yan@linaro.org perf intel-bts: Fix potential NULL pointer dereference found by the smatch tool
YueHaibing yuehaibing@huawei.com PCI: dwc: pci-dra7xx: Fix compilation when !CONFIG_GPIOLIB
Konstantin Taranov konstantin.taranov@inf.ethz.ch RDMA/rxe: Fill in wc byte_len with IB_WC_RECV_RDMA_WITH_IMM
Leo Yan leo.yan@linaro.org perf hists browser: Fix potential NULL pointer dereference found by the smatch tool
Leo Yan leo.yan@linaro.org perf annotate: Fix dereferencing freed memory found by the smatch tool
Leo Yan leo.yan@linaro.org perf map: Fix potential NULL pointer dereference found by smatch tool
Leo Yan leo.yan@linaro.org perf session: Fix potential NULL pointer dereference found by the smatch tool
Leo Yan leo.yan@linaro.org perf trace: Fix potential NULL pointer dereference found by the smatch tool
Leo Yan leo.yan@linaro.org perf top: Fix potential NULL pointer dereference detected by the smatch tool
Mathieu Desnoyers mathieu.desnoyers@efficios.com rseq/selftests: Fix Thumb mode build failure on arm32
Leo Yan leo.yan@linaro.org perf stat: Fix use-after-freed pointer detected by the smatch tool
Numfor Mbiziwo-Tiapo nums@google.com perf test mmap-thread-lookup: Initialize variable to suppress memory sanitizer warning
Hou Zhiqiang Zhiqiang.Hou@nxp.com PCI: mobiveil: Use the 1st inbound window for MEM inbound transactions
Hou Zhiqiang Zhiqiang.Hou@nxp.com PCI: mobiveil: Initialize Primary/Secondary/Subordinate bus numbers
Vasily Gorbik gor@linux.ibm.com kallsyms: exclude kasan local symbols on s390
Hou Zhiqiang Zhiqiang.Hou@nxp.com PCI: mobiveil: Fix the Class Code field
Hou Zhiqiang Zhiqiang.Hou@nxp.com PCI: mobiveil: Fix PCI base address in MEM/IO outbound windows
Sean Christopherson sean.j.christopherson@intel.com KVM: nVMX: Stash L1's CR3 in vmcs01.GUEST_CR3 on nested entry w/o EPT
James Morse james.morse@arm.com arm64: assembler: Switch ESB-instruction with a vanilla nop if !ARM64_HAS_RAS
Valentine Fatiev valentinef@mellanox.com IB/ipoib: Add child to parent list only if device initialized
Aneesh Kumar K.V aneesh.kumar@linux.ibm.com powerpc/mm: Handle page table allocation failures
Parav Pandit parav@mellanox.com IB/mlx5: Fixed reporting counters on 2nd port for Dual port RoCE
Geert Uytterhoeven geert+renesas@glider.be serial: sh-sci: Fix TX DMA buffer flushing and workqueue races
Geert Uytterhoeven geert+renesas@glider.be serial: sh-sci: Terminate TX DMA during buffer flushing
Liu, Changcheng changcheng.liu@intel.com RDMA/i40iw: Set queue pair state when being queried
Masahiro Yamada yamada.masahiro@socionext.com powerpc/mm: mark more tlb functions as __always_inline
Christian Lamparter chunkeey@gmail.com powerpc/4xx/uic: clear pending interrupt after irq type/pol change
Mathieu Malaterre malat@debian.org powerpc: silence a -Wcast-function-type warning in dawr_write_file_bool
Sahitya Tummala stummala@codeaurora.org f2fs: fix is_idle() check for discard type
Johannes Berg johannes.berg@intel.com um: Silence lockdep complaint about mmap_sem
Ira Weiny ira.weiny@intel.com mm/swap: fix release_pages() when releasing devmap pages
Axel Lin axel.lin@ingics.com mfd: hi655x-pmic: Fix missing return value check for devm_regmap_init_mmio_clk
Arnd Bergmann arnd@arndb.de mfd: arizona: Fix undefined behavior
Robert Hancock hancock@sedsystems.ca mfd: core: Set fwnode for created devices
Daniel Gomez dagmcr@gmail.com mfd: madera: Add missing of table registration
Gwendal Grignou gwendal@chromium.org mfd: cros_ec: Register cros_ec_lid_angle driver when presented
Naveen N. Rao naveen.n.rao@linux.vnet.ibm.com recordmcount: Fix spurious mcount entries on powerpc
Masahiro Yamada yamada.masahiro@socionext.com fixdep: check return value of printf() and putchar()
Nathan Lynch nathanl@linux.ibm.com powerpc/rtas: retry when cpu offline races with suspend/migration
Naveen N. Rao naveen.n.rao@linux.vnet.ibm.com powerpc/xmon: Fix disabling tracing while in xmon
Qian Cai cai@lca.pw powerpc/cacheflush: fix variable set but not used
Brian Masney masneyb@onstation.org dt-bindings: backlight: lm3630a: correct schema validation
Bastien Nocera hadess@hadess.net iio: iio-utils: Fix possible incorrect mask calculation
Bharat Kumar Gogada bharat.kumar.gogada@xilinx.com PCI: xilinx-nwl: Fix Multi MSI data programming
Neil Armstrong narmstrong@baylibre.com phy: meson-g12a-usb3-pcie: disable locking for cr_regmap
Will Deacon will@kernel.org genksyms: Teach parser about 128-bit built-in types
Nathan Chancellor natechancellor@gmail.com kbuild: Add -Werror=unknown-warning-option to CLANG_FLAGS
Nathan Huckleberry nhuck@google.com net/ipv4: fib_trie: Avoid cryptic ternary expressions
Fabrice Gasnier fabrice.gasnier@st.com i2c: stm32f7: fix the get_irq error cases
Marek Vasut marek.vasut+renesas@gmail.com PCI: sysfs: Ignore lockdep for remove attribute
Yoshihiro Shimoda yoshihiro.shimoda.uh@renesas.com phy: renesas: rcar-gen3-usb2: fix imbalance powered flag
Stefan Roese sr@denx.de serial: mctrl_gpio: Check if GPIO property exisits before requesting it
Sean Paul seanpaul@chromium.org drm/msm: Depopulate platform on probe failure
Alexey Kardashevskiy aik@ozlabs.ru powerpc/pci/of: Fix OF flags parsing for 64bit BARs
Jordan Crouse jcrouse@codeaurora.org drm/msm/adreno: Ensure that the zap shader region is big enough
Eugene Korenevsky ekorenevsky@gmail.com kvm: vmx: segment limit check: use access length
Sean Christopherson sean.j.christopherson@intel.com KVM: nVMX: Intercept VMWRITEs to GUEST_{CS,SS}_AR_BYTES
Raul E Rangel rrangel@chromium.org mmc: sdhci: sdhci-pci-o2micro: Check if controller supports 8-bit width
Eugene Korenevsky ekorenevsky@gmail.com kvm: vmx: fix limit checking in get_vmx_mem_address()
Enric Balletbo i Serra enric.balletbo@collabora.com usb: dwc3: Fix core validation in probe, move after clocks are enabled
Andrzej Pietrasiewicz andrzej.p@collabora.com usb: gadget: Zero ffs_io_data
Serge Semin fancer.lancer@gmail.com tty: serial_core: Set port active bit in uart_port_activate
Shubhrajyoti Datta shubhrajyoti.datta@xilinx.com serial: uartps: Use the same dynamic major number for all ports
Sergey Organov sorganov@gmail.com serial: imx: fix locking in set_termios()
Alexandru Ardelean alexandru.ardelean@analog.com iio: adxl372: fix iio_triggered_buffer_{pre,post}enable positions
Yurii Pavlovskyi yurii.pavlovskyi@gmail.com platform/x86: asus-wmi: Increase input buffer size of WMI methods
Douglas Anderson dianders@chromium.org drm/rockchip: Properly adjust to a true clock in adjusted_mode
Florian Fainelli f.fainelli@gmail.com dma-remap: Avoid de-referencing NULL atomic_pool
Nathan Lynch nathanl@linux.ibm.com powerpc/pseries/mobility: prevent cpu hotplug during DT update
Tomi Valkeinen tomi.valkeinen@ti.com drm/bridge: tfp410: fix use of cancel_delayed_work_sync
John Paul Adrian Glaubitz glaubitz@physik.fu-berlin.de sunhv: Fix device naming inconsistency between sunhv_console and sunhv_reg
Hariprasad Kelam hariprasad.kelam@gmail.com drm/amd/display: fix compilation error
Yoshihiro Shimoda yoshihiro.shimoda.uh@renesas.com phy: renesas: rcar-gen2: Fix memory leak at error paths
Samson Tam Samson.Tam@amd.com drm/amd/display: set link->dongle_max_pix_clk to 0 on a disconnect
David Riley davidriley@chromium.org drm/virtio: Add memory barriers for capset cache.
Wesley Chalmers Wesley.Chalmers@amd.com drm/amd/display: Update link rate from DPCD 10
Nicholas Kazlauskas nicholas.kazlauskas@amd.com drm/amd/display: Always allocate initial connector state state
Alan Mikhak alan.mikhak@sifive.com PCI: endpoint: Allocate enough space for fixed size BAR
Rautkoski Kimmo EXT ext-kimmo.rautkoski@vaisala.com serial: 8250: Fix TX interrupt handling condition
Jorge Ramirez-Ortiz jorge.ramirez-ortiz@linaro.org tty: serial: msm_serial: avoid system lockup condition
Kefeng Wang wangkefeng.wang@huawei.com tty/serial: digicolor: Fix digicolor-usart already registered warning
Wang Hai wanghai26@huawei.com memstick: Fix error cleanup path of memstick_init
Sebastian Reichel sebastian.reichel@collabora.com drm/omap: don't check dispc timings for DSI
Jason Gunthorpe jgg@ziepe.ca mm/hmm: fix use after free with struct hmm in the mmu notifiers
Ajay Gupta ajayg@nvidia.com i2c: nvidia-gpu: resume ccgx i2c client
Daniel Vetter daniel.vetter@ffwll.ch drm/vkms: Forward timer right after drm_crtc_handle_vblank
Daniel Vetter daniel.vetter@ffwll.ch drm/crc-debugfs: Also sprinkle irqrestore over early exits
Daniel Vetter daniel.vetter@ffwll.ch drm/crc-debugfs: User irqsafe spinlock in drm_crtc_add_crc_entry
Thierry Reding treding@nvidia.com gpu: host1x: Increase maximum DMA segment size
Daniel Rosenberg drosen@google.com f2fs: Lower threshold for disable_cp_again
Daniel Rosenberg drosen@google.com f2fs: Fix accounting for unusable blocks
Eryk Brol eryk.brol@amd.com drm/amd/display: Increase Backlight Gain Step Size
Krunoslav Kovac Krunoslav.Kovac@amd.com drm/amd/display: CS_TFM_1D only applied post EOTF
Nicholas Kazlauskas nicholas.kazlauskas@amd.com drm/amd/display: Reset planes for color management changes
Jyri Sarha jsarha@ti.com drm/bridge: sii902x: pixel clock unit is 10kHz instead of 1kHz
Tomi Valkeinen tomi.valkeinen@ti.com drm/bridge: tc358767: read display_props in get_modes()
Mao Wenan maowenan@huawei.com staging: kpc2000: report error status to spi core
Alex Williamson alex.williamson@redhat.com PCI: Return error if cannot probe VF
Alan Mikhak alan.mikhak@sifive.com tools: PCI: Fix broken pcitest compilation
Gen Zhang blackgod016574@gmail.com drm/edid: Fix a missing-check bug in drm_load_edid_firmware()
Oak Zeng Oak.Zeng@amd.com drm/amdkfd: Fix sdma queue map issue
Oak Zeng ozeng@amd.com drm/amdkfd: Fix a potential memory leak
Paul Hsieh paul.hsieh@amd.com drm/amd/display: Disable ABM before destroy ABM struct
Tiecheng Zhou Tiecheng.Zhou@amd.com drm/amdgpu/sriov: Need to initialize the HDP_NONSURFACE_BAStE
Chao Yu yuchao0@huawei.com f2fs: fix to avoid deadloop if data_flush is on
Felix Kuehling Felix.Kuehling@amd.com drm/amdgpu: Reserve shared fence for eviction fence
Roman Li Roman.Li@amd.com drm/amd/display: Fill plane attrs only for valid pxl format
Nicholas Kazlauskas nicholas.kazlauskas@amd.com drm/amd/display: Disable cursor when offscreen in negative direction
Sean Paul seanpaul@chromium.org drm/msm/a6xx: Avoid freeing gmu resources multiple times
Anthony Koo anthony.koo@amd.com drm/amd/display: fix multi display seamless boot case
Nicholas Kazlauskas nicholas.kazlauskas@amd.com drm/amd/display: Fill prescale_params->scale for RGB565
Kefeng Wang wangkefeng.wang@huawei.com ipmi_ssif: fix unexpected driver unregister warning
Sean Paul seanpaul@chromium.org drm/msm/a6xx: Check for ERR or NULL before iounmap
Chao Yu yuchao0@huawei.com f2fs: fix to check layout on last valid checkpoint park
Christophe Leroy christophe.leroy@c-s.fr tty: serial: cpm_uart - fix init when SMC is relocated
Wen Yang wen.yang99@zte.com.cn pinctrl: rockchip: fix leaked of_node references
Serge Semin fancer.lancer@gmail.com tty: max310x: Fix invalid baudrate divisors calculator
Thinh Nguyen Thinh.Nguyen@synopsys.com usb: core: hub: Disable hub-initiated U1/U2
Sam Bobroff sbobroff@linux.ibm.com drm/bochs: Fix connector leak during driver unload
Quentin Deslandes quentin.deslandes@itdev.co.uk staging: vt6656: use meaningful error code during buffer allocation
Kefeng Wang wangkefeng.wang@huawei.com ipmi_si: fix unexpected driver unregister warning
Jeremy Sowden jeremy@azazel.net staging: kpc2000: added missing clean-up to probe_core_uio.
Chia-I Wu olvaffe@gmail.com drm/virtio: set seqno for dma-fence
Fabien Dessenne fabien.dessenne@st.com iio: adc: stm32-dfsdm: missing error case during probe
Fabien Dessenne fabien.dessenne@st.com iio: adc: stm32-dfsdm: manage the get_irq error case
Peter Ujfalusi peter.ujfalusi@ti.com drm/panel: simple: Fix panel_simple_dsi_probe
Peter Griffin peter.griffin@linaro.org drm/lima: handle shared irq case for lima_pp_bcast_irq_handler
Arnd Bergmann arnd@arndb.de btrfs: shut up bogus -Wmaybe-uninitialized warning
Anders Roxell anders.roxell@linaro.org media: drivers: media: coda: fix warning same module names
Anders Roxell anders.roxell@linaro.org regulator: 88pm800: fix warning same module names
-------------
Diffstat:
.../display/panel/armadeus,st0700-adapt.txt | 9 ++ .../bindings/leds/backlight/lm3630a-backlight.yaml | 21 ++- Documentation/devicetree/bindings/usb/usb251xb.txt | 6 +- Makefile | 5 +- arch/arm64/include/asm/assembler.h | 4 + arch/powerpc/Kconfig | 1 + arch/powerpc/boot/xz_config.h | 20 +++ arch/powerpc/include/asm/cacheflush.h | 7 +- arch/powerpc/include/asm/pmc.h | 5 +- arch/powerpc/kernel/Makefile | 3 +- arch/powerpc/kernel/dma-common.c | 17 +++ arch/powerpc/kernel/eeh.c | 15 +- arch/powerpc/kernel/hw_breakpoint.c | 7 +- arch/powerpc/kernel/irq.c | 6 +- arch/powerpc/kernel/pci_of_scan.c | 2 + arch/powerpc/kernel/rtas.c | 7 +- arch/powerpc/kernel/signal_32.c | 3 + arch/powerpc/kernel/signal_64.c | 5 + arch/powerpc/kvm/book3s_hv.c | 13 ++ arch/powerpc/kvm/book3s_xive.c | 4 +- arch/powerpc/kvm/book3s_xive_native.c | 4 +- arch/powerpc/mm/book3s64/hash_native.c | 2 +- arch/powerpc/mm/book3s64/hash_utils.c | 9 ++ arch/powerpc/mm/book3s64/radix_tlb.c | 32 ++--- arch/powerpc/mm/hugetlbpage.c | 8 ++ arch/powerpc/platforms/4xx/uic.c | 1 + arch/powerpc/platforms/pseries/mobility.c | 9 ++ arch/powerpc/sysdev/xive/common.c | 7 +- arch/powerpc/xmon/xmon.c | 6 +- arch/sh/include/asm/io.h | 6 +- arch/um/include/asm/mmu_context.h | 2 +- arch/x86/include/uapi/asm/vmx.h | 1 - arch/x86/kernel/cpu/bugs.c | 2 +- arch/x86/kernel/stacktrace.c | 2 +- arch/x86/kernel/sysfb_efi.c | 46 ++++++ arch/x86/kvm/vmx/nested.c | 87 +++++++----- arch/x86/kvm/vmx/nested.h | 2 +- arch/x86/kvm/vmx/vmcs_shadow_fields.h | 4 +- arch/x86/kvm/vmx/vmx.c | 3 +- arch/x86/kvm/x86.c | 9 +- block/bio-integrity.c | 8 +- block/blk-core.c | 1 + drivers/android/binder.c | 5 +- drivers/base/core.c | 27 ++-- drivers/char/hpet.c | 3 +- drivers/char/ipmi/ipmi_si_platform.c | 6 +- drivers/char/ipmi/ipmi_ssif.c | 5 +- drivers/fpga/Kconfig | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 4 + drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 3 + .../gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 21 +-- drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c | 5 +- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 30 ++-- drivers/gpu/drm/amd/display/dc/core/dc.c | 14 +- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 6 + drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 9 +- drivers/gpu/drm/amd/display/dc/dce/dce_abm.c | 2 + drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c | 3 + drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.h | 2 + .../amd/display/dc/dce110/dce110_hw_sequencer.c | 3 + .../drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 1 + .../drm/amd/display/modules/color/color_gamma.c | 3 +- drivers/gpu/drm/bochs/bochs_drv.c | 2 + drivers/gpu/drm/bridge/sii902x.c | 5 +- drivers/gpu/drm/bridge/tc358767.c | 7 + drivers/gpu/drm/bridge/ti-tfp410.c | 3 +- drivers/gpu/drm/drm_debugfs_crc.c | 9 +- drivers/gpu/drm/drm_edid_load.c | 2 + drivers/gpu/drm/i915/i915_request.c | 4 +- drivers/gpu/drm/i915/intel_context.c | 1 - drivers/gpu/drm/i915/intel_context_types.h | 2 - drivers/gpu/drm/i915/intel_engine_cs.c | 1 + drivers/gpu/drm/i915/intel_engine_types.h | 2 + drivers/gpu/drm/lima/lima_pp.c | 8 +- drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 20 ++- drivers/gpu/drm/msm/adreno/a6xx_gmu.h | 1 + drivers/gpu/drm/msm/adreno/adreno_gpu.c | 8 +- drivers/gpu/drm/msm/msm_drv.c | 14 +- drivers/gpu/drm/omapdrm/omap_crtc.c | 18 ++- drivers/gpu/drm/panel/panel-simple.c | 38 ++++- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 3 +- drivers/gpu/drm/virtio/virtgpu_drv.h | 1 - drivers/gpu/drm/virtio/virtgpu_fence.c | 17 ++- drivers/gpu/drm/virtio/virtgpu_ioctl.c | 3 + drivers/gpu/drm/virtio/virtgpu_vq.c | 2 + drivers/gpu/drm/vkms/vkms_crtc.c | 22 ++- drivers/gpu/host1x/bus.c | 3 + drivers/i2c/busses/i2c-nvidia-gpu.c | 14 +- drivers/i2c/busses/i2c-stm32f7.c | 26 ++-- drivers/iio/accel/adxl372.c | 27 ++-- drivers/iio/adc/stm32-dfsdm-adc.c | 6 + drivers/iio/adc/stm32-dfsdm-core.c | 8 +- drivers/infiniband/core/addr.c | 2 +- drivers/infiniband/hw/i40iw/i40iw_verbs.c | 2 + drivers/infiniband/hw/mlx5/mad.c | 60 ++++---- drivers/infiniband/sw/rxe/rxe_resp.c | 5 +- drivers/infiniband/sw/rxe/rxe_verbs.h | 1 + drivers/infiniband/ulp/ipoib/ipoib_main.c | 34 +++-- drivers/iommu/intel-iommu.c | 3 +- drivers/iommu/iova.c | 23 ++- drivers/mailbox/mailbox.c | 6 +- drivers/media/platform/coda/Makefile | 4 +- drivers/memstick/core/memstick.c | 13 +- drivers/mfd/arizona-core.c | 2 +- drivers/mfd/cros_ec_dev.c | 13 +- drivers/mfd/hi655x-pmic.c | 2 + drivers/mfd/madera-core.c | 1 + drivers/mfd/mfd-core.c | 1 + drivers/misc/eeprom/Kconfig | 3 + drivers/misc/mei/hw-me-regs.h | 3 + drivers/misc/mei/pci-me.c | 3 + drivers/mmc/host/sdhci-pci-o2micro.c | 12 +- drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c | 19 ++- drivers/nvdimm/bus.c | 121 +++++++++++----- drivers/nvdimm/nd-core.h | 3 +- drivers/nvdimm/region.c | 22 +-- drivers/nvme/host/core.c | 5 + drivers/nvme/host/pci.c | 17 ++- drivers/nvme/host/tcp.c | 9 +- drivers/pci/controller/dwc/pci-dra7xx.c | 1 + drivers/pci/controller/pcie-mobiveil.c | 22 ++- drivers/pci/controller/pcie-xilinx-nwl.c | 11 +- drivers/pci/endpoint/functions/pci-epf-test.c | 8 +- drivers/pci/pci-driver.c | 13 +- drivers/pci/pci-sysfs.c | 2 +- drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c | 2 +- drivers/phy/renesas/phy-rcar-gen2.c | 2 + drivers/phy/renesas/phy-rcar-gen3-usb2.c | 19 ++- drivers/pinctrl/pinctrl-rockchip.c | 1 + drivers/platform/x86/Kconfig | 2 +- drivers/platform/x86/asus-wmi.c | 10 +- .../regulator/{88pm800.c => 88pm800-regulator.c} | 0 drivers/regulator/Makefile | 2 +- drivers/staging/kpc2000/TODO | 1 - drivers/staging/kpc2000/kpc2000/cell_probe.c | 3 + drivers/staging/kpc2000/kpc_spi/spi_driver.c | 8 +- drivers/staging/vt6656/main_usb.c | 42 ++++-- drivers/tty/serial/8250/8250_port.c | 3 +- drivers/tty/serial/cpm_uart/cpm_uart_core.c | 17 ++- drivers/tty/serial/digicolor-usart.c | 6 +- drivers/tty/serial/imx.c | 23 +-- drivers/tty/serial/max310x.c | 51 ++++--- drivers/tty/serial/msm_serial.c | 4 + drivers/tty/serial/serial_core.c | 7 +- drivers/tty/serial/serial_mctrl_gpio.c | 14 ++ drivers/tty/serial/sh-sci.c | 33 +++-- drivers/tty/serial/sunhv.c | 2 +- drivers/tty/serial/xilinx_uartps.c | 5 +- drivers/usb/core/hub.c | 28 ++-- drivers/usb/dwc3/core.c | 12 +- drivers/usb/gadget/function/f_fs.c | 6 +- drivers/usb/host/hwa-hc.c | 2 +- drivers/usb/host/pci-quirks.c | 31 +++-- drivers/usb/host/xhci.h | 3 +- drivers/usb/misc/usb251xb.c | 15 +- drivers/usb/storage/scsiglue.c | 11 ++ fs/9p/vfs_addr.c | 6 +- fs/btrfs/inode.c | 24 +++- fs/btrfs/props.c | 2 +- fs/dlm/lowcomms.c | 18 ++- fs/f2fs/checkpoint.c | 11 -- fs/f2fs/data.c | 3 + fs/f2fs/f2fs.h | 18 ++- fs/f2fs/segment.c | 21 ++- fs/f2fs/super.c | 10 ++ fs/io_uring.c | 60 +++++++- fs/notify/fanotify/fanotify.c | 5 +- fs/notify/inotify/inotify_fsnotify.c | 8 +- fs/open.c | 19 +++ fs/proc/base.c | 28 +++- fs/proc/task_mmu.c | 23 ++- fs/proc/task_nommu.c | 6 +- include/linux/cred.h | 8 +- include/linux/device.h | 1 + include/linux/hmm.h | 1 + include/linux/host1x.h | 2 + include/linux/iova.h | 6 + include/linux/swap.h | 13 +- include/uapi/linux/videodev2.h | 8 +- kernel/cred.c | 21 ++- kernel/dma/remap.c | 3 + kernel/locking/lockdep_proc.c | 8 +- mm/gup.c | 12 +- mm/hmm.c | 23 ++- mm/kmemleak.c | 2 +- mm/memory.c | 6 +- mm/mincore.c | 12 +- mm/mmu_notifier.c | 2 +- mm/nommu.c | 3 +- mm/swap.c | 13 +- mm/swap_state.c | 16 ++- mm/swapfile.c | 154 ++++++++++++++++----- net/rds/rdma_transport.c | 5 +- scripts/Makefile.extrawarn | 1 - scripts/basic/fixdep.c | 51 +++++-- scripts/genksyms/keywords.c | 4 + scripts/genksyms/parse.y | 2 + scripts/kallsyms.c | 3 + scripts/recordmcount.h | 3 +- security/Kconfig.hardening | 7 + security/selinux/ss/sidtab.c | 5 + sound/ac97/bus.c | 13 +- sound/core/pcm_native.c | 9 +- sound/pci/hda/hda_intel.c | 5 +- sound/pci/hda/patch_conexant.c | 1 + sound/usb/line6/podhd.c | 2 +- tools/iio/iio_utils.c | 4 +- tools/pci/pcitest.c | 6 +- tools/perf/builtin-stat.c | 2 +- tools/perf/builtin-top.c | 8 +- tools/perf/builtin-trace.c | 6 +- tools/perf/tests/mmap-thread-lookup.c | 2 +- tools/perf/ui/browsers/hists.c | 15 +- tools/perf/util/annotate.c | 6 +- tools/perf/util/intel-bts.c | 5 +- tools/perf/util/map.c | 7 +- tools/perf/util/session.c | 3 + tools/testing/selftests/rseq/rseq-arm.h | 61 ++++---- 218 files changed, 1785 insertions(+), 679 deletions(-)
From: Anders Roxell anders.roxell@linaro.org
commit 6f10419187d0d5fe395e2a2f2a64370961bf02a3 upstream.
When building with CONFIG_MFD_88PM800 and CONFIG_REGULATOR_88PM800 enabled as loadable modules, we see the following warning:
warning: same module names found: drivers/regulator/88pm800.ko drivers/mfd/88pm800.ko
Rework so that the file is named 88pm800-regulator.
Signed-off-by: Anders Roxell anders.roxell@linaro.org Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/regulator/88pm800-regulator.c | 286 ++++++++++++++++++++++++++++++++++ drivers/regulator/88pm800.c | 286 ---------------------------------- drivers/regulator/Makefile | 2 3 files changed, 287 insertions(+), 287 deletions(-)
--- /dev/null +++ b/drivers/regulator/88pm800-regulator.c @@ -0,0 +1,286 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Regulators driver for Marvell 88PM800 + * + * Copyright (C) 2012 Marvell International Ltd. + * Joseph(Yossi) Hanin yhanin@marvell.com + * Yi Zhang yizhang@marvell.com + */ +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/init.h> +#include <linux/err.h> +#include <linux/regmap.h> +#include <linux/regulator/driver.h> +#include <linux/regulator/machine.h> +#include <linux/mfd/88pm80x.h> +#include <linux/delay.h> +#include <linux/io.h> +#include <linux/of.h> +#include <linux/regulator/of_regulator.h> + +/* LDO1 with DVC[0..3] */ +#define PM800_LDO1_VOUT (0x08) /* VOUT1 */ +#define PM800_LDO1_VOUT_2 (0x09) +#define PM800_LDO1_VOUT_3 (0x0A) +#define PM800_LDO2_VOUT (0x0B) +#define PM800_LDO3_VOUT (0x0C) +#define PM800_LDO4_VOUT (0x0D) +#define PM800_LDO5_VOUT (0x0E) +#define PM800_LDO6_VOUT (0x0F) +#define PM800_LDO7_VOUT (0x10) +#define PM800_LDO8_VOUT (0x11) +#define PM800_LDO9_VOUT (0x12) +#define PM800_LDO10_VOUT (0x13) +#define PM800_LDO11_VOUT (0x14) +#define PM800_LDO12_VOUT (0x15) +#define PM800_LDO13_VOUT (0x16) +#define PM800_LDO14_VOUT (0x17) +#define PM800_LDO15_VOUT (0x18) +#define PM800_LDO16_VOUT (0x19) +#define PM800_LDO17_VOUT (0x1A) +#define PM800_LDO18_VOUT (0x1B) +#define PM800_LDO19_VOUT (0x1C) + +/* BUCK1 with DVC[0..3] */ +#define PM800_BUCK1 (0x3C) +#define PM800_BUCK1_1 (0x3D) +#define PM800_BUCK1_2 (0x3E) +#define PM800_BUCK1_3 (0x3F) +#define PM800_BUCK2 (0x40) +#define PM800_BUCK3 (0x41) +#define PM800_BUCK4 (0x42) +#define PM800_BUCK4_1 (0x43) +#define PM800_BUCK4_2 (0x44) +#define PM800_BUCK4_3 (0x45) +#define PM800_BUCK5 (0x46) + +#define PM800_BUCK_ENA (0x50) +#define PM800_LDO_ENA1_1 (0x51) +#define PM800_LDO_ENA1_2 (0x52) +#define PM800_LDO_ENA1_3 (0x53) + +#define PM800_LDO_ENA2_1 (0x56) +#define PM800_LDO_ENA2_2 (0x57) +#define PM800_LDO_ENA2_3 (0x58) + +#define PM800_BUCK1_MISC1 (0x78) +#define PM800_BUCK3_MISC1 (0x7E) +#define PM800_BUCK4_MISC1 (0x81) +#define PM800_BUCK5_MISC1 (0x84) + +struct pm800_regulator_info { + struct regulator_desc desc; + int max_ua; +}; + +/* + * vreg - the buck regs string. + * ereg - the string for the enable register. + * ebit - the bit number in the enable register. + * amax - the current + * Buck has 2 kinds of voltage steps. It is easy to find voltage by ranges, + * not the constant voltage table. + * n_volt - Number of available selectors + */ +#define PM800_BUCK(match, vreg, ereg, ebit, amax, volt_ranges, n_volt) \ +{ \ + .desc = { \ + .name = #vreg, \ + .of_match = of_match_ptr(#match), \ + .regulators_node = of_match_ptr("regulators"), \ + .ops = &pm800_volt_range_ops, \ + .type = REGULATOR_VOLTAGE, \ + .id = PM800_ID_##vreg, \ + .owner = THIS_MODULE, \ + .n_voltages = n_volt, \ + .linear_ranges = volt_ranges, \ + .n_linear_ranges = ARRAY_SIZE(volt_ranges), \ + .vsel_reg = PM800_##vreg, \ + .vsel_mask = 0x7f, \ + .enable_reg = PM800_##ereg, \ + .enable_mask = 1 << (ebit), \ + }, \ + .max_ua = (amax), \ +} + +/* + * vreg - the LDO regs string + * ereg - the string for the enable register. + * ebit - the bit number in the enable register. + * amax - the current + * volt_table - the LDO voltage table + * For all the LDOes, there are too many ranges. Using volt_table will be + * simpler and faster. + */ +#define PM800_LDO(match, vreg, ereg, ebit, amax, ldo_volt_table) \ +{ \ + .desc = { \ + .name = #vreg, \ + .of_match = of_match_ptr(#match), \ + .regulators_node = of_match_ptr("regulators"), \ + .ops = &pm800_volt_table_ops, \ + .type = REGULATOR_VOLTAGE, \ + .id = PM800_ID_##vreg, \ + .owner = THIS_MODULE, \ + .n_voltages = ARRAY_SIZE(ldo_volt_table), \ + .vsel_reg = PM800_##vreg##_VOUT, \ + .vsel_mask = 0xf, \ + .enable_reg = PM800_##ereg, \ + .enable_mask = 1 << (ebit), \ + .volt_table = ldo_volt_table, \ + }, \ + .max_ua = (amax), \ +} + +/* Ranges are sorted in ascending order. */ +static const struct regulator_linear_range buck1_volt_range[] = { + REGULATOR_LINEAR_RANGE(600000, 0, 0x4f, 12500), + REGULATOR_LINEAR_RANGE(1600000, 0x50, 0x54, 50000), +}; + +/* BUCK 2~5 have same ranges. */ +static const struct regulator_linear_range buck2_5_volt_range[] = { + REGULATOR_LINEAR_RANGE(600000, 0, 0x4f, 12500), + REGULATOR_LINEAR_RANGE(1600000, 0x50, 0x72, 50000), +}; + +static const unsigned int ldo1_volt_table[] = { + 600000, 650000, 700000, 750000, 800000, 850000, 900000, 950000, + 1000000, 1050000, 1100000, 1150000, 1200000, 1300000, 1400000, 1500000, +}; + +static const unsigned int ldo2_volt_table[] = { + 1700000, 1800000, 1900000, 2000000, 2100000, 2500000, 2700000, 2800000, +}; + +/* LDO 3~17 have same voltage table. */ +static const unsigned int ldo3_17_volt_table[] = { + 1200000, 1250000, 1700000, 1800000, 1850000, 1900000, 2500000, 2600000, + 2700000, 2750000, 2800000, 2850000, 2900000, 3000000, 3100000, 3300000, +}; + +/* LDO 18~19 have same voltage table. */ +static const unsigned int ldo18_19_volt_table[] = { + 1700000, 1800000, 1900000, 2500000, 2800000, 2900000, 3100000, 3300000, +}; + +static int pm800_get_current_limit(struct regulator_dev *rdev) +{ + struct pm800_regulator_info *info = rdev_get_drvdata(rdev); + + return info->max_ua; +} + +static const struct regulator_ops pm800_volt_range_ops = { + .list_voltage = regulator_list_voltage_linear_range, + .map_voltage = regulator_map_voltage_linear_range, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .get_current_limit = pm800_get_current_limit, +}; + +static const struct regulator_ops pm800_volt_table_ops = { + .list_voltage = regulator_list_voltage_table, + .map_voltage = regulator_map_voltage_iterate, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .get_current_limit = pm800_get_current_limit, +}; + +/* The array is indexed by id(PM800_ID_XXX) */ +static struct pm800_regulator_info pm800_regulator_info[] = { + PM800_BUCK(buck1, BUCK1, BUCK_ENA, 0, 3000000, buck1_volt_range, 0x55), + PM800_BUCK(buck2, BUCK2, BUCK_ENA, 1, 1200000, buck2_5_volt_range, 0x73), + PM800_BUCK(buck3, BUCK3, BUCK_ENA, 2, 1200000, buck2_5_volt_range, 0x73), + PM800_BUCK(buck4, BUCK4, BUCK_ENA, 3, 1200000, buck2_5_volt_range, 0x73), + PM800_BUCK(buck5, BUCK5, BUCK_ENA, 4, 1200000, buck2_5_volt_range, 0x73), + + PM800_LDO(ldo1, LDO1, LDO_ENA1_1, 0, 200000, ldo1_volt_table), + PM800_LDO(ldo2, LDO2, LDO_ENA1_1, 1, 10000, ldo2_volt_table), + PM800_LDO(ldo3, LDO3, LDO_ENA1_1, 2, 300000, ldo3_17_volt_table), + PM800_LDO(ldo4, LDO4, LDO_ENA1_1, 3, 300000, ldo3_17_volt_table), + PM800_LDO(ldo5, LDO5, LDO_ENA1_1, 4, 300000, ldo3_17_volt_table), + PM800_LDO(ldo6, LDO6, LDO_ENA1_1, 5, 300000, ldo3_17_volt_table), + PM800_LDO(ldo7, LDO7, LDO_ENA1_1, 6, 300000, ldo3_17_volt_table), + PM800_LDO(ldo8, LDO8, LDO_ENA1_1, 7, 300000, ldo3_17_volt_table), + PM800_LDO(ldo9, LDO9, LDO_ENA1_2, 0, 300000, ldo3_17_volt_table), + PM800_LDO(ldo10, LDO10, LDO_ENA1_2, 1, 300000, ldo3_17_volt_table), + PM800_LDO(ldo11, LDO11, LDO_ENA1_2, 2, 300000, ldo3_17_volt_table), + PM800_LDO(ldo12, LDO12, LDO_ENA1_2, 3, 300000, ldo3_17_volt_table), + PM800_LDO(ldo13, LDO13, LDO_ENA1_2, 4, 300000, ldo3_17_volt_table), + PM800_LDO(ldo14, LDO14, LDO_ENA1_2, 5, 300000, ldo3_17_volt_table), + PM800_LDO(ldo15, LDO15, LDO_ENA1_2, 6, 300000, ldo3_17_volt_table), + PM800_LDO(ldo16, LDO16, LDO_ENA1_2, 7, 300000, ldo3_17_volt_table), + PM800_LDO(ldo17, LDO17, LDO_ENA1_3, 0, 300000, ldo3_17_volt_table), + PM800_LDO(ldo18, LDO18, LDO_ENA1_3, 1, 200000, ldo18_19_volt_table), + PM800_LDO(ldo19, LDO19, LDO_ENA1_3, 2, 200000, ldo18_19_volt_table), +}; + +static int pm800_regulator_probe(struct platform_device *pdev) +{ + struct pm80x_chip *chip = dev_get_drvdata(pdev->dev.parent); + struct pm80x_platform_data *pdata = dev_get_platdata(pdev->dev.parent); + struct regulator_config config = { }; + struct regulator_init_data *init_data; + int i, ret; + + if (pdata && pdata->num_regulators) { + unsigned int count = 0; + + /* Check whether num_regulator is valid. */ + for (i = 0; i < ARRAY_SIZE(pdata->regulators); i++) { + if (pdata->regulators[i]) + count++; + } + if (count != pdata->num_regulators) + return -EINVAL; + } + + config.dev = chip->dev; + config.regmap = chip->subchip->regmap_power; + for (i = 0; i < PM800_ID_RG_MAX; i++) { + struct regulator_dev *regulator; + + if (pdata && pdata->num_regulators) { + init_data = pdata->regulators[i]; + if (!init_data) + continue; + + config.init_data = init_data; + } + + config.driver_data = &pm800_regulator_info[i]; + + regulator = devm_regulator_register(&pdev->dev, + &pm800_regulator_info[i].desc, &config); + if (IS_ERR(regulator)) { + ret = PTR_ERR(regulator); + dev_err(&pdev->dev, "Failed to register %s\n", + pm800_regulator_info[i].desc.name); + return ret; + } + } + + return 0; +} + +static struct platform_driver pm800_regulator_driver = { + .driver = { + .name = "88pm80x-regulator", + }, + .probe = pm800_regulator_probe, +}; + +module_platform_driver(pm800_regulator_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Joseph(Yossi) Hanin yhanin@marvell.com"); +MODULE_DESCRIPTION("Regulator Driver for Marvell 88PM800 PMIC"); +MODULE_ALIAS("platform:88pm800-regulator"); --- a/drivers/regulator/88pm800.c +++ /dev/null @@ -1,286 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Regulators driver for Marvell 88PM800 - * - * Copyright (C) 2012 Marvell International Ltd. - * Joseph(Yossi) Hanin yhanin@marvell.com - * Yi Zhang yizhang@marvell.com - */ -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/init.h> -#include <linux/err.h> -#include <linux/regmap.h> -#include <linux/regulator/driver.h> -#include <linux/regulator/machine.h> -#include <linux/mfd/88pm80x.h> -#include <linux/delay.h> -#include <linux/io.h> -#include <linux/of.h> -#include <linux/regulator/of_regulator.h> - -/* LDO1 with DVC[0..3] */ -#define PM800_LDO1_VOUT (0x08) /* VOUT1 */ -#define PM800_LDO1_VOUT_2 (0x09) -#define PM800_LDO1_VOUT_3 (0x0A) -#define PM800_LDO2_VOUT (0x0B) -#define PM800_LDO3_VOUT (0x0C) -#define PM800_LDO4_VOUT (0x0D) -#define PM800_LDO5_VOUT (0x0E) -#define PM800_LDO6_VOUT (0x0F) -#define PM800_LDO7_VOUT (0x10) -#define PM800_LDO8_VOUT (0x11) -#define PM800_LDO9_VOUT (0x12) -#define PM800_LDO10_VOUT (0x13) -#define PM800_LDO11_VOUT (0x14) -#define PM800_LDO12_VOUT (0x15) -#define PM800_LDO13_VOUT (0x16) -#define PM800_LDO14_VOUT (0x17) -#define PM800_LDO15_VOUT (0x18) -#define PM800_LDO16_VOUT (0x19) -#define PM800_LDO17_VOUT (0x1A) -#define PM800_LDO18_VOUT (0x1B) -#define PM800_LDO19_VOUT (0x1C) - -/* BUCK1 with DVC[0..3] */ -#define PM800_BUCK1 (0x3C) -#define PM800_BUCK1_1 (0x3D) -#define PM800_BUCK1_2 (0x3E) -#define PM800_BUCK1_3 (0x3F) -#define PM800_BUCK2 (0x40) -#define PM800_BUCK3 (0x41) -#define PM800_BUCK4 (0x42) -#define PM800_BUCK4_1 (0x43) -#define PM800_BUCK4_2 (0x44) -#define PM800_BUCK4_3 (0x45) -#define PM800_BUCK5 (0x46) - -#define PM800_BUCK_ENA (0x50) -#define PM800_LDO_ENA1_1 (0x51) -#define PM800_LDO_ENA1_2 (0x52) -#define PM800_LDO_ENA1_3 (0x53) - -#define PM800_LDO_ENA2_1 (0x56) -#define PM800_LDO_ENA2_2 (0x57) -#define PM800_LDO_ENA2_3 (0x58) - -#define PM800_BUCK1_MISC1 (0x78) -#define PM800_BUCK3_MISC1 (0x7E) -#define PM800_BUCK4_MISC1 (0x81) -#define PM800_BUCK5_MISC1 (0x84) - -struct pm800_regulator_info { - struct regulator_desc desc; - int max_ua; -}; - -/* - * vreg - the buck regs string. - * ereg - the string for the enable register. - * ebit - the bit number in the enable register. - * amax - the current - * Buck has 2 kinds of voltage steps. It is easy to find voltage by ranges, - * not the constant voltage table. - * n_volt - Number of available selectors - */ -#define PM800_BUCK(match, vreg, ereg, ebit, amax, volt_ranges, n_volt) \ -{ \ - .desc = { \ - .name = #vreg, \ - .of_match = of_match_ptr(#match), \ - .regulators_node = of_match_ptr("regulators"), \ - .ops = &pm800_volt_range_ops, \ - .type = REGULATOR_VOLTAGE, \ - .id = PM800_ID_##vreg, \ - .owner = THIS_MODULE, \ - .n_voltages = n_volt, \ - .linear_ranges = volt_ranges, \ - .n_linear_ranges = ARRAY_SIZE(volt_ranges), \ - .vsel_reg = PM800_##vreg, \ - .vsel_mask = 0x7f, \ - .enable_reg = PM800_##ereg, \ - .enable_mask = 1 << (ebit), \ - }, \ - .max_ua = (amax), \ -} - -/* - * vreg - the LDO regs string - * ereg - the string for the enable register. - * ebit - the bit number in the enable register. - * amax - the current - * volt_table - the LDO voltage table - * For all the LDOes, there are too many ranges. Using volt_table will be - * simpler and faster. - */ -#define PM800_LDO(match, vreg, ereg, ebit, amax, ldo_volt_table) \ -{ \ - .desc = { \ - .name = #vreg, \ - .of_match = of_match_ptr(#match), \ - .regulators_node = of_match_ptr("regulators"), \ - .ops = &pm800_volt_table_ops, \ - .type = REGULATOR_VOLTAGE, \ - .id = PM800_ID_##vreg, \ - .owner = THIS_MODULE, \ - .n_voltages = ARRAY_SIZE(ldo_volt_table), \ - .vsel_reg = PM800_##vreg##_VOUT, \ - .vsel_mask = 0xf, \ - .enable_reg = PM800_##ereg, \ - .enable_mask = 1 << (ebit), \ - .volt_table = ldo_volt_table, \ - }, \ - .max_ua = (amax), \ -} - -/* Ranges are sorted in ascending order. */ -static const struct regulator_linear_range buck1_volt_range[] = { - REGULATOR_LINEAR_RANGE(600000, 0, 0x4f, 12500), - REGULATOR_LINEAR_RANGE(1600000, 0x50, 0x54, 50000), -}; - -/* BUCK 2~5 have same ranges. */ -static const struct regulator_linear_range buck2_5_volt_range[] = { - REGULATOR_LINEAR_RANGE(600000, 0, 0x4f, 12500), - REGULATOR_LINEAR_RANGE(1600000, 0x50, 0x72, 50000), -}; - -static const unsigned int ldo1_volt_table[] = { - 600000, 650000, 700000, 750000, 800000, 850000, 900000, 950000, - 1000000, 1050000, 1100000, 1150000, 1200000, 1300000, 1400000, 1500000, -}; - -static const unsigned int ldo2_volt_table[] = { - 1700000, 1800000, 1900000, 2000000, 2100000, 2500000, 2700000, 2800000, -}; - -/* LDO 3~17 have same voltage table. */ -static const unsigned int ldo3_17_volt_table[] = { - 1200000, 1250000, 1700000, 1800000, 1850000, 1900000, 2500000, 2600000, - 2700000, 2750000, 2800000, 2850000, 2900000, 3000000, 3100000, 3300000, -}; - -/* LDO 18~19 have same voltage table. */ -static const unsigned int ldo18_19_volt_table[] = { - 1700000, 1800000, 1900000, 2500000, 2800000, 2900000, 3100000, 3300000, -}; - -static int pm800_get_current_limit(struct regulator_dev *rdev) -{ - struct pm800_regulator_info *info = rdev_get_drvdata(rdev); - - return info->max_ua; -} - -static const struct regulator_ops pm800_volt_range_ops = { - .list_voltage = regulator_list_voltage_linear_range, - .map_voltage = regulator_map_voltage_linear_range, - .set_voltage_sel = regulator_set_voltage_sel_regmap, - .get_voltage_sel = regulator_get_voltage_sel_regmap, - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, - .is_enabled = regulator_is_enabled_regmap, - .get_current_limit = pm800_get_current_limit, -}; - -static const struct regulator_ops pm800_volt_table_ops = { - .list_voltage = regulator_list_voltage_table, - .map_voltage = regulator_map_voltage_iterate, - .set_voltage_sel = regulator_set_voltage_sel_regmap, - .get_voltage_sel = regulator_get_voltage_sel_regmap, - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, - .is_enabled = regulator_is_enabled_regmap, - .get_current_limit = pm800_get_current_limit, -}; - -/* The array is indexed by id(PM800_ID_XXX) */ -static struct pm800_regulator_info pm800_regulator_info[] = { - PM800_BUCK(buck1, BUCK1, BUCK_ENA, 0, 3000000, buck1_volt_range, 0x55), - PM800_BUCK(buck2, BUCK2, BUCK_ENA, 1, 1200000, buck2_5_volt_range, 0x73), - PM800_BUCK(buck3, BUCK3, BUCK_ENA, 2, 1200000, buck2_5_volt_range, 0x73), - PM800_BUCK(buck4, BUCK4, BUCK_ENA, 3, 1200000, buck2_5_volt_range, 0x73), - PM800_BUCK(buck5, BUCK5, BUCK_ENA, 4, 1200000, buck2_5_volt_range, 0x73), - - PM800_LDO(ldo1, LDO1, LDO_ENA1_1, 0, 200000, ldo1_volt_table), - PM800_LDO(ldo2, LDO2, LDO_ENA1_1, 1, 10000, ldo2_volt_table), - PM800_LDO(ldo3, LDO3, LDO_ENA1_1, 2, 300000, ldo3_17_volt_table), - PM800_LDO(ldo4, LDO4, LDO_ENA1_1, 3, 300000, ldo3_17_volt_table), - PM800_LDO(ldo5, LDO5, LDO_ENA1_1, 4, 300000, ldo3_17_volt_table), - PM800_LDO(ldo6, LDO6, LDO_ENA1_1, 5, 300000, ldo3_17_volt_table), - PM800_LDO(ldo7, LDO7, LDO_ENA1_1, 6, 300000, ldo3_17_volt_table), - PM800_LDO(ldo8, LDO8, LDO_ENA1_1, 7, 300000, ldo3_17_volt_table), - PM800_LDO(ldo9, LDO9, LDO_ENA1_2, 0, 300000, ldo3_17_volt_table), - PM800_LDO(ldo10, LDO10, LDO_ENA1_2, 1, 300000, ldo3_17_volt_table), - PM800_LDO(ldo11, LDO11, LDO_ENA1_2, 2, 300000, ldo3_17_volt_table), - PM800_LDO(ldo12, LDO12, LDO_ENA1_2, 3, 300000, ldo3_17_volt_table), - PM800_LDO(ldo13, LDO13, LDO_ENA1_2, 4, 300000, ldo3_17_volt_table), - PM800_LDO(ldo14, LDO14, LDO_ENA1_2, 5, 300000, ldo3_17_volt_table), - PM800_LDO(ldo15, LDO15, LDO_ENA1_2, 6, 300000, ldo3_17_volt_table), - PM800_LDO(ldo16, LDO16, LDO_ENA1_2, 7, 300000, ldo3_17_volt_table), - PM800_LDO(ldo17, LDO17, LDO_ENA1_3, 0, 300000, ldo3_17_volt_table), - PM800_LDO(ldo18, LDO18, LDO_ENA1_3, 1, 200000, ldo18_19_volt_table), - PM800_LDO(ldo19, LDO19, LDO_ENA1_3, 2, 200000, ldo18_19_volt_table), -}; - -static int pm800_regulator_probe(struct platform_device *pdev) -{ - struct pm80x_chip *chip = dev_get_drvdata(pdev->dev.parent); - struct pm80x_platform_data *pdata = dev_get_platdata(pdev->dev.parent); - struct regulator_config config = { }; - struct regulator_init_data *init_data; - int i, ret; - - if (pdata && pdata->num_regulators) { - unsigned int count = 0; - - /* Check whether num_regulator is valid. */ - for (i = 0; i < ARRAY_SIZE(pdata->regulators); i++) { - if (pdata->regulators[i]) - count++; - } - if (count != pdata->num_regulators) - return -EINVAL; - } - - config.dev = chip->dev; - config.regmap = chip->subchip->regmap_power; - for (i = 0; i < PM800_ID_RG_MAX; i++) { - struct regulator_dev *regulator; - - if (pdata && pdata->num_regulators) { - init_data = pdata->regulators[i]; - if (!init_data) - continue; - - config.init_data = init_data; - } - - config.driver_data = &pm800_regulator_info[i]; - - regulator = devm_regulator_register(&pdev->dev, - &pm800_regulator_info[i].desc, &config); - if (IS_ERR(regulator)) { - ret = PTR_ERR(regulator); - dev_err(&pdev->dev, "Failed to register %s\n", - pm800_regulator_info[i].desc.name); - return ret; - } - } - - return 0; -} - -static struct platform_driver pm800_regulator_driver = { - .driver = { - .name = "88pm80x-regulator", - }, - .probe = pm800_regulator_probe, -}; - -module_platform_driver(pm800_regulator_driver); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Joseph(Yossi) Hanin yhanin@marvell.com"); -MODULE_DESCRIPTION("Regulator Driver for Marvell 88PM800 PMIC"); -MODULE_ALIAS("platform:88pm800-regulator"); --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -11,7 +11,7 @@ obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) obj-$(CONFIG_REGULATOR_USERSPACE_CONSUMER) += userspace-consumer.o
obj-$(CONFIG_REGULATOR_88PG86X) += 88pg86x.o -obj-$(CONFIG_REGULATOR_88PM800) += 88pm800.o +obj-$(CONFIG_REGULATOR_88PM800) += 88pm800-regulator.o obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o obj-$(CONFIG_REGULATOR_CPCAP) += cpcap-regulator.o obj-$(CONFIG_REGULATOR_AAT2870) += aat2870-regulator.o
From: Anders Roxell anders.roxell@linaro.org
commit 1296987d2baf7f56748359b8dd42c425b9e7ee3a upstream.
When building with CONFIG_VIDEO_CODA and CONFIG_CODA_FS enabled as loadable modules, we see the following warning:
fs/coda/coda.ko drivers/media/platform/coda/coda.ko
Rework so media/platform/coda is named coda-vpu. Leaving CODA_FS as is since that's a well known module.
Signed-off-by: Anders Roxell anders.roxell@linaro.org Reviewed-by: Philipp Zabel p.zabel@pengutronix.de Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+samsung@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/media/platform/coda/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/media/platform/coda/Makefile +++ b/drivers/media/platform/coda/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only ccflags-y += -I$(src)
-coda-objs := coda-common.o coda-bit.o coda-gdi.o coda-h264.o coda-jpeg.o +coda-vpu-objs := coda-common.o coda-bit.o coda-gdi.o coda-h264.o coda-jpeg.o
-obj-$(CONFIG_VIDEO_CODA) += coda.o +obj-$(CONFIG_VIDEO_CODA) += coda-vpu.o obj-$(CONFIG_VIDEO_IMX_VDOA) += imx-vdoa.o
From: Arnd Bergmann arnd@arndb.de
commit 6c64460cdc8be5fa074aa8fe2ae8736d5792bdc5 upstream.
gcc sometimes can't determine whether a variable has been initialized when both the initialization and the use are conditional:
fs/btrfs/props.c: In function 'inherit_props': fs/btrfs/props.c:389:4: error: 'num_bytes' may be used uninitialized in this function [-Werror=maybe-uninitialized] btrfs_block_rsv_release(fs_info, trans->block_rsv,
This code is fine. Unfortunately, I cannot think of a good way to rephrase it in a way that makes gcc understand this, so I add a bogus initialization the way one should not.
Signed-off-by: Arnd Bergmann arnd@arndb.de Reviewed-by: David Sterba dsterba@suse.com [ gcc 8 and 9 don't emit the warning ] Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/btrfs/props.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/btrfs/props.c +++ b/fs/btrfs/props.c @@ -337,7 +337,7 @@ static int inherit_props(struct btrfs_tr for (i = 0; i < ARRAY_SIZE(prop_handlers); i++) { const struct prop_handler *h = &prop_handlers[i]; const char *value; - u64 num_bytes; + u64 num_bytes = 0;
if (!h->inheritable) continue;
[ Upstream commit 409c53f07a81f8db122c461f3255c6f43558c881 ]
On Hikey board all lima ip blocks are shared with one irq. This patch avoids a NULL ptr deref crash on this platform on startup. Tested with Weston and kmscube.
Signed-off-by: Peter Griffin peter.griffin@linaro.org Cc: Rob Herring robh@kernel.org Cc: Daniel Vetter daniel@ffwll.ch Cc: Qiang Yu yuq825@gmail.com Signed-off-by: Qiang Yu yuq825@gmail.com Link: https://patchwork.freedesktop.org/patch/msgid/1555662781-22570-7-git-send-em... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/lima/lima_pp.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/lima/lima_pp.c b/drivers/gpu/drm/lima/lima_pp.c index d29721e177bf..8fef224b93c8 100644 --- a/drivers/gpu/drm/lima/lima_pp.c +++ b/drivers/gpu/drm/lima/lima_pp.c @@ -64,7 +64,13 @@ static irqreturn_t lima_pp_bcast_irq_handler(int irq, void *data) struct lima_ip *pp_bcast = data; struct lima_device *dev = pp_bcast->dev; struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp; - struct drm_lima_m450_pp_frame *frame = pipe->current_task->frame; + struct drm_lima_m450_pp_frame *frame; + + /* for shared irq case */ + if (!pipe->current_task) + return IRQ_NONE; + + frame = pipe->current_task->frame;
for (i = 0; i < frame->num_pp; i++) { struct lima_ip *ip = pipe->processor[i];
[ Upstream commit 7ad9db66fafb0f0ad53fd2a66217105da5ddeffe ]
In case mipi_dsi_attach() fails remove the registered panel to avoid added panel without corresponding device.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@ti.com Signed-off-by: Thierry Reding treding@nvidia.com Link: https://patchwork.freedesktop.org/patch/msgid/20190226081153.31334-1-peter.u... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/panel/panel-simple.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 569be4efd8d1..48e2fa7bbe48 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -3098,7 +3098,14 @@ static int panel_simple_dsi_probe(struct mipi_dsi_device *dsi) dsi->format = desc->format; dsi->lanes = desc->lanes;
- return mipi_dsi_attach(dsi); + err = mipi_dsi_attach(dsi); + if (err) { + struct panel_simple *panel = dev_get_drvdata(&dsi->dev); + + drm_panel_remove(&panel->base); + } + + return err; }
static int panel_simple_dsi_remove(struct mipi_dsi_device *dsi)
[ Upstream commit 3e53ef91f826957dec013c47707ffc1bb42b42d7 ]
During probe, check the "get_irq" error value.
Signed-off-by: Fabien Dessenne fabien.dessenne@st.com Acked-by: Fabrice Gasnier fabrice.gasnier@st.com Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/adc/stm32-dfsdm-adc.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/drivers/iio/adc/stm32-dfsdm-adc.c b/drivers/iio/adc/stm32-dfsdm-adc.c index 19adc2b23472..588907cc3b6b 100644 --- a/drivers/iio/adc/stm32-dfsdm-adc.c +++ b/drivers/iio/adc/stm32-dfsdm-adc.c @@ -1456,6 +1456,12 @@ static int stm32_dfsdm_adc_probe(struct platform_device *pdev) * So IRQ associated to filter instance 0 is dedicated to the Filter 0. */ irq = platform_get_irq(pdev, 0); + if (irq < 0) { + if (irq != -EPROBE_DEFER) + dev_err(dev, "Failed to get IRQ: %d\n", irq); + return irq; + } + ret = devm_request_irq(dev, irq, stm32_dfsdm_irq, 0, pdev->name, adc); if (ret < 0) {
[ Upstream commit d2fc0156963cae8f1eec8e2dd645fbbf1e1c1c8e ]
During probe, check the devm_ioremap_resource() error value. Also return the devm_clk_get() error value instead of -EINVAL.
Signed-off-by: Fabien Dessenne fabien.dessenne@st.com Acked-by: Fabrice Gasnier fabrice.gasnier@st.com Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/adc/stm32-dfsdm-core.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/adc/stm32-dfsdm-core.c b/drivers/iio/adc/stm32-dfsdm-core.c index 0a4d3746d21c..26e2011c5868 100644 --- a/drivers/iio/adc/stm32-dfsdm-core.c +++ b/drivers/iio/adc/stm32-dfsdm-core.c @@ -233,6 +233,8 @@ static int stm32_dfsdm_parse_of(struct platform_device *pdev, } priv->dfsdm.phys_base = res->start; priv->dfsdm.base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(priv->dfsdm.base)) + return PTR_ERR(priv->dfsdm.base);
/* * "dfsdm" clock is mandatory for DFSDM peripheral clocking. @@ -242,8 +244,10 @@ static int stm32_dfsdm_parse_of(struct platform_device *pdev, */ priv->clk = devm_clk_get(&pdev->dev, "dfsdm"); if (IS_ERR(priv->clk)) { - dev_err(&pdev->dev, "No stm32_dfsdm_clk clock found\n"); - return -EINVAL; + ret = PTR_ERR(priv->clk); + if (ret != -EPROBE_DEFER) + dev_err(&pdev->dev, "Failed to get clock (%d)\n", ret); + return ret; }
priv->aclk = devm_clk_get(&pdev->dev, "audio");
[ Upstream commit efe2bf965522bf0796d413b47a2abbf81d471d6f ]
This is motivated by having meaningful ftrace events, but it also fixes use cases where dma_fence_is_later is called, such as in sync_file_merge.
In other drivers, fence creation and cmdbuf submission normally happen atomically,
mutex_lock(); fence = dma_fence_create(..., ++timeline->seqno); submit_cmdbuf(); mutex_unlock();
and have no such issue. But in our driver, because most ioctls queue commands into ctrlq, we do not want to grab a lock. Instead, we set seqno to 0 when a fence is created, and update it when the command is finally queued and the seqno is known.
Signed-off-by: Chia-I Wu olvaffe@gmail.com Reviewed-by: Emil Velikov emil.velikov@collabora.com Link: http://patchwork.freedesktop.org/patch/msgid/20190429220825.156644-1-olvaffe... Signed-off-by: Gerd Hoffmann kraxel@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/virtio/virtgpu_drv.h | 1 - drivers/gpu/drm/virtio/virtgpu_fence.c | 17 ++++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index b69ae10ca238..d724fb3de44e 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -102,7 +102,6 @@ struct virtio_gpu_fence { struct dma_fence f; struct virtio_gpu_fence_driver *drv; struct list_head node; - uint64_t seq; }; #define to_virtio_fence(x) \ container_of(x, struct virtio_gpu_fence, f) diff --git a/drivers/gpu/drm/virtio/virtgpu_fence.c b/drivers/gpu/drm/virtio/virtgpu_fence.c index 87d1966192f4..72b4f7561432 100644 --- a/drivers/gpu/drm/virtio/virtgpu_fence.c +++ b/drivers/gpu/drm/virtio/virtgpu_fence.c @@ -40,16 +40,14 @@ bool virtio_fence_signaled(struct dma_fence *f) { struct virtio_gpu_fence *fence = to_virtio_fence(f);
- if (atomic64_read(&fence->drv->last_seq) >= fence->seq) + if (atomic64_read(&fence->drv->last_seq) >= fence->f.seqno) return true; return false; }
static void virtio_fence_value_str(struct dma_fence *f, char *str, int size) { - struct virtio_gpu_fence *fence = to_virtio_fence(f); - - snprintf(str, size, "%llu", fence->seq); + snprintf(str, size, "%llu", f->seqno); }
static void virtio_timeline_value_str(struct dma_fence *f, char *str, int size) @@ -76,6 +74,11 @@ struct virtio_gpu_fence *virtio_gpu_fence_alloc(struct virtio_gpu_device *vgdev) return fence;
fence->drv = drv; + + /* This only partially initializes the fence because the seqno is + * unknown yet. The fence must not be used outside of the driver + * until virtio_gpu_fence_emit is called. + */ dma_fence_init(&fence->f, &virtio_fence_ops, &drv->lock, drv->context, 0);
return fence; @@ -89,13 +92,13 @@ int virtio_gpu_fence_emit(struct virtio_gpu_device *vgdev, unsigned long irq_flags;
spin_lock_irqsave(&drv->lock, irq_flags); - fence->seq = ++drv->sync_seq; + fence->f.seqno = ++drv->sync_seq; dma_fence_get(&fence->f); list_add_tail(&fence->node, &drv->fences); spin_unlock_irqrestore(&drv->lock, irq_flags);
cmd_hdr->flags |= cpu_to_le32(VIRTIO_GPU_FLAG_FENCE); - cmd_hdr->fence_id = cpu_to_le64(fence->seq); + cmd_hdr->fence_id = cpu_to_le64(fence->f.seqno); return 0; }
@@ -109,7 +112,7 @@ void virtio_gpu_fence_event_process(struct virtio_gpu_device *vgdev, spin_lock_irqsave(&drv->lock, irq_flags); atomic64_set(&vgdev->fence_drv.last_seq, last_seq); list_for_each_entry_safe(fence, tmp, &drv->fences, node) { - if (last_seq < fence->seq) + if (last_seq < fence->f.seqno) continue; dma_fence_signal_locked(&fence->f); list_del(&fence->node);
[ Upstream commit abb611d2c21c0a4fa8eab35dc936c80d9a07acd8 ]
On error, probe_core_uio just returned an error without freeing resources which had previously been allocated. Added the missing clean-up code.
Updated TODO.
Signed-off-by: Jeremy Sowden jeremy@azazel.net Reviewed-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/staging/kpc2000/TODO | 1 - drivers/staging/kpc2000/kpc2000/cell_probe.c | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/staging/kpc2000/TODO b/drivers/staging/kpc2000/TODO index 8c7af29fefae..ed951acc829a 100644 --- a/drivers/staging/kpc2000/TODO +++ b/drivers/staging/kpc2000/TODO @@ -1,7 +1,6 @@ - the kpc_spi driver doesn't seem to let multiple transactions (to different instances of the core) happen in parallel... - The kpc_i2c driver is a hot mess, it should probably be cleaned up a ton. It functions against current hardware though. - pcard->card_num in kp2000_pcie_probe() is a global variable and needs atomic / locking / something better. -- probe_core_uio() probably needs error handling - the loop in kp2000_probe_cores() that uses probe_core_uio() also probably needs error handling - would be nice if the AIO fileops in kpc_dma could be made to work - probably want to add a CONFIG_ option to control compilation of the AIO functions diff --git a/drivers/staging/kpc2000/kpc2000/cell_probe.c b/drivers/staging/kpc2000/kpc2000/cell_probe.c index e0dba91e7fa8..d6b57f550876 100644 --- a/drivers/staging/kpc2000/kpc2000/cell_probe.c +++ b/drivers/staging/kpc2000/kpc2000/cell_probe.c @@ -295,6 +295,7 @@ int probe_core_uio(unsigned int core_num, struct kp2000_device *pcard, char *na kudev->dev = device_create(kpc_uio_class, &pcard->pdev->dev, MKDEV(0,0), kudev, "%s.%d.%d.%d", kudev->uioinfo.name, pcard->card_num, cte.type, kudev->core_num); if (IS_ERR(kudev->dev)) { dev_err(&pcard->pdev->dev, "probe_core_uio device_create failed!\n"); + kfree(kudev); return -ENODEV; } dev_set_drvdata(kudev->dev, kudev); @@ -302,6 +303,8 @@ int probe_core_uio(unsigned int core_num, struct kp2000_device *pcard, char *na rv = uio_register_device(kudev->dev, &kudev->uioinfo); if (rv){ dev_err(&pcard->pdev->dev, "probe_core_uio failed uio_register_device: %d\n", rv); + put_device(kudev->dev); + kfree(kudev); return rv; }
[ Upstream commit 2f66353963043e1d8dfacfbdf509acc5d3be7698 ]
If ipmi_si_platform_init()->platform_driver_register() fails, platform_driver_unregister() called unconditionally will trigger following warning,
ipmi_platform: Unable to register driver: -12 ------------[ cut here ]------------ Unexpected driver unregister! WARNING: CPU: 1 PID: 7210 at drivers/base/driver.c:193 driver_unregister+0x60/0x70 drivers/base/driver.c:193
Fix it by adding platform_registered variable, only unregister platform driver when it is already successfully registered.
Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Kefeng Wang wangkefeng.wang@huawei.com Message-Id: 20190517101245.4341-1-wangkefeng.wang@huawei.com
Signed-off-by: Corey Minyard cminyard@mvista.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/char/ipmi/ipmi_si_platform.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/char/ipmi/ipmi_si_platform.c b/drivers/char/ipmi/ipmi_si_platform.c index f2a91c4d8cab..0cd849675d99 100644 --- a/drivers/char/ipmi/ipmi_si_platform.c +++ b/drivers/char/ipmi/ipmi_si_platform.c @@ -19,6 +19,7 @@ #include "ipmi_si.h" #include "ipmi_dmi.h"
+static bool platform_registered; static bool si_tryplatform = true; #ifdef CONFIG_ACPI static bool si_tryacpi = true; @@ -469,9 +470,12 @@ void ipmi_si_platform_init(void) int rv = platform_driver_register(&ipmi_platform_driver); if (rv) pr_err("Unable to register driver: %d\n", rv); + else + platform_registered = true; }
void ipmi_si_platform_shutdown(void) { - platform_driver_unregister(&ipmi_platform_driver); + if (platform_registered) + platform_driver_unregister(&ipmi_platform_driver); }
[ Upstream commit d8c2869300ab5f7a19bf6f5a04fe473c5c9887e3 ]
Check on called function's returned value for error and return 0 on success or a negative errno value on error instead of a boolean value.
Signed-off-by: Quentin Deslandes quentin.deslandes@itdev.co.uk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/staging/vt6656/main_usb.c | 42 ++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 14 deletions(-)
diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index ccafcc2c87ac..70433f756d8e 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -402,16 +402,19 @@ static void vnt_free_int_bufs(struct vnt_private *priv) kfree(priv->int_buf.data_buf); }
-static bool vnt_alloc_bufs(struct vnt_private *priv) +static int vnt_alloc_bufs(struct vnt_private *priv) { + int ret = 0; struct vnt_usb_send_context *tx_context; struct vnt_rcb *rcb; int ii;
for (ii = 0; ii < priv->num_tx_context; ii++) { tx_context = kmalloc(sizeof(*tx_context), GFP_KERNEL); - if (!tx_context) + if (!tx_context) { + ret = -ENOMEM; goto free_tx; + }
priv->tx_context[ii] = tx_context; tx_context->priv = priv; @@ -419,16 +422,20 @@ static bool vnt_alloc_bufs(struct vnt_private *priv)
/* allocate URBs */ tx_context->urb = usb_alloc_urb(0, GFP_KERNEL); - if (!tx_context->urb) + if (!tx_context->urb) { + ret = -ENOMEM; goto free_tx; + }
tx_context->in_use = false; }
for (ii = 0; ii < priv->num_rcb; ii++) { priv->rcb[ii] = kzalloc(sizeof(*priv->rcb[ii]), GFP_KERNEL); - if (!priv->rcb[ii]) + if (!priv->rcb[ii]) { + ret = -ENOMEM; goto free_rx_tx; + }
rcb = priv->rcb[ii];
@@ -436,39 +443,46 @@ static bool vnt_alloc_bufs(struct vnt_private *priv)
/* allocate URBs */ rcb->urb = usb_alloc_urb(0, GFP_KERNEL); - if (!rcb->urb) + if (!rcb->urb) { + ret = -ENOMEM; goto free_rx_tx; + }
rcb->skb = dev_alloc_skb(priv->rx_buf_sz); - if (!rcb->skb) + if (!rcb->skb) { + ret = -ENOMEM; goto free_rx_tx; + }
rcb->in_use = false;
/* submit rx urb */ - if (vnt_submit_rx_urb(priv, rcb)) + ret = vnt_submit_rx_urb(priv, rcb); + if (ret) goto free_rx_tx; }
priv->interrupt_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!priv->interrupt_urb) + if (!priv->interrupt_urb) { + ret = -ENOMEM; goto free_rx_tx; + }
priv->int_buf.data_buf = kmalloc(MAX_INTERRUPT_SIZE, GFP_KERNEL); if (!priv->int_buf.data_buf) { - usb_free_urb(priv->interrupt_urb); - goto free_rx_tx; + ret = -ENOMEM; + goto free_rx_tx_urb; }
- return true; + return 0;
+free_rx_tx_urb: + usb_free_urb(priv->interrupt_urb); free_rx_tx: vnt_free_rx_bufs(priv); - free_tx: vnt_free_tx_bufs(priv); - - return false; + return ret; }
static void vnt_tx_80211(struct ieee80211_hw *hw,
[ Upstream commit 3c6b8625dde82600fd03ad1fcba223f1303ee535 ]
When unloading the bochs-drm driver, a warning message is printed by drm_mode_config_cleanup() because a reference is still held to one of the drm_connector structs.
Correct this by calling drm_atomic_helper_shutdown() in bochs_pci_remove().
Fixes: 6579c39594ae ("drm/bochs: atomic: switch planes to atomic, wire up helpers.") Signed-off-by: Sam Bobroff sbobroff@linux.ibm.com Link: http://patchwork.freedesktop.org/patch/msgid/93b363ad62f4938d9ddf3e05b2a61e3... Signed-off-by: Gerd Hoffmann kraxel@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bochs/bochs_drv.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/bochs/bochs_drv.c b/drivers/gpu/drm/bochs/bochs_drv.c index b86cc705138c..d8b945596b09 100644 --- a/drivers/gpu/drm/bochs/bochs_drv.c +++ b/drivers/gpu/drm/bochs/bochs_drv.c @@ -7,6 +7,7 @@ #include <linux/slab.h> #include <drm/drm_fb_helper.h> #include <drm/drm_probe_helper.h> +#include <drm/drm_atomic_helper.h>
#include "bochs.h"
@@ -171,6 +172,7 @@ static void bochs_pci_remove(struct pci_dev *pdev) { struct drm_device *dev = pci_get_drvdata(pdev);
+ drm_atomic_helper_shutdown(dev); drm_dev_unregister(dev); bochs_unload(dev); drm_dev_put(dev);
[ Upstream commit 561759292774707b71ee61aecc07724905bb7ef1 ]
If the device rejects the control transfer to enable device-initiated U1/U2 entry, then the device will not initiate U1/U2 transition. To improve the performance, the downstream port should not initate transition to U1/U2 to avoid the delay from the device link command response (no packet can be transmitted while waiting for a response from the device). If the device has some quirks and does not implement U1/U2, it may reject all the link state change requests, and the downstream port may resend and flood the bus with more requests. This will affect the device performance even further. This patch disables the hub-initated U1/U2 if the device-initiated U1/U2 entry fails.
Reference: USB 3.2 spec 7.2.4.2.3
Signed-off-by: Thinh Nguyen thinhn@synopsys.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/core/hub.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-)
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 2c8e60c7dbd8..2844366dc173 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -4002,6 +4002,9 @@ static int usb_set_lpm_timeout(struct usb_device *udev, * control transfers to set the hub timeout or enable device-initiated U1/U2 * will be successful. * + * If the control transfer to enable device-initiated U1/U2 entry fails, then + * hub-initiated U1/U2 will be disabled. + * * If we cannot set the parent hub U1/U2 timeout, we attempt to let the xHCI * driver know about it. If that call fails, it should be harmless, and just * take up more slightly more bus bandwidth for unnecessary U1/U2 exit latency. @@ -4056,23 +4059,24 @@ static void usb_enable_link_state(struct usb_hcd *hcd, struct usb_device *udev, * host know that this link state won't be enabled. */ hcd->driver->disable_usb3_lpm_timeout(hcd, udev, state); - } else { - /* Only a configured device will accept the Set Feature - * U1/U2_ENABLE - */ - if (udev->actconfig) - usb_set_device_initiated_lpm(udev, state, true); + return; + }
- /* As soon as usb_set_lpm_timeout(timeout) returns 0, the - * hub-initiated LPM is enabled. Thus, LPM is enabled no - * matter the result of usb_set_device_initiated_lpm(). - * The only difference is whether device is able to initiate - * LPM. - */ + /* Only a configured device will accept the Set Feature + * U1/U2_ENABLE + */ + if (udev->actconfig && + usb_set_device_initiated_lpm(udev, state, true) == 0) { if (state == USB3_LPM_U1) udev->usb3_lpm_u1_enabled = 1; else if (state == USB3_LPM_U2) udev->usb3_lpm_u2_enabled = 1; + } else { + /* Don't request U1/U2 entry if the device + * cannot transition to U1/U2. + */ + usb_set_lpm_timeout(udev, state, 0); + hcd->driver->disable_usb3_lpm_timeout(hcd, udev, state); } }
[ Upstream commit 35240ba26a932b279a513f66fa4cabfd7af55221 ]
Current calculator doesn't do it' job quite correct. First of all the max310x baud-rates generator supports the divisor being less than 16. In this case the x2/x4 modes can be used to double or quadruple the reference frequency. But the current baud-rate setter function just filters all these modes out by the first condition and setups these modes only if there is a clocks-baud division remainder. The former doesn't seem right at all, since enabling the x2/x4 modes causes the line noise tolerance reduction and should be only used as a last resort to enable a requested too high baud-rate.
Finally the fraction is supposed to be calculated from D = Fref/(c*baud) formulae, but not from D % 16, which causes the precision loss. So to speak the current baud-rate calculator code works well only if the baud perfectly fits to the uart reference input frequency.
Lets fix the calculator by implementing the algo fully compliant with the fractional baud-rate generator described in the datasheet: D = Fref / (c*baud), where c={16,8,4} is the x1/x2/x4 rate mode respectively, Fref - reference input frequency. The divisor fraction is calculated from the same formulae, but making sure it is found with a resolution of 0.0625 (four bits).
Signed-off-by: Serge Semin fancer.lancer@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/max310x.c | 51 ++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 20 deletions(-)
diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c index e5aebbf5f302..c3afd128b8fc 100644 --- a/drivers/tty/serial/max310x.c +++ b/drivers/tty/serial/max310x.c @@ -496,37 +496,48 @@ static bool max310x_reg_precious(struct device *dev, unsigned int reg)
static int max310x_set_baud(struct uart_port *port, int baud) { - unsigned int mode = 0, clk = port->uartclk, div = clk / baud; + unsigned int mode = 0, div = 0, frac = 0, c = 0, F = 0;
- /* Check for minimal value for divider */ - if (div < 16) - div = 16; - - if (clk % baud && (div / 16) < 0x8000) { + /* + * Calculate the integer divisor first. Select a proper mode + * in case if the requested baud is too high for the pre-defined + * clocks frequency. + */ + div = port->uartclk / baud; + if (div < 8) { + /* Mode x4 */ + c = 4; + mode = MAX310X_BRGCFG_4XMODE_BIT; + } else if (div < 16) { /* Mode x2 */ + c = 8; mode = MAX310X_BRGCFG_2XMODE_BIT; - clk = port->uartclk * 2; - div = clk / baud; - - if (clk % baud && (div / 16) < 0x8000) { - /* Mode x4 */ - mode = MAX310X_BRGCFG_4XMODE_BIT; - clk = port->uartclk * 4; - div = clk / baud; - } + } else { + c = 16; }
- max310x_port_write(port, MAX310X_BRGDIVMSB_REG, (div / 16) >> 8); - max310x_port_write(port, MAX310X_BRGDIVLSB_REG, div / 16); - max310x_port_write(port, MAX310X_BRGCFG_REG, (div % 16) | mode); + /* Calculate the divisor in accordance with the fraction coefficient */ + div /= c; + F = c*baud; + + /* Calculate the baud rate fraction */ + if (div > 0) + frac = (16*(port->uartclk % F)) / F; + else + div = 1; + + max310x_port_write(port, MAX310X_BRGDIVMSB_REG, div >> 8); + max310x_port_write(port, MAX310X_BRGDIVLSB_REG, div); + max310x_port_write(port, MAX310X_BRGCFG_REG, frac | mode);
- return DIV_ROUND_CLOSEST(clk, div); + /* Return the actual baud rate we just programmed */ + return (16*port->uartclk) / (c*(16*div + frac)); }
static int max310x_update_best_err(unsigned long f, long *besterr) { /* Use baudrate 115200 for calculate error */ - long err = f % (115200 * 16); + long err = f % (460800 * 16);
if ((*besterr < 0) || (*besterr > err)) { *besterr = err;
[ Upstream commit 3c89c70634bb0b6f48512de873e7a45c7e1fbaa5 ]
The call to of_parse_phandle returns a node pointer with refcount incremented thus it must be explicitly decremented after the last usage.
Detected by coccinelle with the following warnings: ./drivers/pinctrl/pinctrl-rockchip.c:3221:2-8: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 3196, but without a corresponding object release within this function. ./drivers/pinctrl/pinctrl-rockchip.c:3223:1-7: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 3196, but without a corresponding object release within this function.
Signed-off-by: Wen Yang wen.yang99@zte.com.cn Cc: Linus Walleij linus.walleij@linaro.org Cc: Heiko Stuebner heiko@sntech.de Cc: linux-gpio@vger.kernel.org Cc: linux-rockchip@lists.infradead.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/pinctrl-rockchip.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index 807a3263d849..62a622159006 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -3204,6 +3204,7 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank, base, &rockchip_regmap_config); } + of_node_put(node); }
bank->irq = irq_of_parse_and_map(bank->of_node, 0);
[ Upstream commit 06aaa3d066db87e8478522d910285141d44b1e58 ]
SMC relocation can also be activated earlier by the bootloader, so the driver's behaviour cannot rely on selected kernel config.
When the SMC is relocated, CPM_CR_INIT_TRX cannot be used.
But the only thing CPM_CR_INIT_TRX does is to clear the rstate and tstate registers, so this can be done manually, even when SMC is not relocated.
Signed-off-by: Christophe Leroy christophe.leroy@c-s.fr Fixes: 9ab921201444 ("cpm_uart: fix non-console port startup bug") Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/cpm_uart/cpm_uart_core.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_core.c b/drivers/tty/serial/cpm_uart/cpm_uart_core.c index b929c7ae3a27..7bab9a3eda92 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/tty/serial/cpm_uart/cpm_uart_core.c @@ -407,7 +407,16 @@ static int cpm_uart_startup(struct uart_port *port) clrbits16(&pinfo->sccp->scc_sccm, UART_SCCM_RX); } cpm_uart_initbd(pinfo); - cpm_line_cr_cmd(pinfo, CPM_CR_INIT_TRX); + if (IS_SMC(pinfo)) { + out_be32(&pinfo->smcup->smc_rstate, 0); + out_be32(&pinfo->smcup->smc_tstate, 0); + out_be16(&pinfo->smcup->smc_rbptr, + in_be16(&pinfo->smcup->smc_rbase)); + out_be16(&pinfo->smcup->smc_tbptr, + in_be16(&pinfo->smcup->smc_tbase)); + } else { + cpm_line_cr_cmd(pinfo, CPM_CR_INIT_TRX); + } } /* Install interrupt handler. */ retval = request_irq(port->irq, cpm_uart_int, 0, "cpm_uart", port); @@ -861,16 +870,14 @@ static void cpm_uart_init_smc(struct uart_cpm_port *pinfo) (u8 __iomem *)pinfo->tx_bd_base - DPRAM_BASE);
/* - * In case SMC1 is being relocated... + * In case SMC is being relocated... */ -#if defined (CONFIG_I2C_SPI_SMC1_UCODE_PATCH) out_be16(&up->smc_rbptr, in_be16(&pinfo->smcup->smc_rbase)); out_be16(&up->smc_tbptr, in_be16(&pinfo->smcup->smc_tbase)); out_be32(&up->smc_rstate, 0); out_be32(&up->smc_tstate, 0); out_be16(&up->smc_brkcr, 1); /* number of break chars */ out_be16(&up->smc_brkec, 0); -#endif
/* Set up the uart parameters in the * parameter ram. @@ -884,8 +891,6 @@ static void cpm_uart_init_smc(struct uart_cpm_port *pinfo) out_be16(&up->smc_brkec, 0); out_be16(&up->smc_brkcr, 1);
- cpm_line_cr_cmd(pinfo, CPM_CR_INIT_TRX); - /* Set UART mode, 8 bit, no parity, one stop. * Enable receive and transmit. */
[ Upstream commit 5dae2d39074dde941cc3150dcbb7840d88179743 ]
As Ju Hyung reported:
" I was semi-forced today to use the new kernel and test f2fs.
My Ubuntu initramfs got a bit wonky and I had to boot into live CD and fix some stuffs. The live CD was using 4.15 kernel, and just mounting the f2fs partition there corrupted f2fs and my 4.19(with 5.1-rc1-4.19 f2fs-stable merged) refused to mount with "SIT is corrupted node" message.
I used the latest f2fs-tools sent by Chao including "fsck.f2fs: fix to repair cp_loads blocks at correct position"
It spit out 140M worth of output, but at least I didn't have to run it twice. Everything returned "Ok" in the 2nd run. The new log is at http://arter97.com/f2fs/final
After fixing the image, I used my 4.19 kernel with 5.2-rc1-4.19 f2fs-stable merged and it mounted.
But, I got this: [ 1.047791] F2FS-fs (nvme0n1p3): layout of large_nat_bitmap is deprecated, run fsck to repair, chksum_offset: 4092 [ 1.081307] F2FS-fs (nvme0n1p3): Found nat_bits in checkpoint [ 1.161520] F2FS-fs (nvme0n1p3): recover fsync data on readonly fs [ 1.162418] F2FS-fs (nvme0n1p3): Mounted with checkpoint version = 761c7e00
But after doing a reboot, the message is gone: [ 1.098423] F2FS-fs (nvme0n1p3): Found nat_bits in checkpoint [ 1.177771] F2FS-fs (nvme0n1p3): recover fsync data on readonly fs [ 1.178365] F2FS-fs (nvme0n1p3): Mounted with checkpoint version = 761c7eda
I'm not exactly sure why the kernel detected that I'm still using the old layout on the first boot. Maybe fsck didn't fix it properly, or the check from the kernel is improper. "
Although we have rebuild the old deprecated checkpoint with new layout during repair, we only repair last checkpoint park, the other old one is remained.
Once the image was mounted, we will 1) sanity check layout and 2) decide which checkpoint park to use according to cp_ver. So that we will print reported message unnecessarily at step 1), to avoid it, we simply move layout check into f2fs_sanity_check_ckpt() after step 2).
Reported-by: Park Ju Hyung qkrwngud825@gmail.com Signed-off-by: Chao Yu yuchao0@huawei.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/checkpoint.c | 11 ----------- fs/f2fs/super.c | 9 +++++++++ 2 files changed, 9 insertions(+), 11 deletions(-)
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index ed70b68b2b38..d0539ddad6e2 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -832,17 +832,6 @@ static int get_checkpoint_version(struct f2fs_sb_info *sbi, block_t cp_addr, return -EINVAL; }
- if (__is_set_ckpt_flags(*cp_block, CP_LARGE_NAT_BITMAP_FLAG)) { - if (crc_offset != CP_MIN_CHKSUM_OFFSET) { - f2fs_put_page(*cp_page, 1); - f2fs_msg(sbi->sb, KERN_WARNING, - "layout of large_nat_bitmap is deprecated, " - "run fsck to repair, chksum_offset: %zu", - crc_offset); - return -EINVAL; - } - } - crc = f2fs_checkpoint_chksum(sbi, *cp_block); if (crc != cur_cp_crc(*cp_block)) { f2fs_put_page(*cp_page, 1); diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 6b959bbb336a..856f9081c599 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -2718,6 +2718,15 @@ int f2fs_sanity_check_ckpt(struct f2fs_sb_info *sbi) return 1; }
+ if (__is_set_ckpt_flags(ckpt, CP_LARGE_NAT_BITMAP_FLAG) && + le32_to_cpu(ckpt->checksum_offset) != CP_MIN_CHKSUM_OFFSET) { + f2fs_msg(sbi->sb, KERN_WARNING, + "layout of large_nat_bitmap is deprecated, " + "run fsck to repair, chksum_offset: %u", + le32_to_cpu(ckpt->checksum_offset)); + return 1; + } + if (unlikely(f2fs_cp_error(sbi))) { f2fs_msg(sbi->sb, KERN_ERR, "A bug case: need to run fsck"); return 1;
[ Upstream commit 5ca4a094ba7e1369363dcbcbde8baf06ddcdc2d1 ]
pdcptr and seqptr aren't necessarily valid, check them before trying to unmap them.
Changes in v2: - None
Cc: Jordan Crouse jcrouse@codeaurora.org Reviewed-by: Jordan Crouse jcrouse@codeaurora.org Signed-off-by: Sean Paul seanpaul@chromium.org Link: https://patchwork.freedesktop.org/patch/msgid/20190523171653.138678-3-sean@p... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index 38e2cfa9cec7..418bb08bbed7 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -504,8 +504,10 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu) wmb();
err: - devm_iounmap(gmu->dev, pdcptr); - devm_iounmap(gmu->dev, seqptr); + if (!IS_ERR_OR_NULL(pdcptr)) + devm_iounmap(gmu->dev, pdcptr); + if (!IS_ERR_OR_NULL(seqptr)) + devm_iounmap(gmu->dev, seqptr); }
/*
[ Upstream commit 2cd0e54489e65b8e22124a8b053aff40815487f7 ]
If platform_driver_register() fails from init_ipmi_ssif(), platform_driver_unregister() called unconditionally will trigger following warning,
ipmi_ssif: Unable to register driver: -12 ------------[ cut here ]------------ Unexpected driver unregister! WARNING: CPU: 1 PID: 6305 at drivers/base/driver.c:193 driver_unregister+0x60/0x70 drivers/base/driver.c:193
Fix it by adding platform_registered variable, only unregister platform driver when it is already successfully registered.
Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Kefeng Wang wangkefeng.wang@huawei.com Message-Id: 20190524143724.43218-1-wangkefeng.wang@huawei.com
Signed-off-by: Corey Minyard cminyard@mvista.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/char/ipmi/ipmi_ssif.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c index cf8156d6bc07..305fa5054274 100644 --- a/drivers/char/ipmi/ipmi_ssif.c +++ b/drivers/char/ipmi/ipmi_ssif.c @@ -303,6 +303,7 @@ struct ssif_info { ((unsigned int) atomic_read(&(ssif)->stats[SSIF_STAT_ ## stat]))
static bool initialized; +static bool platform_registered;
static void return_hosed_msg(struct ssif_info *ssif_info, struct ipmi_smi_msg *msg); @@ -2088,6 +2089,8 @@ static int init_ipmi_ssif(void) rv = platform_driver_register(&ipmi_driver); if (rv) pr_err("Unable to register driver: %d\n", rv); + else + platform_registered = true; }
ssif_i2c_driver.address_list = ssif_address_list(); @@ -2111,7 +2114,7 @@ static void cleanup_ipmi_ssif(void)
kfree(ssif_i2c_driver.address_list);
- if (ssif_trydmi) + if (ssif_trydmi && platform_registered) platform_driver_unregister(&ipmi_driver);
free_ssif_clients();
[ Upstream commit 1352c779cb74d427f4150cbe779a2f7886f70cae ]
[Why] An assertion is thrown when using SURFACE_PIXEL_FORMAT_GRPH_RGB565 formats on DCE since the prescale_params->scale wasn't being filled.
Found by a dmesg-fail when running the igt@kms_plane@pixel-format-pipe-a-planes test on Baffin.
[How] Fill in the scale parameter.
Signed-off-by: Nicholas Kazlauskas nicholas.kazlauskas@amd.com Reviewed-by: Roman Li Roman.Li@amd.com Acked-by: Bhawanpreet Lakha Bhawanpreet.Lakha@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index 7ac50ab1b762..7d7e93c87c28 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -242,6 +242,9 @@ static void build_prescale_params(struct ipp_prescale_params *prescale_params, prescale_params->mode = IPP_PRESCALE_MODE_FIXED_UNSIGNED;
switch (plane_state->format) { + case SURFACE_PIXEL_FORMAT_GRPH_RGB565: + prescale_params->scale = 0x2082; + break; case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888: case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888: prescale_params->scale = 0x2020;
[ Upstream commit 4cd75ff096f4ef49c343093b52a952f27aba7796 ]
[Why] There is a scenario that causes eDP to become blank if there are multiple displays connected, and the external display is set as the primary display such that the first flip comes to the external display.
In this scenario, we call our optimize function before the eDP even has a chance to flip.
[How] There is a check that prevents bandwidth optimize from occurring before first flip is complete on the seamless boot display. But actually it assumed the seamless boot display is the first one to flip. But in this scenario it is not. Modify the check to ensure the steam with the seamless boot flag set is the one that has completed the first flip.
Signed-off-by: Anthony Koo anthony.koo@amd.com Reviewed-by: Aric Cyr Aric.Cyr@amd.com Acked-by: Bhawanpreet Lakha Bhawanpreet.Lakha@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/core/dc.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 18c775a950cc..ee6b646180b6 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -1138,9 +1138,6 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c const struct dc_link *link = context->streams[i]->link; struct dc_stream_status *status;
- if (context->streams[i]->apply_seamless_boot_optimization) - context->streams[i]->apply_seamless_boot_optimization = false; - if (!context->streams[i]->mode_changed) continue;
@@ -1792,10 +1789,15 @@ static void commit_planes_for_stream(struct dc *dc, if (dc->optimize_seamless_boot && surface_count > 0) { /* Optimize seamless boot flag keeps clocks and watermarks high until * first flip. After first flip, optimization is required to lower - * bandwidth. + * bandwidth. Important to note that it is expected UEFI will + * only light up a single display on POST, therefore we only expect + * one stream with seamless boot flag set. */ - dc->optimize_seamless_boot = false; - dc->optimized_required = true; + if (stream->apply_seamless_boot_optimization) { + stream->apply_seamless_boot_optimization = false; + dc->optimize_seamless_boot = false; + dc->optimized_required = true; + } }
if (update_type == UPDATE_TYPE_FULL && !dc->optimize_seamless_boot) {
[ Upstream commit 606ec90fc2266284f584a96ebf7f874589f56251 ]
The driver checks for gmu->mmio as a sign that the device has been initialized, however there are failures in probe below the mmio init. If one of those is hit, mmio will be non-null but freed.
In that case, a6xx_gmu_probe will return an error to a6xx_gpu_init which will in turn call a6xx_gmu_remove which checks gmu->mmio and tries to free resources for a second time. This causes a great boom.
Fix this by adding an initialized member to gmu which is set on successful probe and cleared on removal.
Changes in v2: - None
Cc: Jordan Crouse jcrouse@codeaurora.org Reviewed-by: Jordan Crouse jcrouse@codeaurora.org Signed-off-by: Sean Paul seanpaul@chromium.org Link: https://patchwork.freedesktop.org/patch/msgid/20190523171653.138678-1-sean@p... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 14 +++++++++----- drivers/gpu/drm/msm/adreno/a6xx_gmu.h | 1 + 2 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index 418bb08bbed7..6910d0468e3c 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -74,7 +74,7 @@ bool a6xx_gmu_sptprac_is_on(struct a6xx_gmu *gmu) u32 val;
/* This can be called from gpu state code so make sure GMU is valid */ - if (IS_ERR_OR_NULL(gmu->mmio)) + if (!gmu->initialized) return false;
val = gmu_read(gmu, REG_A6XX_GMU_SPTPRAC_PWR_CLK_STATUS); @@ -90,7 +90,7 @@ bool a6xx_gmu_gx_is_on(struct a6xx_gmu *gmu) u32 val;
/* This can be called from gpu state code so make sure GMU is valid */ - if (IS_ERR_OR_NULL(gmu->mmio)) + if (!gmu->initialized) return false;
val = gmu_read(gmu, REG_A6XX_GMU_SPTPRAC_PWR_CLK_STATUS); @@ -697,7 +697,7 @@ int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu) struct a6xx_gmu *gmu = &a6xx_gpu->gmu; int status, ret;
- if (WARN(!gmu->mmio, "The GMU is not set up yet\n")) + if (WARN(!gmu->initialized, "The GMU is not set up yet\n")) return 0;
gmu->hung = false; @@ -767,7 +767,7 @@ bool a6xx_gmu_isidle(struct a6xx_gmu *gmu) { u32 reg;
- if (!gmu->mmio) + if (!gmu->initialized) return true;
reg = gmu_read(gmu, REG_A6XX_GPU_GMU_AO_GPU_CX_BUSY_STATUS); @@ -1229,7 +1229,7 @@ void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu) { struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
- if (IS_ERR_OR_NULL(gmu->mmio)) + if (!gmu->initialized) return;
a6xx_gmu_stop(a6xx_gpu); @@ -1247,6 +1247,8 @@ void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu) iommu_detach_device(gmu->domain, gmu->dev);
iommu_domain_free(gmu->domain); + + gmu->initialized = false; }
int a6xx_gmu_probe(struct a6xx_gpu *a6xx_gpu, struct device_node *node) @@ -1311,6 +1313,8 @@ int a6xx_gmu_probe(struct a6xx_gpu *a6xx_gpu, struct device_node *node) /* Set up the HFI queues */ a6xx_hfi_init(gmu);
+ gmu->initialized = true; + return 0; err: a6xx_gmu_memory_free(gmu, gmu->hfi); diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h index bedd8e6a63aa..39a26dd63674 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h @@ -75,6 +75,7 @@ struct a6xx_gmu {
struct a6xx_hfi_queue queues[2];
+ bool initialized; bool hung; };
[ Upstream commit e371e19c10a264bd72c2ff1d21e2167b994710d1 ]
[Why] When x or y is negative we set the x and y values to 0 and compensate with a positive cursor hotspot in DM since DC expects positive cursor values.
When x or y is less than or equal to the maximum cursor width or height the cursor hotspot is clamped so the hotspot doesn't exceed the cursor size:
if (x < 0) { xorigin = min(-x, amdgpu_crtc->max_cursor_width - 1); x = 0; }
if (y < 0) { yorigin = min(-y, amdgpu_crtc->max_cursor_height - 1); y = 0; }
This incorrectly forces the cursor to be at least 1 pixel on the screen in either direction when x or y is sufficiently negative.
[How] Just disable the cursor when it goes far enough off the screen in one of these directions.
This fixes kms_cursor_crc@cursor-256x256-offscreen.
Signed-off-by: Nicholas Kazlauskas nicholas.kazlauskas@amd.com Reviewed-by: Sun peng Li Sunpeng.Li@amd.com Acked-by: Bhawanpreet Lakha Bhawanpreet.Lakha@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index ab7c5c3004ee..fa268dd736f4 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4952,12 +4952,12 @@ static int get_cursor_position(struct drm_plane *plane, struct drm_crtc *crtc, int x, y; int xorigin = 0, yorigin = 0;
- if (!crtc || !plane->state->fb) { - position->enable = false; - position->x = 0; - position->y = 0; + position->enable = false; + position->x = 0; + position->y = 0; + + if (!crtc || !plane->state->fb) return 0; - }
if ((plane->state->crtc_w > amdgpu_crtc->max_cursor_width) || (plane->state->crtc_h > amdgpu_crtc->max_cursor_height)) { @@ -4971,6 +4971,10 @@ static int get_cursor_position(struct drm_plane *plane, struct drm_crtc *crtc, x = plane->state->crtc_x; y = plane->state->crtc_y;
+ if (x <= -amdgpu_crtc->max_cursor_width || + y <= -amdgpu_crtc->max_cursor_height) + return 0; + if (crtc->primary->state) { /* avivo cursor are offset into the total surface */ x += crtc->primary->state->src_x >> 16;
[ Upstream commit 1894478ad1f8fd7366edc5cee49ee9caea0e3d52 ]
[Why] In fill_plane_buffer_attributes() we calculate chroma/luma assuming that the surface_pixel_format is always valid. If it's not the case, there's a risk of divide by zero error.
[How] Check if format valid before calculating pixel format attributes
Signed-off-by: Roman Li Roman.Li@amd.com Reviewed-by: David Francis David.Francis@amd.com Acked-by: Bhawanpreet Lakha Bhawanpreet.Lakha@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index fa268dd736f4..31530bfd002a 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -2592,7 +2592,7 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev, address->type = PLN_ADDR_TYPE_GRAPHICS; address->grph.addr.low_part = lower_32_bits(afb->address); address->grph.addr.high_part = upper_32_bits(afb->address); - } else { + } else if (format < SURFACE_PIXEL_FORMAT_INVALID) { uint64_t chroma_addr = afb->address + fb->offsets[1];
plane_size->video.luma_size.x = 0;
[ Upstream commit dd68722c427d5b33420dce0ed0c44b4881e0a416 ]
Need to reserve space for the shared eviction fence when initializing a KFD VM.
Signed-off-by: Felix Kuehling Felix.Kuehling@amd.com Acked-by: Christian König christian.koenig@amd.com Reviewed-by: Harish Kasiviswanathan Harish.Kasiviswanathan@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c index a6e5184d436c..4b192e0ce92f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c @@ -896,6 +896,9 @@ static int init_kfd_vm(struct amdgpu_vm *vm, void **process_info, AMDGPU_FENCE_OWNER_KFD, false); if (ret) goto wait_pd_fail; + ret = reservation_object_reserve_shared(vm->root.base.bo->tbo.resv, 1); + if (ret) + goto reserve_shared_fail; amdgpu_bo_fence(vm->root.base.bo, &vm->process_info->eviction_fence->base, true); amdgpu_bo_unreserve(vm->root.base.bo); @@ -909,6 +912,7 @@ static int init_kfd_vm(struct amdgpu_vm *vm, void **process_info,
return 0;
+reserve_shared_fail: wait_pd_fail: validate_pd_fail: amdgpu_bo_unreserve(vm->root.base.bo);
[ Upstream commit 040d2bb318d1aea4f28cc22504b44e446666c86e ]
As Hagbard Celine reported:
[ 615.697824] INFO: task kworker/u16:5:344 blocked for more than 120 seconds. [ 615.697825] Not tainted 5.0.15-gentoo-f2fslog #4 [ 615.697826] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. [ 615.697827] kworker/u16:5 D 0 344 2 0x80000000 [ 615.697831] Workqueue: writeback wb_workfn (flush-259:0) [ 615.697832] Call Trace: [ 615.697836] ? __schedule+0x2c5/0x8b0 [ 615.697839] schedule+0x32/0x80 [ 615.697841] schedule_preempt_disabled+0x14/0x20 [ 615.697842] __mutex_lock.isra.8+0x2ba/0x4d0 [ 615.697845] ? log_store+0xf5/0x260 [ 615.697848] f2fs_write_data_pages+0x133/0x320 [ 615.697851] ? trace_hardirqs_on+0x2c/0xe0 [ 615.697854] do_writepages+0x41/0xd0 [ 615.697857] __filemap_fdatawrite_range+0x81/0xb0 [ 615.697859] f2fs_sync_dirty_inodes+0x1dd/0x200 [ 615.697861] f2fs_balance_fs_bg+0x2a7/0x2c0 [ 615.697863] ? up_read+0x5/0x20 [ 615.697865] ? f2fs_do_write_data_page+0x2cb/0x940 [ 615.697867] f2fs_balance_fs+0xe5/0x2c0 [ 615.697869] __write_data_page+0x1c8/0x6e0 [ 615.697873] f2fs_write_cache_pages+0x1e0/0x450 [ 615.697878] f2fs_write_data_pages+0x14b/0x320 [ 615.697880] ? trace_hardirqs_on+0x2c/0xe0 [ 615.697883] do_writepages+0x41/0xd0 [ 615.697885] __filemap_fdatawrite_range+0x81/0xb0 [ 615.697887] f2fs_sync_dirty_inodes+0x1dd/0x200 [ 615.697889] f2fs_balance_fs_bg+0x2a7/0x2c0 [ 615.697891] f2fs_write_node_pages+0x51/0x220 [ 615.697894] do_writepages+0x41/0xd0 [ 615.697897] __writeback_single_inode+0x3d/0x3d0 [ 615.697899] writeback_sb_inodes+0x1e8/0x410 [ 615.697902] __writeback_inodes_wb+0x5d/0xb0 [ 615.697904] wb_writeback+0x28f/0x340 [ 615.697906] ? cpumask_next+0x16/0x20 [ 615.697908] wb_workfn+0x33e/0x420 [ 615.697911] process_one_work+0x1a1/0x3d0 [ 615.697913] worker_thread+0x30/0x380 [ 615.697915] ? process_one_work+0x3d0/0x3d0 [ 615.697916] kthread+0x116/0x130 [ 615.697918] ? kthread_create_worker_on_cpu+0x70/0x70 [ 615.697921] ret_from_fork+0x3a/0x50
There is still deadloop in below condition:
d A - do_writepages - f2fs_write_node_pages - f2fs_balance_fs_bg - f2fs_sync_dirty_inodes - f2fs_write_cache_pages - mutex_lock(&sbi->writepages) -- lock once - __write_data_page - f2fs_balance_fs_bg - f2fs_sync_dirty_inodes - f2fs_write_data_pages - mutex_lock(&sbi->writepages) -- lock again
Thread A Thread B - do_writepages - f2fs_write_node_pages - f2fs_balance_fs_bg - f2fs_sync_dirty_inodes - .cp_task = current - f2fs_sync_dirty_inodes - .cp_task = current - filemap_fdatawrite - .cp_task = NULL - filemap_fdatawrite - f2fs_write_cache_pages - enter f2fs_balance_fs_bg since .cp_task is NULL - .cp_task = NULL
Change as below to avoid this: - add condition to avoid holding .writepages mutex lock in path of data flush - introduce mutex lock sbi.flush_lock to exclude concurrent data flush in background.
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/data.c | 3 +++ fs/f2fs/f2fs.h | 1 + fs/f2fs/segment.c | 4 ++++ fs/f2fs/super.c | 1 + 4 files changed, 9 insertions(+)
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index eda4181d2092..923923603a7d 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -2262,6 +2262,9 @@ static inline bool __should_serialize_io(struct inode *inode, return false; if (IS_NOQUOTA(inode)) return false; + /* to avoid deadlock in path of data flush */ + if (F2FS_I(inode)->cp_task) + return false; if (wbc->sync_mode != WB_SYNC_ALL) return true; if (get_dirty_pages(inode) >= SM_I(F2FS_I_SB(inode))->min_seq_blocks) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 06b89a9862ab..d1b64cb77326 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1207,6 +1207,7 @@ struct f2fs_sb_info { /* for inode management */ struct list_head inode_list[NR_INODE_TYPE]; /* dirty inode list */ spinlock_t inode_lock[NR_INODE_TYPE]; /* for dirty inode list lock */ + struct mutex flush_lock; /* for flush exclusion */
/* for extent tree cache */ struct radix_tree_root extent_tree_root;/* cache extent cache entries */ diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 8dee063c833f..a96b9e964733 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -546,9 +546,13 @@ void f2fs_balance_fs_bg(struct f2fs_sb_info *sbi) if (test_opt(sbi, DATA_FLUSH)) { struct blk_plug plug;
+ mutex_lock(&sbi->flush_lock); + blk_start_plug(&plug); f2fs_sync_dirty_inodes(sbi, FILE_INODE); blk_finish_plug(&plug); + + mutex_unlock(&sbi->flush_lock); } f2fs_sync_fs(sbi->sb, true); stat_inc_bg_cp_count(sbi->stat_info); diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 856f9081c599..4b47ac994daf 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -3296,6 +3296,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) INIT_LIST_HEAD(&sbi->inode_list[i]); spin_lock_init(&sbi->inode_lock[i]); } + mutex_init(&sbi->flush_lock);
f2fs_init_extent_cache_info(sbi);
[ Upstream commit fe2b5323d2c3cedaa3bf943dc7a0d233c853c914 ]
it requires to initialize HDP_NONSURFACE_BASE, so as to avoid using the value left by a previous VM under sriov scenario.
v2: it should not hurt baremetal, generalize it for both sriov and baremetal
Signed-off-by: Emily Deng Emily.Deng@amd.com Signed-off-by: Tiecheng Zhou Tiecheng.Zhou@amd.com Reviewed-by: Christian König christian.koenig@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c index 72837b8c7031..c2086eb00555 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c @@ -1163,6 +1163,9 @@ static int gmc_v9_0_gart_enable(struct amdgpu_device *adev) tmp = RREG32_SOC15(HDP, 0, mmHDP_HOST_PATH_CNTL); WREG32_SOC15(HDP, 0, mmHDP_HOST_PATH_CNTL, tmp);
+ WREG32_SOC15(HDP, 0, mmHDP_NONSURFACE_BASE, (adev->gmc.vram_start >> 8)); + WREG32_SOC15(HDP, 0, mmHDP_NONSURFACE_BASE_HI, (adev->gmc.vram_start >> 40)); + /* After HDP is initialized, flush HDP.*/ adev->nbio_funcs->hdp_flush(adev, NULL);
[ Upstream commit 1090d58d4815b1fcd95a80987391006c86398b4c ]
[Why] When disable driver, OS will set backlight optimization then do stop device. But this flag will cause driver to enable ABM when driver disabled.
[How] Send ABM disable command before destroy ABM construct
Signed-off-by: Paul Hsieh paul.hsieh@amd.com Reviewed-by: Anthony Koo Anthony.Koo@amd.com Acked-by: Bhawanpreet Lakha Bhawanpreet.Lakha@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/dce/dce_abm.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c index da96229db53a..2959c3c9390b 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c @@ -473,6 +473,8 @@ void dce_abm_destroy(struct abm **abm) { struct dce_abm *abm_dce = TO_DCE_ABM(*abm);
+ abm_dce->base.funcs->set_abm_immediate_disable(*abm); + kfree(abm_dce); *abm = NULL; }
[ Upstream commit e73390d181103a19e1111ec2f25559a0570e9fe0 ]
Free mqd_mem_obj it GTT buffer allocation for MQD+control stack fails.
Signed-off-by: Oak Zeng ozeng@amd.com Reviewed-by: Felix Kuehling Felix.Kuehling@amd.com Signed-off-by: Felix Kuehling Felix.Kuehling@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c index 9dbba609450e..8fe74b821b32 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c @@ -76,6 +76,7 @@ static int init_mqd(struct mqd_manager *mm, void **mqd, struct v9_mqd *m; struct kfd_dev *kfd = mm->dev;
+ *mqd_mem_obj = NULL; /* From V9, for CWSR, the control stack is located on the next page * boundary after the mqd, we will use the gtt allocation function * instead of sub-allocation function. @@ -93,8 +94,10 @@ static int init_mqd(struct mqd_manager *mm, void **mqd, } else retval = kfd_gtt_sa_allocate(mm->dev, sizeof(struct v9_mqd), mqd_mem_obj); - if (retval != 0) + if (retval) { + kfree(*mqd_mem_obj); return -ENOMEM; + }
m = (struct v9_mqd *) (*mqd_mem_obj)->cpu_ptr; addr = (*mqd_mem_obj)->gpu_addr;
[ Upstream commit 065e4bdfa1f3ab2884c110394d8b7e7ebe3b988c ]
Previous codes assumes there are two sdma engines. This is not true e.g., Raven only has 1 SDMA engine. Fix the issue by using sdma engine number info in device_info.
Signed-off-by: Oak Zeng Oak.Zeng@amd.com Reviewed-by: Felix Kuehling Felix.Kuehling@amd.com Signed-off-by: Felix Kuehling Felix.Kuehling@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../drm/amd/amdkfd/kfd_device_queue_manager.c | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index ae381450601c..afbaf6f5131e 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -1268,12 +1268,17 @@ int amdkfd_fence_wait_timeout(unsigned int *fence_addr, return 0; }
-static int unmap_sdma_queues(struct device_queue_manager *dqm, - unsigned int sdma_engine) +static int unmap_sdma_queues(struct device_queue_manager *dqm) { - return pm_send_unmap_queue(&dqm->packets, KFD_QUEUE_TYPE_SDMA, - KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0, false, - sdma_engine); + int i, retval = 0; + + for (i = 0; i < dqm->dev->device_info->num_sdma_engines; i++) { + retval = pm_send_unmap_queue(&dqm->packets, KFD_QUEUE_TYPE_SDMA, + KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0, false, i); + if (retval) + return retval; + } + return retval; }
/* dqm->lock mutex has to be locked before calling this function */ @@ -1312,10 +1317,8 @@ static int unmap_queues_cpsch(struct device_queue_manager *dqm, pr_debug("Before destroying queues, sdma queue count is : %u\n", dqm->sdma_queue_count);
- if (dqm->sdma_queue_count > 0) { - unmap_sdma_queues(dqm, 0); - unmap_sdma_queues(dqm, 1); - } + if (dqm->sdma_queue_count > 0) + unmap_sdma_queues(dqm);
retval = pm_send_unmap_queue(&dqm->packets, KFD_QUEUE_TYPE_COMPUTE, filter, filter_param, false, 0);
[ Upstream commit 9f1f1a2dab38d4ce87a13565cf4dc1b73bef3a5f ]
In drm_load_edid_firmware(), fwstr is allocated by kstrdup(). And fwstr is dereferenced in the following codes. However, memory allocation functions such as kstrdup() may fail and returns NULL. Dereferencing this null pointer may cause the kernel go wrong. Thus we should check this kstrdup() operation. Further, if kstrdup() returns NULL, we should return ERR_PTR(-ENOMEM) to the caller site.
Signed-off-by: Gen Zhang blackgod016574@gmail.com Reviewed-by: Jani Nikula jani.nikula@intel.com Signed-off-by: Jani Nikula jani.nikula@intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20190524023222.GA5302@zhanggen... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/drm_edid_load.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/drm_edid_load.c b/drivers/gpu/drm/drm_edid_load.c index 1e5593575d23..6192b7b20d84 100644 --- a/drivers/gpu/drm/drm_edid_load.c +++ b/drivers/gpu/drm/drm_edid_load.c @@ -278,6 +278,8 @@ struct edid *drm_load_edid_firmware(struct drm_connector *connector) * the last one found one as a fallback. */ fwstr = kstrdup(edid_firmware, GFP_KERNEL); + if (!fwstr) + return ERR_PTR(-ENOMEM); edidstr = fwstr;
while ((edidname = strsep(&edidstr, ","))) {
[ Upstream commit 8a5e0af240e07dd3d4897eb8ff52aab757da7fab ]
pcitest is currently broken due to the following compiler error and related warning. Fix by changing the run_test() function signature to return an integer result.
pcitest.c: In function run_test: pcitest.c:143:9: warning: return with a value, in function returning void return (ret < 0) ? ret : 1 - ret; /* return 0 if test succeeded */
pcitest.c: In function main: pcitest.c:232:9: error: void value not ignored as it ought to be return run_test(test);
Fixes: fef31ecaaf2c ("tools: PCI: Fix compilation warnings") Signed-off-by: Alan Mikhak alan.mikhak@sifive.com Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Reviewed-by: Paul Walmsley paul.walmsley@sifive.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/pci/pcitest.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/tools/pci/pcitest.c b/tools/pci/pcitest.c index cb7a47dfd8b6..49ddfa6f5a8c 100644 --- a/tools/pci/pcitest.c +++ b/tools/pci/pcitest.c @@ -36,15 +36,15 @@ struct pci_test { unsigned long size; };
-static void run_test(struct pci_test *test) +static int run_test(struct pci_test *test) { - long ret; + int ret = -EINVAL; int fd;
fd = open(test->device, O_RDWR); if (fd < 0) { perror("can't open PCI Endpoint Test device"); - return; + return -ENODEV; }
if (test->barnum >= 0 && test->barnum <= 5) {
[ Upstream commit 76002d8b48c4b08c9bd414517dd295e132ad910b ]
Commit 0e7df22401a3 ("PCI: Add sysfs sriov_drivers_autoprobe to control VF driver binding") allows the user to specify that drivers for VFs of a PF should not be probed, but it actually causes pci_device_probe() to return success back to the driver core in this case. Therefore by all sysfs appearances the device is bound to a driver, the driver link from the device exists as does the device link back from the driver, yet the driver's probe function is never called on the device. We also fail to do any sort of cleanup when we're prohibited from probing the device, the IRQ setup remains in place and we even hold a device reference.
Instead, abort with errno before any setup or references are taken when pci_device_can_probe() prevents us from trying to probe the device.
Link: https://lore.kernel.org/lkml/155672991496.20698.4279330795743262888.stgit@gi... Fixes: 0e7df22401a3 ("PCI: Add sysfs sriov_drivers_autoprobe to control VF driver binding") Signed-off-by: Alex Williamson alex.williamson@redhat.com Signed-off-by: Bjorn Helgaas bhelgaas@google.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/pci-driver.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index ca3793002e2f..74c3df250d9c 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -414,6 +414,9 @@ static int pci_device_probe(struct device *dev) struct pci_dev *pci_dev = to_pci_dev(dev); struct pci_driver *drv = to_pci_driver(dev->driver);
+ if (!pci_device_can_probe(pci_dev)) + return -ENODEV; + pci_assign_irq(pci_dev);
error = pcibios_alloc_irq(pci_dev); @@ -421,12 +424,10 @@ static int pci_device_probe(struct device *dev) return error;
pci_dev_get(pci_dev); - if (pci_device_can_probe(pci_dev)) { - error = __pci_device_probe(drv, pci_dev); - if (error) { - pcibios_free_irq(pci_dev); - pci_dev_put(pci_dev); - } + error = __pci_device_probe(drv, pci_dev); + if (error) { + pcibios_free_irq(pci_dev); + pci_dev_put(pci_dev); }
return error;
[ Upstream commit 9164f336311863d3e9f80840f4a1cce2aee293bd ]
There is an error condition that's not reported to the spi core in kp_spi_transfer_one_message(). It should restore status value to m->status, and return it in error path.
Signed-off-by: Mao Wenan maowenan@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/staging/kpc2000/kpc_spi/spi_driver.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/staging/kpc2000/kpc_spi/spi_driver.c b/drivers/staging/kpc2000/kpc_spi/spi_driver.c index 86df16547a92..2f535022dc03 100644 --- a/drivers/staging/kpc2000/kpc_spi/spi_driver.c +++ b/drivers/staging/kpc2000/kpc_spi/spi_driver.c @@ -333,7 +333,7 @@ kp_spi_transfer_one_message(struct spi_master *master, struct spi_message *m) list_for_each_entry(transfer, &m->transfers, transfer_list) { if (transfer->tx_buf == NULL && transfer->rx_buf == NULL && transfer->len) { status = -EINVAL; - break; + goto error; }
/* transfer */ @@ -371,7 +371,7 @@ kp_spi_transfer_one_message(struct spi_master *master, struct spi_message *m)
if (count != transfer->len) { status = -EIO; - break; + goto error; } }
@@ -389,6 +389,10 @@ kp_spi_transfer_one_message(struct spi_master *master, struct spi_message *m) /* done work */ spi_finalize_current_message(master); return 0; + + error: + m->status = status; + return status; }
static void
[ Upstream commit 3231573065ad4f4ecc5c9147b24f29f846dc0c2f ]
We need to know the link bandwidth to filter out modes we cannot support, so we need to have read the display props before doing the filtering.
To ensure we have up to date display props, call tc_get_display_props() in the beginning of tc_connector_get_modes().
Signed-off-by: Tomi Valkeinen tomi.valkeinen@ti.com Reviewed-by: Andrzej Hajda a.hajda@samsung.com Signed-off-by: Andrzej Hajda a.hajda@samsung.com Link: https://patchwork.freedesktop.org/patch/msgid/20190528082747.3631-22-tomi.va... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/tc358767.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c index 4655bb1eb88f..f59a51e19dab 100644 --- a/drivers/gpu/drm/bridge/tc358767.c +++ b/drivers/gpu/drm/bridge/tc358767.c @@ -1141,6 +1141,13 @@ static int tc_connector_get_modes(struct drm_connector *connector) struct tc_data *tc = connector_to_tc(connector); struct edid *edid; unsigned int count; + int ret; + + ret = tc_get_display_props(tc); + if (ret < 0) { + dev_err(tc->dev, "failed to read display props: %d\n", ret); + return 0; + }
if (tc->panel && tc->panel->funcs && tc->panel->funcs->get_modes) { count = tc->panel->funcs->get_modes(tc->panel);
[ Upstream commit 8dbfc5b65023b67397aca28e8adb25c819f6398c ]
The pixel clock unit in the first two registers (0x00 and 0x01) of sii9022 is 10kHz, not 1kHz as in struct drm_display_mode. Division by 10 fixes the issue.
Signed-off-by: Jyri Sarha jsarha@ti.com Reviewed-by: Andrzej Hajda a.hajda@samsung.com Reviewed-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Signed-off-by: Andrzej Hajda a.hajda@samsung.com Link: https://patchwork.freedesktop.org/patch/msgid/1a2a8eae0b9d6333e7a5841026bf7f... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/sii902x.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/bridge/sii902x.c b/drivers/gpu/drm/bridge/sii902x.c index 1211b5379df1..8e3c5e599eba 100644 --- a/drivers/gpu/drm/bridge/sii902x.c +++ b/drivers/gpu/drm/bridge/sii902x.c @@ -229,10 +229,11 @@ static void sii902x_bridge_mode_set(struct drm_bridge *bridge, struct regmap *regmap = sii902x->regmap; u8 buf[HDMI_INFOFRAME_SIZE(AVI)]; struct hdmi_avi_infoframe frame; + u16 pixel_clock_10kHz = adj->clock / 10; int ret;
- buf[0] = adj->clock; - buf[1] = adj->clock >> 8; + buf[0] = pixel_clock_10kHz & 0xff; + buf[1] = pixel_clock_10kHz >> 8; buf[2] = adj->vrefresh; buf[3] = 0x00; buf[4] = adj->hdisplay;
[ Upstream commit 7316c4ad299663a16ca9ce13e5e817b4ca760809 ]
[Why] For commits with allow_modeset=false and CRTC degamma changes the planes aren't reset. This results in incorrect rendering.
[How] Reset the planes when color management has changed on the CRTC. Technically this will include regamma changes as well, but it doesn't really after legacy userspace since those commit with allow_modeset=true.
Signed-off-by: Nicholas Kazlauskas nicholas.kazlauskas@amd.com Reviewed-by: Harry Wentland Harry.Wentland@amd.com Acked-by: Leo Li sunpeng.li@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 31530bfd002a..0e482349a5cb 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -6331,6 +6331,10 @@ static bool should_reset_plane(struct drm_atomic_state *state, if (!new_crtc_state) return true;
+ /* CRTC Degamma changes currently require us to recreate planes. */ + if (new_crtc_state->color_mgmt_changed) + return true; + if (drm_atomic_crtc_needs_modeset(new_crtc_state)) return true;
[ Upstream commit 6ad34adeaec5b56a5ba90e90099cabf1c1fe9dd2 ]
[Why] There's some unnecessary mem allocation for CS_TFM_ID. What's worse, it depends on LUT size and since it's 4K for CS_TFM_1D, it is 16x bigger than in regular case when it's actually needed. This leads to some crashes in stress conditions.
[How] Skip ramp combining designed for RGB256 and DXGI gamma with CS_TFM_1D.
Signed-off-by: Krunoslav Kovac Krunoslav.Kovac@amd.com Reviewed-by: Aric Cyr Aric.Cyr@amd.com Acked-by: Leo Li sunpeng.li@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/modules/color/color_gamma.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c index a1055413bade..31f867bb5afe 100644 --- a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c +++ b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c @@ -1564,7 +1564,8 @@ bool mod_color_calculate_regamma_params(struct dc_transfer_func *output_tf,
output_tf->type = TF_TYPE_DISTRIBUTED_POINTS;
- if (ramp && (mapUserRamp || ramp->type != GAMMA_RGB_256)) { + if (ramp && ramp->type != GAMMA_CS_TFM_1D && + (mapUserRamp || ramp->type != GAMMA_RGB_256)) { rgb_user = kvcalloc(ramp->num_entries + _EXTRA_POINTS, sizeof(*rgb_user), GFP_KERNEL);
[ Upstream commit e25228b02e4833e5b0fdd262801a2ae6cc72b39d ]
[Why] Some backlight tests fail due to backlight settling taking too long. This happens because the step size used to change backlight levels is too small.
[How] 1. Change the size of the backlight gain step size 2. Change how DMCU firmware gets the step size value so that it is passed in by driver during DMCU initn
Signed-off-by: Eryk Brol eryk.brol@amd.com Reviewed-by: Jun Lei Jun.Lei@amd.com Acked-by: Leo Li sunpeng.li@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c | 3 +++ drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.h | 2 ++ 2 files changed, 5 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c index 818536eea00a..c6a607cd0e4b 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c @@ -388,6 +388,9 @@ static bool dcn10_dmcu_init(struct dmcu *dmcu) /* Set initialized ramping boundary value */ REG_WRITE(MASTER_COMM_DATA_REG1, 0xFFFF);
+ /* Set backlight ramping stepsize */ + REG_WRITE(MASTER_COMM_DATA_REG2, abm_gain_stepsize); + /* Set command to initialize microcontroller */ REG_UPDATE(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0, MCP_INIT_DMCU); diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.h b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.h index 60ce56f60ae3..5bd0df55aa5d 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.h @@ -263,4 +263,6 @@ struct dmcu *dcn10_dmcu_create(
void dce_dmcu_destroy(struct dmcu **dmcu);
+static const uint32_t abm_gain_stepsize = 0x0060; + #endif /* _DCE_ABM_H_ */
[ Upstream commit a4c3ecaaadac5693f555cfef1c9eecf4c39df818 ]
Fixes possible underflows when dealing with unusable blocks.
Signed-off-by: Daniel Rosenberg drosen@google.com Reviewed-by: Chao Yu yuchao0@huawei.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/f2fs.h | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index d1b64cb77326..9e6721e15b24 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1767,8 +1767,12 @@ static inline int inc_valid_block_count(struct f2fs_sb_info *sbi,
if (!__allow_reserved_blocks(sbi, inode, true)) avail_user_block_count -= F2FS_OPTION(sbi).root_reserved_blocks; - if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) - avail_user_block_count -= sbi->unusable_block_count; + if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) { + if (avail_user_block_count > sbi->unusable_block_count) + avail_user_block_count -= sbi->unusable_block_count; + else + avail_user_block_count = 0; + } if (unlikely(sbi->total_valid_block_count > avail_user_block_count)) { diff = sbi->total_valid_block_count - avail_user_block_count; if (diff > *count) @@ -1968,7 +1972,7 @@ static inline int inc_valid_node_count(struct f2fs_sb_info *sbi, struct inode *inode, bool is_inode) { block_t valid_block_count; - unsigned int valid_node_count; + unsigned int valid_node_count, user_block_count; int err;
if (is_inode) { @@ -1995,10 +1999,11 @@ static inline int inc_valid_node_count(struct f2fs_sb_info *sbi,
if (!__allow_reserved_blocks(sbi, inode, false)) valid_block_count += F2FS_OPTION(sbi).root_reserved_blocks; + user_block_count = sbi->user_block_count; if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) - valid_block_count += sbi->unusable_block_count; + user_block_count -= sbi->unusable_block_count;
- if (unlikely(valid_block_count > sbi->user_block_count)) { + if (unlikely(valid_block_count > user_block_count)) { spin_unlock(&sbi->stat_lock); goto enospc; }
[ Upstream commit ae4ad7ea09d32ff1b6fb908ff12f8c1bd5241b29 ]
The existing threshold for allowable holes at checkpoint=disable time is too high. The OVP space contains reserved segments, which are always in the form of free segments. These must be subtracted from the OVP value.
The current threshold is meant to be the maximum value of holes of a single type we can have and still guarantee that we can fill the disk without failing to find space for a block of a given type.
If the disk is full, ignoring current reserved, which only helps us, the amount of unused blocks is equal to the OVP area. Of that, there are reserved segments, which must be free segments, and the rest of the ovp area, which can come from either free segments or holes. The maximum possible amount of holes is OVP-reserved.
Now, consider the disk when mounting with checkpoint=disable. We must be able to fill all available free space with either data or node blocks. When we start with checkpoint=disable, holes are locked to their current type. Say we have H of one type of hole, and H+X of the other. We can fill H of that space with arbitrary typed blocks via SSR. For the remaining H+X blocks, we may not have any of a given block type left at all. For instance, if we were to fill the disk entirely with blocks of the type with fewer holes, the H+X blocks of the opposite type would not be used. If H+X > OVP-reserved, there would be more holes than could possibly exist, and we would have failed to find a suitable block earlier on, leading to a crash in update_sit_entry.
If H+X <= OVP-reserved, then the holes end up effectively masked by the OVP region in this case.
Signed-off-by: Daniel Rosenberg drosen@google.com Reviewed-by: Chao Yu yuchao0@huawei.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/segment.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index a96b9e964733..8903b61457e7 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -876,7 +876,9 @@ void f2fs_dirty_to_prefree(struct f2fs_sb_info *sbi) int f2fs_disable_cp_again(struct f2fs_sb_info *sbi) { struct dirty_seglist_info *dirty_i = DIRTY_I(sbi); - block_t ovp = overprovision_segments(sbi) << sbi->log_blocks_per_seg; + int ovp_hole_segs = + (overprovision_segments(sbi) - reserved_segments(sbi)); + block_t ovp_holes = ovp_hole_segs << sbi->log_blocks_per_seg; block_t holes[2] = {0, 0}; /* DATA and NODE */ struct seg_entry *se; unsigned int segno; @@ -891,10 +893,10 @@ int f2fs_disable_cp_again(struct f2fs_sb_info *sbi) } mutex_unlock(&dirty_i->seglist_lock);
- if (holes[DATA] > ovp || holes[NODE] > ovp) + if (holes[DATA] > ovp_holes || holes[NODE] > ovp_holes) return -EAGAIN; if (is_sbi_flag_set(sbi, SBI_CP_DISABLED_QUICK) && - dirty_segments(sbi) > overprovision_segments(sbi)) + dirty_segments(sbi) > ovp_hole_segs) return -EAGAIN; return 0; }
[ Upstream commit 1e390478cfb527e34c9ab89ba57212cb05c33c51 ]
Recent versions of the DMA API debug code have started to warn about violations of the maximum DMA segment size. This is because the segment size defaults to 64 KiB, which can easily be exceeded in large buffer allocations such as used in DRM/KMS for framebuffers.
Technically the Tegra SMMU and ARM SMMU don't have a maximum segment size (they map individual pages irrespective of whether they are contiguous or not), so the choice of 4 MiB is a bit arbitrary here. The maximum segment size is a 32-bit unsigned integer, though, so we can't set it to the correct maximum size, which would be the size of the aperture.
Signed-off-by: Thierry Reding treding@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/host1x/bus.c | 3 +++ include/linux/host1x.h | 2 ++ 2 files changed, 5 insertions(+)
diff --git a/drivers/gpu/host1x/bus.c b/drivers/gpu/host1x/bus.c index 9797ccb0a073..6387302c1245 100644 --- a/drivers/gpu/host1x/bus.c +++ b/drivers/gpu/host1x/bus.c @@ -414,6 +414,9 @@ static int host1x_device_add(struct host1x *host1x,
of_dma_configure(&device->dev, host1x->dev->of_node, true);
+ device->dev.dma_parms = &device->dma_parms; + dma_set_max_seg_size(&device->dev, SZ_4M); + err = host1x_device_parse_dt(device, driver); if (err < 0) { kfree(device); diff --git a/include/linux/host1x.h b/include/linux/host1x.h index cfff30b9a62e..e6eea45e1154 100644 --- a/include/linux/host1x.h +++ b/include/linux/host1x.h @@ -297,6 +297,8 @@ struct host1x_device { struct list_head clients;
bool registered; + + struct device_dma_parameters dma_parms; };
static inline struct host1x_device *to_host1x_device(struct device *dev)
[ Upstream commit 1882018a70e06376234133e69ede9dd743b4dbd9 ]
We can be called from any context, we need to be prepared.
Noticed this while hacking on vkms, which calls this function from a normal worker. Which really upsets lockdep.
Cc: Rodrigo Siqueira rodrigosiqueiramelo@gmail.com Cc: Tomeu Vizoso tomeu.vizoso@collabora.com Cc: Emil Velikov emil.velikov@collabora.com Cc: Benjamin Gaignard benjamin.gaignard@linaro.org Reviewed-by: Benjamin Gaignard benjamin.gaignard@linaro.org Reviewed-by: Ville Syrjälä ville.syrjala@linux.intel.com Signed-off-by: Daniel Vetter daniel.vetter@intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20190605194556.16744-1-daniel.... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/drm_debugfs_crc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/drm_debugfs_crc.c b/drivers/gpu/drm/drm_debugfs_crc.c index 00e743153e94..1a6a5b78e30f 100644 --- a/drivers/gpu/drm/drm_debugfs_crc.c +++ b/drivers/gpu/drm/drm_debugfs_crc.c @@ -389,8 +389,9 @@ int drm_crtc_add_crc_entry(struct drm_crtc *crtc, bool has_frame, struct drm_crtc_crc *crc = &crtc->crc; struct drm_crtc_crc_entry *entry; int head, tail; + unsigned long flags;
- spin_lock(&crc->lock); + spin_lock_irqsave(&crc->lock, flags);
/* Caller may not have noticed yet that userspace has stopped reading */ if (!crc->entries) { @@ -421,7 +422,7 @@ int drm_crtc_add_crc_entry(struct drm_crtc *crtc, bool has_frame, head = (head + 1) & (DRM_CRC_ENTRIES_NR - 1); crc->head = head;
- spin_unlock(&crc->lock); + spin_unlock_irqrestore(&crc->lock, flags);
wake_up_interruptible(&crc->wq);
[ Upstream commit d99004d7201aa653658ff2390d6e516567c96ebc ]
I. was. blind.
Caught with vkms, which has some really slow crc computation function.
Fixes: 1882018a70e0 ("drm/crc-debugfs: User irqsafe spinlock in drm_crtc_add_crc_entry") Cc: Rodrigo Siqueira rodrigosiqueiramelo@gmail.com Cc: Tomeu Vizoso tomeu.vizoso@collabora.com Cc: Emil Velikov emil.velikov@collabora.com Cc: Benjamin Gaignard benjamin.gaignard@linaro.org Cc: Ville Syrjälä ville.syrjala@linux.intel.com Reviewed-by: Emil Velikov emil.velikov@collabora.com Reviewed-by: Benjamin Gaignard benjamin.gaignard@linaro.org Signed-off-by: Daniel Vetter daniel.vetter@intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20190606211544.5389-1-daniel.v... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/drm_debugfs_crc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/drm_debugfs_crc.c b/drivers/gpu/drm/drm_debugfs_crc.c index 1a6a5b78e30f..fde298d9f510 100644 --- a/drivers/gpu/drm/drm_debugfs_crc.c +++ b/drivers/gpu/drm/drm_debugfs_crc.c @@ -395,7 +395,7 @@ int drm_crtc_add_crc_entry(struct drm_crtc *crtc, bool has_frame,
/* Caller may not have noticed yet that userspace has stopped reading */ if (!crc->entries) { - spin_unlock(&crc->lock); + spin_unlock_irqrestore(&crc->lock, flags); return -EINVAL; }
@@ -406,7 +406,7 @@ int drm_crtc_add_crc_entry(struct drm_crtc *crtc, bool has_frame, bool was_overflow = crc->overflow;
crc->overflow = true; - spin_unlock(&crc->lock); + spin_unlock_irqrestore(&crc->lock, flags);
if (!was_overflow) DRM_ERROR("Overflow of CRC buffer, userspace reads too slow.\n");
[ Upstream commit 7355965da22b8d9ebac8bce4b776399fb0bb9d32 ]
In
commit def35e7c592616bc09be328de8795e5e624a3cf8 Author: Shayenne Moura shayenneluzmoura@gmail.com Date: Wed Jan 30 14:06:36 2019 -0200
drm/vkms: Bugfix extra vblank frame
we fixed the vblank counter to give accurate results outside of drm_crtc_handle_vblank, which fixed bugs around vblank timestamps being off-by-one and causing the vblank counter to jump when it shouldn't.
The trouble is that this completely broke crc generation. Shayenne and Rodrigo tracked this down to the vblank timestamp going backwards in time somehow. Which then resulted in an underflow in drm_vblank.c code, which resulted in all kinds of things breaking really badly.
The reason for this is that once we've called drm_crtc_handle_vblank and the hrtimer isn't forwarded yet, we're returning a vblank timestamp in the past. This race is really hard to hit since it's small, except when you enable crc generation: In that case there's a call to drm_crtc_accurate_vblank right in-betwen, so we're guaranteed to hit the bug.
The fix is to roll the hrtimer forward _before_ we do the vblank processing (which has a side-effect of incrementing the vblank counter), and we always subtract one frame from the hrtimer - since now it's always one frame in the future.
To make sure we don't hit this again also add a WARN_ON checking for whether our timestamp is somehow moving into the past, which is never should.
This also aligns more with how real hw works: 1. first all registers are updated with the new timestamp/vblank counter values. 2. then an interrupt is generated 3. kernel interrupt handler eventually fires.
So doing this aligns vkms closer with what drm_vblank.c expects. Document this also in a comment.
Cc: Shayenne Moura shayenneluzmoura@gmail.com Cc: Rodrigo Siqueira rodrigosiqueiramelo@gmail.com Signed-off-by: Daniel Vetter daniel.vetter@intel.com Tested-by: Rodrigo Siqueira rodrigosiqueiramelo@gmail.com Reviewed-by: Rodrigo Siqueira rodrigosiqueiramelo@gmail.com Signed-off-by: Rodrigo Siqueira rodrigosiqueiramelo@gmail.com Link: https://patchwork.freedesktop.org/patch/msgid/20190606084404.12014-1-daniel.... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/vkms/vkms_crtc.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c index bb66dbcd5e3f..e447b7588d06 100644 --- a/drivers/gpu/drm/vkms/vkms_crtc.c +++ b/drivers/gpu/drm/vkms/vkms_crtc.c @@ -15,6 +15,10 @@ static enum hrtimer_restart vkms_vblank_simulate(struct hrtimer *timer)
spin_lock(&output->lock);
+ ret_overrun = hrtimer_forward_now(&output->vblank_hrtimer, + output->period_ns); + WARN_ON(ret_overrun != 1); + ret = drm_crtc_handle_vblank(crtc); if (!ret) DRM_ERROR("vkms failure on handling vblank"); @@ -35,10 +39,6 @@ static enum hrtimer_restart vkms_vblank_simulate(struct hrtimer *timer) DRM_WARN("failed to queue vkms_crc_work_handle"); }
- ret_overrun = hrtimer_forward_now(&output->vblank_hrtimer, - output->period_ns); - WARN_ON(ret_overrun != 1); - spin_unlock(&output->lock);
return HRTIMER_RESTART; @@ -74,11 +74,21 @@ bool vkms_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, { struct vkms_device *vkmsdev = drm_device_to_vkms_device(dev); struct vkms_output *output = &vkmsdev->output; + struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
*vblank_time = output->vblank_hrtimer.node.expires;
- if (!in_vblank_irq) - *vblank_time -= output->period_ns; + if (WARN_ON(*vblank_time == vblank->time)) + return true; + + /* + * To prevent races we roll the hrtimer forward before we do any + * interrupt processing - this is how real hw works (the interrupt is + * only generated after all the vblank registers are updated) and what + * the vblank core expects. Therefore we need to always correct the + * timestampe by one frame. + */ + *vblank_time -= output->period_ns;
return true; }
[ Upstream commit 9f2e244d0a39eb437f98324ac315e605e48636db ]
Cypress USB Type-C CCGx controller firmware version 3.1.10 (which is being used in many NVIDIA GPU cards) has known issue of not triggering interrupt when a USB device is hot plugged to runtime resume the controller. If any GPU card gets latest kernel with runtime pm support but does not get latest fixed firmware then also it should continue to work and therefore a workaround is required to check for any connector change event
The workaround is to request runtime resume of i2c client which is UCSI Cypress CCGx driver. CCG driver will call the ISR for any connector change event only if NVIDIA GPU has old CCG firmware with the known issue.
Signed-off-by: Ajay Gupta ajayg@nvidia.com Signed-off-by: Wolfram Sang wsa@the-dreams.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/i2c/busses/i2c-nvidia-gpu.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/drivers/i2c/busses/i2c-nvidia-gpu.c b/drivers/i2c/busses/i2c-nvidia-gpu.c index 1c8f708f212b..ee2412b7459c 100644 --- a/drivers/i2c/busses/i2c-nvidia-gpu.c +++ b/drivers/i2c/busses/i2c-nvidia-gpu.c @@ -51,6 +51,7 @@ struct gpu_i2c_dev { void __iomem *regs; struct i2c_adapter adapter; struct i2c_board_info *gpu_ccgx_ucsi; + struct i2c_client *ccgx_client; };
static void gpu_enable_i2c_bus(struct gpu_i2c_dev *i2cd) @@ -261,8 +262,6 @@ static const struct property_entry ccgx_props[] = {
static int gpu_populate_client(struct gpu_i2c_dev *i2cd, int irq) { - struct i2c_client *ccgx_client; - i2cd->gpu_ccgx_ucsi = devm_kzalloc(i2cd->dev, sizeof(*i2cd->gpu_ccgx_ucsi), GFP_KERNEL); @@ -274,8 +273,8 @@ static int gpu_populate_client(struct gpu_i2c_dev *i2cd, int irq) i2cd->gpu_ccgx_ucsi->addr = 0x8; i2cd->gpu_ccgx_ucsi->irq = irq; i2cd->gpu_ccgx_ucsi->properties = ccgx_props; - ccgx_client = i2c_new_device(&i2cd->adapter, i2cd->gpu_ccgx_ucsi); - if (!ccgx_client) + i2cd->ccgx_client = i2c_new_device(&i2cd->adapter, i2cd->gpu_ccgx_ucsi); + if (!i2cd->ccgx_client) return -ENODEV;
return 0; @@ -354,6 +353,13 @@ static __maybe_unused int gpu_i2c_resume(struct device *dev) struct gpu_i2c_dev *i2cd = dev_get_drvdata(dev);
gpu_enable_i2c_bus(i2cd); + /* + * Runtime resume ccgx client so that it can see for any + * connector change event. Old ccg firmware has known + * issue of not triggering interrupt when a device is + * connected to runtime resume the controller. + */ + pm_request_resume(&i2cd->ccgx_client->dev); return 0; }
[ Upstream commit 6d7c3cde93c1d9ac0b37f78ec3f2ff052159a242 ]
mmu_notifier_unregister_no_release() is not a fence and the mmu_notifier system will continue to reference hmm->mn until the srcu grace period expires.
Resulting in use after free races like this:
CPU0 CPU1 __mmu_notifier_invalidate_range_start() srcu_read_lock hlist_for_each () // mn == hmm->mn hmm_mirror_unregister() hmm_put() hmm_free() mmu_notifier_unregister_no_release() hlist_del_init_rcu(hmm-mn->list) mn->ops->invalidate_range_start(mn, range); mm_get_hmm() mm->hmm = NULL; kfree(hmm) mutex_lock(&hmm->lock);
Use SRCU to kfree the hmm memory so that the notifiers can rely on hmm existing. Get the now-safe hmm struct through container_of and directly check kref_get_unless_zero to lock it against free.
Signed-off-by: Jason Gunthorpe jgg@mellanox.com Reviewed-by: Ira Weiny ira.weiny@intel.com Reviewed-by: John Hubbard jhubbard@nvidia.com Reviewed-by: Ralph Campbell rcampbell@nvidia.com Reviewed-by: Christoph Hellwig hch@lst.de Tested-by: Philip Yang Philip.Yang@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/hmm.h | 1 + mm/hmm.c | 23 +++++++++++++++++------ 2 files changed, 18 insertions(+), 6 deletions(-)
diff --git a/include/linux/hmm.h b/include/linux/hmm.h index 044a36d7c3f8..89508dc0795f 100644 --- a/include/linux/hmm.h +++ b/include/linux/hmm.h @@ -93,6 +93,7 @@ struct hmm { struct mmu_notifier mmu_notifier; struct rw_semaphore mirrors_sem; wait_queue_head_t wq; + struct rcu_head rcu; long notifiers; bool dead; }; diff --git a/mm/hmm.c b/mm/hmm.c index f702a3895d05..4c405dfbd2b3 100644 --- a/mm/hmm.c +++ b/mm/hmm.c @@ -104,6 +104,11 @@ static struct hmm *hmm_get_or_create(struct mm_struct *mm) return NULL; }
+static void hmm_free_rcu(struct rcu_head *rcu) +{ + kfree(container_of(rcu, struct hmm, rcu)); +} + static void hmm_free(struct kref *kref) { struct hmm *hmm = container_of(kref, struct hmm, kref); @@ -116,7 +121,7 @@ static void hmm_free(struct kref *kref) mm->hmm = NULL; spin_unlock(&mm->page_table_lock);
- kfree(hmm); + mmu_notifier_call_srcu(&hmm->rcu, hmm_free_rcu); }
static inline void hmm_put(struct hmm *hmm) @@ -144,10 +149,14 @@ void hmm_mm_destroy(struct mm_struct *mm)
static void hmm_release(struct mmu_notifier *mn, struct mm_struct *mm) { - struct hmm *hmm = mm_get_hmm(mm); + struct hmm *hmm = container_of(mn, struct hmm, mmu_notifier); struct hmm_mirror *mirror; struct hmm_range *range;
+ /* Bail out if hmm is in the process of being freed */ + if (!kref_get_unless_zero(&hmm->kref)) + return; + /* Report this HMM as dying. */ hmm->dead = true;
@@ -185,13 +194,14 @@ static void hmm_release(struct mmu_notifier *mn, struct mm_struct *mm) static int hmm_invalidate_range_start(struct mmu_notifier *mn, const struct mmu_notifier_range *nrange) { - struct hmm *hmm = mm_get_hmm(nrange->mm); + struct hmm *hmm = container_of(mn, struct hmm, mmu_notifier); struct hmm_mirror *mirror; struct hmm_update update; struct hmm_range *range; int ret = 0;
- VM_BUG_ON(!hmm); + if (!kref_get_unless_zero(&hmm->kref)) + return 0;
update.start = nrange->start; update.end = nrange->end; @@ -239,9 +249,10 @@ static int hmm_invalidate_range_start(struct mmu_notifier *mn, static void hmm_invalidate_range_end(struct mmu_notifier *mn, const struct mmu_notifier_range *nrange) { - struct hmm *hmm = mm_get_hmm(nrange->mm); + struct hmm *hmm = container_of(mn, struct hmm, mmu_notifier);
- VM_BUG_ON(!hmm); + if (!kref_get_unless_zero(&hmm->kref)) + return;
mutex_lock(&hmm->lock); hmm->notifiers--;
[ Upstream commit ad9df7d91b4a6e8f4b20c2bf539ac09b3b2ad6eb ]
While most display types only forward their VM to the DISPC, this is not true for DSI. DSI calculates the VM for DISPC based on its own, but it's not identical. Actually the DSI VM is not even a valid DISPC VM making this check fail. Let's restore the old behaviour and avoid checking the DISPC VM for DSI here.
Fixes: 7c27fa57ef31 ("drm/omap: Call dispc timings check operation directly") Acked-by: Pavel Machek pavel@ucw.cz Tested-by: Tony Lindgren tony@atomide.com Tested-by: Pavel Machek pavel@ucw.cz Signed-off-by: Sebastian Reichel sebastian.reichel@collabora.com Signed-off-by: Tomi Valkeinen tomi.valkeinen@ti.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/omapdrm/omap_crtc.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index 8712af79a49c..4c43dd282acc 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -384,10 +384,20 @@ static enum drm_mode_status omap_crtc_mode_valid(struct drm_crtc *crtc, int r;
drm_display_mode_to_videomode(mode, &vm); - r = priv->dispc_ops->mgr_check_timings(priv->dispc, omap_crtc->channel, - &vm); - if (r) - return r; + + /* + * DSI might not call this, since the supplied mode is not a + * valid DISPC mode. DSI will calculate and configure the + * proper DISPC mode later. + */ + if (omap_crtc->pipe->output->next == NULL || + omap_crtc->pipe->output->next->type != OMAP_DISPLAY_TYPE_DSI) { + r = priv->dispc_ops->mgr_check_timings(priv->dispc, + omap_crtc->channel, + &vm); + if (r) + return r; + }
/* Check for bandwidth limit */ if (priv->max_bandwidth) {
On Mon 2019-07-29 21:20:44, Greg Kroah-Hartman wrote:
[ Upstream commit ad9df7d91b4a6e8f4b20c2bf539ac09b3b2ad6eb ]
While most display types only forward their VM to the DISPC, this is not true for DSI. DSI calculates the VM for DISPC based on its own, but it's not identical. Actually the DSI VM is not even a valid DISPC VM making this check fail. Let's restore the old behaviour and avoid checking the DISPC VM for DSI here.
Fixes: 7c27fa57ef31 ("drm/omap: Call dispc timings check operation directly") Acked-by: Pavel Machek pavel@ucw.cz Tested-by: Tony Lindgren tony@atomide.com Tested-by: Pavel Machek pavel@ucw.cz Signed-off-by: Sebastian Reichel sebastian.reichel@collabora.com Signed-off-by: Tomi Valkeinen tomi.valkeinen@ti.com Signed-off-by: Sasha Levin sashal@kernel.org
Not sure if this is good idea for stable. IIRC there's series of patches to enable display on droid4 (etc), which is useful, but this patch is not going to do any good on its own.
Pavel
drivers/gpu/drm/omapdrm/omap_crtc.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index 8712af79a49c..4c43dd282acc 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -384,10 +384,20 @@ static enum drm_mode_status omap_crtc_mode_valid(struct drm_crtc *crtc, int r; drm_display_mode_to_videomode(mode, &vm);
- r = priv->dispc_ops->mgr_check_timings(priv->dispc, omap_crtc->channel,
&vm);
- if (r)
return r;
- /*
* DSI might not call this, since the supplied mode is not a
* valid DISPC mode. DSI will calculate and configure the
* proper DISPC mode later.
*/
- if (omap_crtc->pipe->output->next == NULL ||
omap_crtc->pipe->output->next->type != OMAP_DISPLAY_TYPE_DSI) {
r = priv->dispc_ops->mgr_check_timings(priv->dispc,
omap_crtc->channel,
&vm);
if (r)
return r;
- }
/* Check for bandwidth limit */ if (priv->max_bandwidth) {
Hi,
On Tue, Jul 30, 2019 at 01:37:51PM +0200, Pavel Machek wrote:
On Mon 2019-07-29 21:20:44, Greg Kroah-Hartman wrote:
[ Upstream commit ad9df7d91b4a6e8f4b20c2bf539ac09b3b2ad6eb ]
While most display types only forward their VM to the DISPC, this is not true for DSI. DSI calculates the VM for DISPC based on its own, but it's not identical. Actually the DSI VM is not even a valid DISPC VM making this check fail. Let's restore the old behaviour and avoid checking the DISPC VM for DSI here.
Fixes: 7c27fa57ef31 ("drm/omap: Call dispc timings check operation directly") Acked-by: Pavel Machek pavel@ucw.cz Tested-by: Tony Lindgren tony@atomide.com Tested-by: Pavel Machek pavel@ucw.cz Signed-off-by: Sebastian Reichel sebastian.reichel@collabora.com Signed-off-by: Tomi Valkeinen tomi.valkeinen@ti.com Signed-off-by: Sasha Levin sashal@kernel.org
Not sure if this is good idea for stable. IIRC there's series of patches to enable display on droid4 (etc), which is useful, but this patch is not going to do any good on its own.
It does not hurt to have it. I know that some people have out of tree omapdrm DSI drivers and those also need this regression fix.
-- Sebastian
Pavel
drivers/gpu/drm/omapdrm/omap_crtc.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index 8712af79a49c..4c43dd282acc 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -384,10 +384,20 @@ static enum drm_mode_status omap_crtc_mode_valid(struct drm_crtc *crtc, int r; drm_display_mode_to_videomode(mode, &vm);
- r = priv->dispc_ops->mgr_check_timings(priv->dispc, omap_crtc->channel,
&vm);
- if (r)
return r;
- /*
* DSI might not call this, since the supplied mode is not a
* valid DISPC mode. DSI will calculate and configure the
* proper DISPC mode later.
*/
- if (omap_crtc->pipe->output->next == NULL ||
omap_crtc->pipe->output->next->type != OMAP_DISPLAY_TYPE_DSI) {
r = priv->dispc_ops->mgr_check_timings(priv->dispc,
omap_crtc->channel,
&vm);
if (r)
return r;
- }
/* Check for bandwidth limit */ if (priv->max_bandwidth) {
-- (english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
[ Upstream commit 65f1a0d39c289bb6fc85635528cd36c4b07f560e ]
If bus_register fails. On its error handling path, it has cleaned up what it has done. There is no need to call bus_unregister again. Otherwise, if bus_unregister is called, issues such as null-ptr-deref will arise.
Syzkaller report this:
kobject_add_internal failed for memstick (error: -12 parent: bus) BUG: KASAN: null-ptr-deref in sysfs_remove_file_ns+0x1b/0x40 fs/sysfs/file.c:467 Read of size 8 at addr 0000000000000078 by task syz-executor.0/4460
Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0xa9/0x10e lib/dump_stack.c:113 __kasan_report+0x171/0x18d mm/kasan/report.c:321 kasan_report+0xe/0x20 mm/kasan/common.c:614 sysfs_remove_file_ns+0x1b/0x40 fs/sysfs/file.c:467 sysfs_remove_file include/linux/sysfs.h:519 [inline] bus_remove_file+0x6c/0x90 drivers/base/bus.c:145 remove_probe_files drivers/base/bus.c:599 [inline] bus_unregister+0x6e/0x100 drivers/base/bus.c:916 ? 0xffffffffc1590000 memstick_init+0x7a/0x1000 [memstick] do_one_initcall+0xb9/0x3b5 init/main.c:914 do_init_module+0xe0/0x330 kernel/module.c:3468 load_module+0x38eb/0x4270 kernel/module.c:3819 __do_sys_finit_module+0x162/0x190 kernel/module.c:3909 do_syscall_64+0x72/0x2a0 arch/x86/entry/common.c:298 entry_SYSCALL_64_after_hwframe+0x49/0xbe
Fixes: baf8532a147d ("memstick: initial commit for Sony MemoryStick support") Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Wang Hai wanghai26@huawei.com Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/memstick/core/memstick.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/memstick/core/memstick.c b/drivers/memstick/core/memstick.c index 6cfb293396f2..693ee73eb291 100644 --- a/drivers/memstick/core/memstick.c +++ b/drivers/memstick/core/memstick.c @@ -625,13 +625,18 @@ static int __init memstick_init(void) return -ENOMEM;
rc = bus_register(&memstick_bus_type); - if (!rc) - rc = class_register(&memstick_host_class); + if (rc) + goto error_destroy_workqueue;
- if (!rc) - return 0; + rc = class_register(&memstick_host_class); + if (rc) + goto error_bus_unregister; + + return 0;
+error_bus_unregister: bus_unregister(&memstick_bus_type); +error_destroy_workqueue: destroy_workqueue(workqueue);
return rc;
[ Upstream commit c7ad9ba0611c53cfe194223db02e3bca015f0674 ]
When modprobe/rmmod/modprobe module, if platform_driver_register() fails, the kernel complained,
proc_dir_entry 'driver/digicolor-usart' already registered WARNING: CPU: 1 PID: 5636 at fs/proc/generic.c:360 proc_register+0x19d/0x270
Fix this by adding uart_unregister_driver() when platform_driver_register() fails.
Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Kefeng Wang wangkefeng.wang@huawei.com Acked-by: Baruch Siach baruch@tkos.co.il Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/digicolor-usart.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/tty/serial/digicolor-usart.c b/drivers/tty/serial/digicolor-usart.c index f460cca139e2..13ac36e2da4f 100644 --- a/drivers/tty/serial/digicolor-usart.c +++ b/drivers/tty/serial/digicolor-usart.c @@ -541,7 +541,11 @@ static int __init digicolor_uart_init(void) if (ret) return ret;
- return platform_driver_register(&digicolor_uart_platform); + ret = platform_driver_register(&digicolor_uart_platform); + if (ret) + uart_unregister_driver(&digicolor_uart); + + return ret; } module_init(digicolor_uart_init);
[ Upstream commit ba3684f99f1b25d2a30b6956d02d339d7acb9799 ]
The function msm_wait_for_xmitr can be taken with interrupts disabled. In order to avoid a potential system lockup - demonstrated under stress testing conditions on SoC QCS404/5 - make sure we wait for a bounded amount of time.
Tested on SoC QCS404.
Signed-off-by: Jorge Ramirez-Ortiz jorge.ramirez-ortiz@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/msm_serial.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c index 23833ad952ba..3657a24913fc 100644 --- a/drivers/tty/serial/msm_serial.c +++ b/drivers/tty/serial/msm_serial.c @@ -383,10 +383,14 @@ static void msm_request_rx_dma(struct msm_port *msm_port, resource_size_t base)
static inline void msm_wait_for_xmitr(struct uart_port *port) { + unsigned int timeout = 500000; + while (!(msm_read(port, UART_SR) & UART_SR_TX_EMPTY)) { if (msm_read(port, UART_ISR) & UART_ISR_TX_READY) break; udelay(1); + if (!timeout--) + break; } msm_write(port, UART_CR_CMD_RESET_TX_READY, UART_CR); }
[ Upstream commit db1b5bc047b3cadaedab3826bba82c3d9e023c4b ]
Interrupt handler checked THRE bit (transmitter holding register empty) in LSR to detect if TX fifo is empty. In case when there is only receive interrupts the TX handling got called because THRE bit in LSR is set when there is no transmission (FIFO empty). TX handling caused TX stop, which in RS-485 half-duplex mode actually resets receiver FIFO. This is not desired during reception because of possible data loss.
The fix is to check if THRI is set in IER in addition of the TX fifo status. THRI in IER is set when TX is started and cleared when TX is stopped. This ensures that TX handling is only called when there is really transmission on going and an interrupt for THRE and not when there are only RX interrupts.
Signed-off-by: Kimmo Rautkoski ext-kimmo.rautkoski@vaisala.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/8250/8250_port.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index 682300713be4..eb2e2d141c01 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -1874,7 +1874,8 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir) status = serial8250_rx_chars(up, status); } serial8250_modem_status(up); - if ((!up->dma || up->dma->tx_err) && (status & UART_LSR_THRE)) + if ((!up->dma || up->dma->tx_err) && (status & UART_LSR_THRE) && + (up->ier & UART_IER_THRI)) serial8250_tx_chars(up);
uart_unlock_and_check_sysrq(port, flags);
[ Upstream commit f16fb16ed16c7f561e9c41c9ae4107c7f6aa553c ]
PCI endpoint test function code should honor the .bar_fixed_size parameter from underlying endpoint controller drivers or results may be unexpected.
In pci_epf_test_alloc_space(), check if BAR being used for test register space is a fixed size BAR. If so, allocate the required fixed size.
Signed-off-by: Alan Mikhak alan.mikhak@sifive.com Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Acked-by: Kishon Vijay Abraham I kishon@ti.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/endpoint/functions/pci-epf-test.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c index 27806987e93b..7d41e6684b87 100644 --- a/drivers/pci/endpoint/functions/pci-epf-test.c +++ b/drivers/pci/endpoint/functions/pci-epf-test.c @@ -434,10 +434,16 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf) int bar; enum pci_barno test_reg_bar = epf_test->test_reg_bar; const struct pci_epc_features *epc_features; + size_t test_reg_size;
epc_features = epf_test->epc_features;
- base = pci_epf_alloc_space(epf, sizeof(struct pci_epf_test_reg), + if (epc_features->bar_fixed_size[test_reg_bar]) + test_reg_size = bar_size[test_reg_bar]; + else + test_reg_size = sizeof(struct pci_epf_test_reg); + + base = pci_epf_alloc_space(epf, test_reg_size, test_reg_bar, epc_features->align); if (!base) { dev_err(dev, "Failed to allocated register space\n");
[ Upstream commit f04bee34d6e35df26cbb2d65e801adfd0d8fe20d ]
[Why] Unlike our regular connectors, MST connectors don't start off with an initial connector state. This causes a NULL pointer dereference to occur when attaching the bpc property since it tries to modify the connector state.
We need an initial connector state on the connector to avoid the crash.
[How] Use our reset helper to allocate an initial state and reset the values to their defaults. We were already doing this before, just not for MST connectors.
Signed-off-by: Nicholas Kazlauskas nicholas.kazlauskas@amd.com Reviewed-by: Leo Li sunpeng.li@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 0e482349a5cb..dc3ac66a4450 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4627,6 +4627,13 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm, { struct amdgpu_device *adev = dm->ddev->dev_private;
+ /* + * Some of the properties below require access to state, like bpc. + * Allocate some default initial connector state with our reset helper. + */ + if (aconnector->base.funcs->reset) + aconnector->base.funcs->reset(&aconnector->base); + aconnector->connector_id = link_index; aconnector->dc_link = link; aconnector->base.interlace_allowed = false; @@ -4809,9 +4816,6 @@ static int amdgpu_dm_connector_init(struct amdgpu_display_manager *dm, &aconnector->base, &amdgpu_dm_connector_helper_funcs);
- if (aconnector->base.funcs->reset) - aconnector->base.funcs->reset(&aconnector->base); - amdgpu_dm_connector_init_helper( dm, aconnector,
[ Upstream commit 53c81fc7875bc2dca358485dac3999e14ec91a00 ]
[WHY] Some panels return a link rate of 0 (unknown) in DPCD 0. In this case, an appropriate mode cannot be set, and certain panels will show corruption as they are forced to use a mode they do not support.
[HOW] Read DPCD 10 in the case where supported link rate from DPCD 0 is unknown, and pass that value on to the reported link rate. This re-introduces behaviour present in previous versions that appears to have been accidentally removed.
Signed-off-by: Wesley Chalmers Wesley.Chalmers@amd.com Reviewed-by: Anthony Koo Anthony.Koo@amd.com Acked-by: Bhawanpreet Lakha Bhawanpreet.Lakha@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c index 1ee544a32ebb..253311864cdd 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c @@ -1624,8 +1624,7 @@ static bool decide_edp_link_settings(struct dc_link *link, struct dc_link_settin uint32_t link_bw;
if (link->dpcd_caps.dpcd_rev.raw < DPCD_REV_14 || - link->dpcd_caps.edp_supported_link_rates_count == 0 || - link->dc->config.optimize_edp_link_rate == false) { + link->dpcd_caps.edp_supported_link_rates_count == 0) { *link_setting = link->verified_link_cap; return true; } @@ -2597,7 +2596,8 @@ void detect_edp_sink_caps(struct dc_link *link) memset(supported_link_rates, 0, sizeof(supported_link_rates));
if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_14 && - link->dc->config.optimize_edp_link_rate) { + (link->dc->config.optimize_edp_link_rate || + link->reported_link_cap.link_rate == LINK_RATE_UNKNOWN)) { // Read DPCD 00010h - 0001Fh 16 bytes at one shot core_link_read_dpcd(link, DP_SUPPORTED_LINK_RATES, supported_link_rates, sizeof(supported_link_rates)); @@ -2612,6 +2612,9 @@ void detect_edp_sink_caps(struct dc_link *link) link_rate = linkRateInKHzToLinkRateMultiplier(link_rate_in_khz); link->dpcd_caps.edp_supported_link_rates[link->dpcd_caps.edp_supported_link_rates_count] = link_rate; link->dpcd_caps.edp_supported_link_rates_count++; + + if (link->reported_link_cap.link_rate < link_rate) + link->reported_link_cap.link_rate = link_rate; } } }
[ Upstream commit 9ff3a5c88e1f1ab17a31402b96d45abe14aab9d7 ]
After data is copied to the cache entry, atomic_set is used indicate that the data is the entry is valid without appropriate memory barriers. Similarly the read side was missing the corresponding memory barriers.
Signed-off-by: David Riley davidriley@chromium.org Link: http://patchwork.freedesktop.org/patch/msgid/20190610211810.253227-5-davidri... Signed-off-by: Gerd Hoffmann kraxel@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/virtio/virtgpu_ioctl.c | 3 +++ drivers/gpu/drm/virtio/virtgpu_vq.c | 2 ++ 2 files changed, 5 insertions(+)
diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c index 949a264985fc..19fbffd0f7a3 100644 --- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c +++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c @@ -542,6 +542,9 @@ static int virtio_gpu_get_caps_ioctl(struct drm_device *dev, if (!ret) return -EBUSY;
+ /* is_valid check must proceed before copy of the cache entry. */ + smp_rmb(); + ptr = cache_ent->caps_cache;
copy_exit: diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c index 5bb0f0a084e9..a7684f9c80db 100644 --- a/drivers/gpu/drm/virtio/virtgpu_vq.c +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c @@ -583,6 +583,8 @@ static void virtio_gpu_cmd_capset_cb(struct virtio_gpu_device *vgdev, cache_ent->id == le32_to_cpu(cmd->capset_id)) { memcpy(cache_ent->caps_cache, resp->capset_data, cache_ent->size); + /* Copy must occur before is_valid is signalled. */ + smp_wmb(); atomic_set(&cache_ent->is_valid, 1); break; }
[ Upstream commit 233d87a579b8adcc6da5823fa507ecb6675e7562 ]
[Why] Found issue in EDID Emulation where if we connect a display using a passive HDMI-DP dongle, disconnect it and then try to emulate a display using DP, we could not see 4K modes. This was because on a disconnect, dongle_max_pix_clk was still set so when we emulate using DP, in dc_link_validate_mode_timing(), it would think we were still using a dongle and limit the modes we support.
[How] In dc_link_detect(), set dongle_max_pix_clk to 0 when we detect a hotplug out ( if new_connection_type = dc_connection_none ).
Signed-off-by: Samson Tam Samson.Tam@amd.com Reviewed-by: Jun Lei Jun.Lei@amd.com Acked-by: Bhawanpreet Lakha Bhawanpreet.Lakha@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c index b37ecc3ede61..a3ff33ff6da1 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -960,6 +960,12 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
link->type = dc_connection_none; sink_caps.signal = SIGNAL_TYPE_NONE; + /* When we unplug a passive DP-HDMI dongle connection, dongle_max_pix_clk + * is not cleared. If we emulate a DP signal on this connection, it thinks + * the dongle is still there and limits the number of modes we can emulate. + * Clear dongle_max_pix_clk on disconnect to fix this + */ + link->dongle_max_pix_clk = 0; }
LINK_INFO("link=%d, dc_sink_in=%p is now %s prev_sink=%p dpcd same=%d edid same=%d\n",
[ Upstream commit d4a36e82924d3305a17ac987a510f3902df5a4b2 ]
This patch fixes memory leak at error paths of the probe function. In for_each_child_of_node, if the loop returns, the driver should call of_put_node() before returns.
Reported-by: Julia Lawall julia.lawall@lip6.fr Fixes: 1233f59f745b237 ("phy: Renesas R-Car Gen2 PHY driver") Signed-off-by: Yoshihiro Shimoda yoshihiro.shimoda.uh@renesas.com Reviewed-by: Geert Uytterhoeven geert+renesas@glider.be Signed-off-by: Kishon Vijay Abraham I kishon@ti.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/phy/renesas/phy-rcar-gen2.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/phy/renesas/phy-rcar-gen2.c b/drivers/phy/renesas/phy-rcar-gen2.c index 8dc5710d9c98..2926e4937301 100644 --- a/drivers/phy/renesas/phy-rcar-gen2.c +++ b/drivers/phy/renesas/phy-rcar-gen2.c @@ -391,6 +391,7 @@ static int rcar_gen2_phy_probe(struct platform_device *pdev) error = of_property_read_u32(np, "reg", &channel_num); if (error || channel_num > 2) { dev_err(dev, "Invalid "reg" property\n"); + of_node_put(np); return error; } channel->select_mask = select_mask[channel_num]; @@ -406,6 +407,7 @@ static int rcar_gen2_phy_probe(struct platform_device *pdev) data->gen2_phy_ops); if (IS_ERR(phy->phy)) { dev_err(dev, "Failed to create PHY\n"); + of_node_put(np); return PTR_ERR(phy->phy); } phy_set_drvdata(phy->phy, phy);
[ Upstream commit 88099f53cc3717437f5fc9cf84205c5b65118377 ]
this patch fixes below compilation error
drivers/gpu/drm/amd/amdgpu/../display/dc/dcn10/dcn10_hw_sequencer.c: In function ‘dcn10_apply_ctx_for_surface’: drivers/gpu/drm/amd/amdgpu/../display/dc/dcn10/dcn10_hw_sequencer.c:2378:3: error: implicit declaration of function ‘udelay’ [-Werror=implicit-function-declaration] udelay(underflow_check_delay_us);
Signed-off-by: Hariprasad Kelam hariprasad.kelam@gmail.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 33d311cea28c..9e4d70a0055e 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -23,6 +23,7 @@ * */
+#include <linux/delay.h> #include "dm_services.h" #include "core_types.h" #include "resource.h"
[ Upstream commit 07a6d63eb1b54b5fb38092780fe618dfe1d96e23 ]
In d5a2aa24, the name in struct console sunhv_console was changed from "ttyS" to "ttyHV" while the name in struct uart_ops sunhv_pops remained unchanged.
This results in the hypervisor console device to be listed as "ttyHV0" under /proc/consoles while the device node is still named "ttyS0":
root@osaka:~# cat /proc/consoles ttyHV0 -W- (EC p ) 4:64 tty0 -WU (E ) 4:1 root@osaka:~# readlink /sys/dev/char/4:64 ../../devices/root/f02836f0/f0285690/tty/ttyS0 root@osaka:~#
This means that any userland code which tries to determine the name of the device file of the hypervisor console device can not rely on the information provided by /proc/consoles. In particular, booting current versions of debian- installer inside a SPARC LDOM will fail with the installer unable to determine the console device.
After renaming the device in struct uart_ops sunhv_pops to "ttyHV" as well, the inconsistency is fixed and it is possible again to determine the name of the device file of the hypervisor console device by reading the contents of /proc/console:
root@osaka:~# cat /proc/consoles ttyHV0 -W- (EC p ) 4:64 tty0 -WU (E ) 4:1 root@osaka:~# readlink /sys/dev/char/4:64 ../../devices/root/f02836f0/f0285690/tty/ttyHV0 root@osaka:~#
With this change, debian-installer works correctly when installing inside a SPARC LDOM.
Signed-off-by: John Paul Adrian Glaubitz glaubitz@physik.fu-berlin.de Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/sunhv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/tty/serial/sunhv.c b/drivers/tty/serial/sunhv.c index 63e34d868de8..f8503f8fc44e 100644 --- a/drivers/tty/serial/sunhv.c +++ b/drivers/tty/serial/sunhv.c @@ -397,7 +397,7 @@ static const struct uart_ops sunhv_pops = { static struct uart_driver sunhv_reg = { .owner = THIS_MODULE, .driver_name = "sunhv", - .dev_name = "ttyS", + .dev_name = "ttyHV", .major = TTY_MAJOR, };
[ Upstream commit b1622cb3be4557fd086831ca7426eafe5f1acc2e ]
We use delayed_work in HPD handling, and cancel any scheduled work in tfp410_fini using cancel_delayed_work_sync(). However, we have only initialized the delayed work if we actually have a HPD interrupt configured in the DT, but in the tfp410_fini, we always cancel the work, possibly causing a WARN().
Fix this by doing the cancel only if we actually had the delayed work set up.
Signed-off-by: Tomi Valkeinen tomi.valkeinen@ti.com Signed-off-by: Andrzej Hajda a.hajda@samsung.com Link: https://patchwork.freedesktop.org/patch/msgid/20190610135739.6077-2-tomi.val... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/ti-tfp410.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/bridge/ti-tfp410.c b/drivers/gpu/drm/bridge/ti-tfp410.c index a879aac21246..3a8af9978ebd 100644 --- a/drivers/gpu/drm/bridge/ti-tfp410.c +++ b/drivers/gpu/drm/bridge/ti-tfp410.c @@ -372,7 +372,8 @@ static int tfp410_fini(struct device *dev) { struct tfp410 *dvi = dev_get_drvdata(dev);
- cancel_delayed_work_sync(&dvi->hpd_work); + if (dvi->hpd_irq >= 0) + cancel_delayed_work_sync(&dvi->hpd_work);
drm_bridge_remove(&dvi->bridge);
[ Upstream commit e59a175faa8df9d674247946f2a5a9c29c835725 ]
CPU online/offline code paths are sensitive to parts of the device tree (various cpu node properties, cache nodes) that can be changed as a result of a migration.
Prevent CPU hotplug while the device tree potentially is inconsistent.
Fixes: 410bccf97881 ("powerpc/pseries: Partition migration in the kernel") Signed-off-by: Nathan Lynch nathanl@linux.ibm.com Reviewed-by: Gautham R. Shenoy ego@linux.vnet.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/platforms/pseries/mobility.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c index 0c48c8964783..50e7aee3c7f3 100644 --- a/arch/powerpc/platforms/pseries/mobility.c +++ b/arch/powerpc/platforms/pseries/mobility.c @@ -6,6 +6,7 @@ * Copyright (C) 2010 IBM Corporation */
+#include <linux/cpu.h> #include <linux/kernel.h> #include <linux/kobject.h> #include <linux/smp.h> @@ -335,11 +336,19 @@ void post_mobility_fixup(void) if (rc) printk(KERN_ERR "Post-mobility activate-fw failed: %d\n", rc);
+ /* + * We don't want CPUs to go online/offline while the device + * tree is being updated. + */ + cpus_read_lock(); + rc = pseries_devicetree_update(MIGRATION_SCOPE); if (rc) printk(KERN_ERR "Post-mobility device tree update " "failed: %d\n", rc);
+ cpus_read_unlock(); + /* Possibly switch to a new RFI flush type */ pseries_setup_rfi_flush();
[ Upstream commit 4b4b077cbd0a998aebaa72c199e06b8a4c8dcfee ]
With architectures allowing the kernel to be placed almost arbitrarily in memory (e.g.: ARM64), it is possible to have the kernel resides at physical addresses above 4GB, resulting in neither the default CMA area, nor the atomic pool from successfully allocating. This does not prevent specific peripherals from working though, one example is XHCI, which still operates correctly.
Trouble comes when the XHCI driver gets suspended and resumed, since we can now trigger the following NPD:
[ 12.664170] usb usb1: root hub lost power or was reset [ 12.669387] usb usb2: root hub lost power or was reset [ 12.674662] Unable to handle kernel NULL pointer dereference at virtual address 00000008 [ 12.682896] pgd = ffffffc1365a7000 [ 12.686386] [00000008] *pgd=0000000136500003, *pud=0000000136500003, *pmd=0000000000000000 [ 12.694897] Internal error: Oops: 96000006 [#1] SMP [ 12.699843] Modules linked in: [ 12.702980] CPU: 0 PID: 1499 Comm: pml Not tainted 4.9.135-1.13pre #51 [ 12.709577] Hardware name: BCM97268DV (DT) [ 12.713736] task: ffffffc136bb6540 task.stack: ffffffc1366cc000 [ 12.719740] PC is at addr_in_gen_pool+0x4/0x48 [ 12.724253] LR is at __dma_free+0x64/0xbc [ 12.728325] pc : [<ffffff80083c0df8>] lr : [<ffffff80080979e0>] pstate: 60000145 [ 12.735825] sp : ffffffc1366cf990 [ 12.739196] x29: ffffffc1366cf990 x28: ffffffc1366cc000 [ 12.744608] x27: 0000000000000000 x26: ffffffc13a8568c8 [ 12.750020] x25: 0000000000000000 x24: ffffff80098f9000 [ 12.755433] x23: 000000013a5ff000 x22: ffffff8009c57000 [ 12.760844] x21: ffffffc13a856810 x20: 0000000000000000 [ 12.766255] x19: 0000000000001000 x18: 000000000000000a [ 12.771667] x17: 0000007f917553e0 x16: 0000000000001002 [ 12.777078] x15: 00000000000a36cb x14: ffffff80898feb77 [ 12.782490] x13: ffffffffffffffff x12: 0000000000000030 [ 12.787899] x11: 00000000fffffffe x10: ffffff80098feb7f [ 12.793311] x9 : 0000000005f5e0ff x8 : 65776f702074736f [ 12.798723] x7 : 6c2062756820746f x6 : ffffff80098febb1 [ 12.804134] x5 : ffffff800809797c x4 : 0000000000000000 [ 12.809545] x3 : 000000013a5ff000 x2 : 0000000000000fff [ 12.814955] x1 : ffffff8009c57000 x0 : 0000000000000000 [ 12.820363] [ 12.821907] Process pml (pid: 1499, stack limit = 0xffffffc1366cc020) [ 12.828421] Stack: (0xffffffc1366cf990 to 0xffffffc1366d0000) [ 12.834240] f980: ffffffc1366cf9e0 ffffff80086004d0 [ 12.842186] f9a0: ffffffc13ab08238 0000000000000010 ffffff80097c2218 ffffffc13a856810 [ 12.850131] f9c0: ffffff8009c57000 000000013a5ff000 0000000000000008 000000013a5ff000 [ 12.858076] f9e0: ffffffc1366cfa50 ffffff80085f9250 ffffffc13ab08238 0000000000000004 [ 12.866021] fa00: ffffffc13ab08000 ffffff80097b6000 ffffffc13ab08130 0000000000000001 [ 12.873966] fa20: 0000000000000008 ffffffc13a8568c8 0000000000000000 ffffffc1366cc000 [ 12.881911] fa40: ffffffc13ab08130 0000000000000001 ffffffc1366cfa90 ffffff80085e3de8 [ 12.889856] fa60: ffffffc13ab08238 0000000000000000 ffffffc136b75b00 0000000000000000 [ 12.897801] fa80: 0000000000000010 ffffff80089ccb92 ffffffc1366cfac0 ffffff80084ad040 [ 12.905746] faa0: ffffffc13a856810 0000000000000000 ffffff80084ad004 ffffff80084b91a8 [ 12.913691] fac0: ffffffc1366cfae0 ffffff80084b91b4 ffffffc13a856810 ffffff80080db5cc [ 12.921636] fae0: ffffffc1366cfb20 ffffff80084b96bc ffffffc13a856810 0000000000000010 [ 12.929581] fb00: ffffffc13a856870 0000000000000000 ffffffc13a856810 ffffff800984d2b8 [ 12.937526] fb20: ffffffc1366cfb50 ffffff80084baa70 ffffff8009932ad0 ffffff800984d260 [ 12.945471] fb40: 0000000000000010 00000002eff0a065 ffffffc1366cfbb0 ffffff80084bafbc [ 12.953415] fb60: 0000000000000010 0000000000000003 ffffff80098fe000 0000000000000000 [ 12.961360] fb80: ffffff80097b6000 ffffff80097b6dc8 ffffff80098c12b8 ffffff80098c12f8 [ 12.969306] fba0: ffffff8008842000 ffffff80097b6dc8 ffffffc1366cfbd0 ffffff80080e0d88 [ 12.977251] fbc0: 00000000fffffffb ffffff80080e10bc ffffffc1366cfc60 ffffff80080e16a8 [ 12.985196] fbe0: 0000000000000000 0000000000000003 ffffff80097b6000 ffffff80098fe9f0 [ 12.993140] fc00: ffffff80097d4000 ffffff8008983802 0000000000000123 0000000000000040 [ 13.001085] fc20: ffffff8008842000 ffffffc1366cc000 ffffff80089803c2 00000000ffffffff [ 13.009029] fc40: 0000000000000000 0000000000000000 ffffffc1366cfc60 0000000000040987 [ 13.016974] fc60: ffffffc1366cfcc0 ffffff80080dfd08 0000000000000003 0000000000000004 [ 13.024919] fc80: 0000000000000003 ffffff80098fea08 ffffffc136577ec0 ffffff80089803c2 [ 13.032864] fca0: 0000000000000123 0000000000000001 0000000500000002 0000000000040987 [ 13.040809] fcc0: ffffffc1366cfd00 ffffff80083a89d4 0000000000000004 ffffffc136577ec0 [ 13.048754] fce0: ffffffc136610cc0 ffffffffffffffea ffffffc1366cfeb0 ffffffc136610cd8 [ 13.056700] fd00: ffffffc1366cfd10 ffffff800822a614 ffffffc1366cfd40 ffffff80082295d4 [ 13.064645] fd20: 0000000000000004 ffffffc136577ec0 ffffffc136610cc0 0000000021670570 [ 13.072590] fd40: ffffffc1366cfd80 ffffff80081b5d10 ffffff80097b6000 ffffffc13aae4200 [ 13.080536] fd60: ffffffc1366cfeb0 0000000000000004 0000000021670570 0000000000000004 [ 13.088481] fd80: ffffffc1366cfe30 ffffff80081b6b20 ffffffc13aae4200 0000000000000000 [ 13.096427] fda0: 0000000000000004 0000000021670570 ffffffc1366cfeb0 ffffffc13a838200 [ 13.104371] fdc0: 0000000000000000 000000000000000a ffffff80097b6000 0000000000040987 [ 13.112316] fde0: ffffffc1366cfe20 ffffff80081b3af0 ffffffc13a838200 0000000000000000 [ 13.120261] fe00: ffffffc1366cfe30 ffffff80081b6b0c ffffffc13aae4200 0000000000000000 [ 13.128206] fe20: 0000000000000004 0000000000040987 ffffffc1366cfe70 ffffff80081b7dd8 [ 13.136151] fe40: ffffff80097b6000 ffffffc13aae4200 ffffffc13aae4200 fffffffffffffff7 [ 13.144096] fe60: 0000000021670570 ffffffc13a8c63c0 0000000000000000 ffffff8008083180 [ 13.152042] fe80: ffffffffffffff1d 0000000021670570 ffffffffffffffff 0000007f917ad9b8 [ 13.159986] fea0: 0000000020000000 0000000000000015 0000000000000000 0000000000040987 [ 13.167930] fec0: 0000000000000001 0000000021670570 0000000000000004 0000000000000000 [ 13.175874] fee0: 0000000000000888 0000440110000000 000000000000006d 0000000000000003 [ 13.183819] ff00: 0000000000000040 ffffff80ffffffc8 0000000000000000 0000000000000020 [ 13.191762] ff20: 0000000000000000 0000000000000000 0000000000000001 0000000000000000 [ 13.199707] ff40: 0000000000000000 0000007f917553e0 0000000000000000 0000000000000004 [ 13.207651] ff60: 0000000021670570 0000007f91835480 0000000000000004 0000007f91831638 [ 13.215595] ff80: 0000000000000004 00000000004b0de0 00000000004b0000 0000000000000000 [ 13.223539] ffa0: 0000000000000000 0000007fc92ac8c0 0000007f9175d178 0000007fc92ac8c0 [ 13.231483] ffc0: 0000007f917ad9b8 0000000020000000 0000000000000001 0000000000000040 [ 13.239427] ffe0: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 [ 13.247360] Call trace: [ 13.249866] Exception stack(0xffffffc1366cf7a0 to 0xffffffc1366cf8d0) [ 13.256386] f7a0: 0000000000001000 0000007fffffffff ffffffc1366cf990 ffffff80083c0df8 [ 13.264331] f7c0: 0000000060000145 ffffff80089b5001 ffffffc13ab08130 0000000000000001 [ 13.272275] f7e0: 0000000000000008 ffffffc13a8568c8 0000000000000000 0000000000000000 [ 13.280220] f800: ffffffc1366cf960 ffffffc1366cf960 ffffffc1366cf930 00000000ffffffd8 [ 13.288165] f820: ffffff8009931ac0 4554535953425553 4544006273753d4d 3831633d45434956 [ 13.296110] f840: ffff003832313a39 ffffff800845926c ffffffc1366cf880 0000000000040987 [ 13.304054] f860: 0000000000000000 ffffff8009c57000 0000000000000fff 000000013a5ff000 [ 13.311999] f880: 0000000000000000 ffffff800809797c ffffff80098febb1 6c2062756820746f [ 13.319944] f8a0: 65776f702074736f 0000000005f5e0ff ffffff80098feb7f 00000000fffffffe [ 13.327884] f8c0: 0000000000000030 ffffffffffffffff [ 13.332835] [<ffffff80083c0df8>] addr_in_gen_pool+0x4/0x48 [ 13.338398] [<ffffff80086004d0>] xhci_mem_cleanup+0xc8/0x51c [ 13.344137] [<ffffff80085f9250>] xhci_resume+0x308/0x65c [ 13.349524] [<ffffff80085e3de8>] xhci_brcm_resume+0x84/0x8c [ 13.355174] [<ffffff80084ad040>] platform_pm_resume+0x3c/0x64 [ 13.360997] [<ffffff80084b91b4>] dpm_run_callback+0x5c/0x15c [ 13.366732] [<ffffff80084b96bc>] device_resume+0xc0/0x190 [ 13.372205] [<ffffff80084baa70>] dpm_resume+0x144/0x2cc [ 13.377504] [<ffffff80084bafbc>] dpm_resume_end+0x20/0x34 [ 13.382980] [<ffffff80080e0d88>] suspend_devices_and_enter+0x104/0x704 [ 13.389585] [<ffffff80080e16a8>] pm_suspend+0x320/0x53c [ 13.394881] [<ffffff80080dfd08>] state_store+0xbc/0xe0 [ 13.400094] [<ffffff80083a89d4>] kobj_attr_store+0x14/0x24 [ 13.405655] [<ffffff800822a614>] sysfs_kf_write+0x60/0x70 [ 13.411128] [<ffffff80082295d4>] kernfs_fop_write+0x130/0x194 [ 13.416954] [<ffffff80081b5d10>] __vfs_write+0x60/0x150 [ 13.422254] [<ffffff80081b6b20>] vfs_write+0xc8/0x164 [ 13.427376] [<ffffff80081b7dd8>] SyS_write+0x70/0xc8 [ 13.432412] [<ffffff8008083180>] el0_svc_naked+0x34/0x38 [ 13.437800] Code: 92800173 97f6fb9e 17fffff5 d1000442 (f8408c03) [ 13.444033] ---[ end trace 2effe12f909ce205 ]---
The call path leading to this problem is xhci_mem_cleanup() -> dma_free_coherent() -> dma_free_from_pool() -> addr_in_gen_pool. If the atomic_pool is NULL, we can't possibly have the address in the atomic pool anyway, so guard against that.
Signed-off-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: Christoph Hellwig hch@lst.de Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/dma/remap.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/kernel/dma/remap.c b/kernel/dma/remap.c index 7a723194ecbe..0207e3764d52 100644 --- a/kernel/dma/remap.c +++ b/kernel/dma/remap.c @@ -158,6 +158,9 @@ int __init dma_atomic_pool_init(gfp_t gfp, pgprot_t prot)
bool dma_in_atomic_pool(void *start, size_t size) { + if (unlikely(!atomic_pool)) + return false; + return addr_in_gen_pool(atomic_pool, (unsigned long)start, size); }
[ Upstream commit 99b9683f2142b20bad78e61f7f829e8714e45685 ]
When fixing up the clock in vop_crtc_mode_fixup() we're not doing it quite correctly. Specifically if we've got the true clock 266666667 Hz, we'll perform this calculation: 266666667 / 1000 => 266666
Later when we try to set the clock we'll do clk_set_rate(266666 * 1000). The common clock framework won't actually pick the proper clock in this case since it always wants clocks <= the specified one.
Let's solve this by using DIV_ROUND_UP.
Fixes: b59b8de31497 ("drm/rockchip: return a true clock rate to adjusted_mode") Signed-off-by: Douglas Anderson dianders@chromium.org Signed-off-by: Sean Paul seanpaul@chromium.org Reviewed-by: Yakir Yang ykk@rock-chips.com Signed-off-by: Heiko Stuebner heiko@sntech.de Link: https://patchwork.freedesktop.org/patch/msgid/20190614224730.98622-1-diander... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 12ed5265a90b..09046135e720 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -1011,7 +1011,8 @@ static bool vop_crtc_mode_fixup(struct drm_crtc *crtc, struct vop *vop = to_vop(crtc);
adjusted_mode->clock = - clk_round_rate(vop->dclk, mode->clock * 1000) / 1000; + DIV_ROUND_UP(clk_round_rate(vop->dclk, mode->clock * 1000), + 1000);
return true; }
[ Upstream commit 98e865a522983f2afde075648ec9d15ea4bb9194 ]
The asus-nb-wmi driver is matched by WMI alias but fails to load on TUF Gaming series laptops producing multiple ACPI errors in the kernel log.
The input buffer for WMI method invocation size is 2 dwords, whereas 3 are expected by this model.
FX505GM: .. Method (WMNB, 3, Serialized) { P8XH (Zero, 0x11) CreateDWordField (Arg2, Zero, IIA0) CreateDWordField (Arg2, 0x04, IIA1) CreateDWordField (Arg2, 0x08, IIA2) Local0 = (Arg1 & 0xFFFFFFFF) ...
Compare with older K54C: ... Method (WMNB, 3, NotSerialized) { CreateDWordField (Arg2, 0x00, IIA0) CreateDWordField (Arg2, 0x04, IIA1) Local0 = (Arg1 & 0xFFFFFFFF) ...
Increase buffer size to 3 dwords. No negative consequences of this change are expected, as the input buffer size is not verified. The original function is replaced by a wrapper for a new method passing value 0 for the last parameter. The new function will be used to control RGB keyboard backlight.
Signed-off-by: Yurii Pavlovskyi yurii.pavlovskyi@gmail.com Reviewed-by: Daniel Drake drake@endlessm.com Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/x86/asus-wmi.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index 9b18a184e0aa..abfa99d18fea 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c @@ -85,6 +85,7 @@ static bool ashs_present(void) struct bios_args { u32 arg0; u32 arg1; + u32 arg2; /* At least TUF Gaming series uses 3 dword input buffer. */ } __packed;
/* @@ -211,11 +212,13 @@ static void asus_wmi_input_exit(struct asus_wmi *asus) asus->inputdev = NULL; }
-int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1, u32 *retval) +static int asus_wmi_evaluate_method3(u32 method_id, + u32 arg0, u32 arg1, u32 arg2, u32 *retval) { struct bios_args args = { .arg0 = arg0, .arg1 = arg1, + .arg2 = arg2, }; struct acpi_buffer input = { (acpi_size) sizeof(args), &args }; struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; @@ -247,6 +250,11 @@ int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1, u32 *retval)
return 0; } + +int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1, u32 *retval) +{ + return asus_wmi_evaluate_method3(method_id, arg0, arg1, 0, retval); +} EXPORT_SYMBOL_GPL(asus_wmi_evaluate_method);
static int asus_wmi_evaluate_method_agfn(const struct acpi_buffer args)
[ Upstream commit 0e4f0b42f42d88507b48282c8915f502551534e4 ]
The iio_triggered_buffer_{predisable,postenable} functions attach/detach the poll functions.
For the predisable hook, the disable code should occur before detaching the poll func, and for the postenable hook, the poll func should be attached before the enable code.
Signed-off-by: Alexandru Ardelean alexandru.ardelean@analog.com Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/accel/adxl372.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-)
diff --git a/drivers/iio/accel/adxl372.c b/drivers/iio/accel/adxl372.c index 3b84cb243a87..055227cb3d43 100644 --- a/drivers/iio/accel/adxl372.c +++ b/drivers/iio/accel/adxl372.c @@ -782,10 +782,14 @@ static int adxl372_buffer_postenable(struct iio_dev *indio_dev) unsigned int mask; int i, ret;
- ret = adxl372_set_interrupts(st, ADXL372_INT1_MAP_FIFO_FULL_MSK, 0); + ret = iio_triggered_buffer_postenable(indio_dev); if (ret < 0) return ret;
+ ret = adxl372_set_interrupts(st, ADXL372_INT1_MAP_FIFO_FULL_MSK, 0); + if (ret < 0) + goto err; + mask = *indio_dev->active_scan_mask;
for (i = 0; i < ARRAY_SIZE(adxl372_axis_lookup_table); i++) { @@ -793,8 +797,10 @@ static int adxl372_buffer_postenable(struct iio_dev *indio_dev) break; }
- if (i == ARRAY_SIZE(adxl372_axis_lookup_table)) - return -EINVAL; + if (i == ARRAY_SIZE(adxl372_axis_lookup_table)) { + ret = -EINVAL; + goto err; + }
st->fifo_format = adxl372_axis_lookup_table[i].fifo_format; st->fifo_set_size = bitmap_weight(indio_dev->active_scan_mask, @@ -814,26 +820,25 @@ static int adxl372_buffer_postenable(struct iio_dev *indio_dev) if (ret < 0) { st->fifo_mode = ADXL372_FIFO_BYPASSED; adxl372_set_interrupts(st, 0, 0); - return ret; + goto err; }
- return iio_triggered_buffer_postenable(indio_dev); + return 0; + +err: + iio_triggered_buffer_predisable(indio_dev); + return ret; }
static int adxl372_buffer_predisable(struct iio_dev *indio_dev) { struct adxl372_state *st = iio_priv(indio_dev); - int ret; - - ret = iio_triggered_buffer_predisable(indio_dev); - if (ret < 0) - return ret;
adxl372_set_interrupts(st, 0, 0); st->fifo_mode = ADXL372_FIFO_BYPASSED; adxl372_configure_fifo(st);
- return 0; + return iio_triggered_buffer_predisable(indio_dev); }
static const struct iio_buffer_setup_ops adxl372_buffer_ops = {
[ Upstream commit 4e828c3e09201512be5ee162393f334321f7cf01 ]
imx_uart_set_termios() called imx_uart_rts_active(), or imx_uart_rts_inactive() before taking port->port.lock.
As a consequence, sport->port.mctrl that these functions modify could have been changed without holding port->port.lock.
Moved locking of port->port.lock above the calls to fix the issue.
Signed-off-by: Sergey Organov sorganov@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/imx.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-)
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 8b752e895053..10db3e54ac9e 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -383,6 +383,7 @@ static void imx_uart_ucrs_restore(struct imx_port *sport, } #endif
+/* called with port.lock taken and irqs caller dependent */ static void imx_uart_rts_active(struct imx_port *sport, u32 *ucr2) { *ucr2 &= ~(UCR2_CTSC | UCR2_CTS); @@ -391,6 +392,7 @@ static void imx_uart_rts_active(struct imx_port *sport, u32 *ucr2) mctrl_gpio_set(sport->gpios, sport->port.mctrl); }
+/* called with port.lock taken and irqs caller dependent */ static void imx_uart_rts_inactive(struct imx_port *sport, u32 *ucr2) { *ucr2 &= ~UCR2_CTSC; @@ -400,6 +402,7 @@ static void imx_uart_rts_inactive(struct imx_port *sport, u32 *ucr2) mctrl_gpio_set(sport->gpios, sport->port.mctrl); }
+/* called with port.lock taken and irqs caller dependent */ static void imx_uart_rts_auto(struct imx_port *sport, u32 *ucr2) { *ucr2 |= UCR2_CTSC; @@ -1549,6 +1552,16 @@ imx_uart_set_termios(struct uart_port *port, struct ktermios *termios, old_csize = CS8; }
+ del_timer_sync(&sport->timer); + + /* + * Ask the core to calculate the divisor for us. + */ + baud = uart_get_baud_rate(port, termios, old, 50, port->uartclk / 16); + quot = uart_get_divisor(port, baud); + + spin_lock_irqsave(&sport->port.lock, flags); + if ((termios->c_cflag & CSIZE) == CS8) ucr2 = UCR2_WS | UCR2_SRST | UCR2_IRTS; else @@ -1592,16 +1605,6 @@ imx_uart_set_termios(struct uart_port *port, struct ktermios *termios, ucr2 |= UCR2_PROE; }
- del_timer_sync(&sport->timer); - - /* - * Ask the core to calculate the divisor for us. - */ - baud = uart_get_baud_rate(port, termios, old, 50, port->uartclk / 16); - quot = uart_get_divisor(port, baud); - - spin_lock_irqsave(&sport->port.lock, flags); - sport->port.read_status_mask = 0; if (termios->c_iflag & INPCK) sport->port.read_status_mask |= (URXD_FRMERR | URXD_PRERR);
[ Upstream commit ab262666018de6f4e206b021386b93ed0c164316 ]
Let kernel to find out major number dynamically for the first device and then reuse it for other instances. This fixes the issue that each uart is registered with a different major number.
After the patch: crw------- 1 root root 253, 0 Jun 10 08:31 /dev/ttyPS0 crw--w---- 1 root root 253, 1 Jan 1 1970 /dev/ttyPS1
Fixes: 024ca329bfb9 ("serial: uartps: Register own uart console and driver structures") Signed-off-by: Shubhrajyoti Datta shubhrajyoti.datta@xilinx.com Signed-off-by: Michal Simek michal.simek@xilinx.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/xilinx_uartps.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c index 605354fd60b1..9dcc4d855ddd 100644 --- a/drivers/tty/serial/xilinx_uartps.c +++ b/drivers/tty/serial/xilinx_uartps.c @@ -29,12 +29,12 @@
#define CDNS_UART_TTY_NAME "ttyPS" #define CDNS_UART_NAME "xuartps" -#define CDNS_UART_MAJOR 0 /* use dynamic node allocation */ #define CDNS_UART_FIFO_SIZE 64 /* FIFO size */ #define CDNS_UART_REGISTER_SPACE 0x1000
/* Rx Trigger level */ static int rx_trigger_level = 56; +static int uartps_major; module_param(rx_trigger_level, uint, S_IRUGO); MODULE_PARM_DESC(rx_trigger_level, "Rx trigger level, 1-63 bytes");
@@ -1517,7 +1517,7 @@ static int cdns_uart_probe(struct platform_device *pdev) cdns_uart_uart_driver->owner = THIS_MODULE; cdns_uart_uart_driver->driver_name = driver_name; cdns_uart_uart_driver->dev_name = CDNS_UART_TTY_NAME; - cdns_uart_uart_driver->major = CDNS_UART_MAJOR; + cdns_uart_uart_driver->major = uartps_major; cdns_uart_uart_driver->minor = cdns_uart_data->id; cdns_uart_uart_driver->nr = 1;
@@ -1546,6 +1546,7 @@ static int cdns_uart_probe(struct platform_device *pdev) goto err_out_id; }
+ uartps_major = cdns_uart_uart_driver->tty_driver->major; cdns_uart_data->cdns_uart_driver = cdns_uart_uart_driver;
/*
[ Upstream commit 13b18d35909707571af9539f7731389fbf0feb31 ]
A bug was introduced by commit b3b576461864 ("tty: serial_core: convert uart_open to use tty_port_open"). It caused a constant warning printed into the system log regarding the tty and port counter mismatch:
[ 21.644197] ttyS ttySx: tty_port_close_start: tty->count = 1 port count = 2
in case if session hangup was detected so the warning is printed starting from the second open-close iteration.
Particularly the problem was discovered in situation when there is a serial tty device without hardware back-end being setup. It is considered by the tty-serial subsystems as a hardware problem with session hang up. In this case uart_startup() will return a positive value with TTY_IO_ERROR flag set in corresponding tty_struct instance. The same value will get passed to be returned from the activate() callback and then being returned from tty_port_open(). But since in this case tty_port_block_til_ready() isn't called the TTY_PORT_ACTIVE flag isn't set (while the method had been called before tty_port_open conversion was introduced and the rest of the subsystem code expected the bit being set in this case), which prevents the uart_hangup() method to perform any cleanups including the tty port counter setting to zero. So the next attempt to open/close the tty device will discover the counters mismatch.
In order to fix the problem we need to manually set the TTY_PORT_ACTIVE flag in case if uart_startup() returned a positive value. In this case the hang up procedure will perform a full set of cleanup actions including the port ref-counter resetting.
Fixes: b3b576461864 "tty: serial_core: convert uart_open to use tty_port_open" Signed-off-by: Serge Semin fancer.lancer@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/serial_core.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 83f4dd0bfd74..4223cb496764 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -1777,6 +1777,7 @@ static int uart_port_activate(struct tty_port *port, struct tty_struct *tty) { struct uart_state *state = container_of(port, struct uart_state, port); struct uart_port *uport; + int ret;
uport = uart_port_check(state); if (!uport || uport->flags & UPF_DEAD) @@ -1787,7 +1788,11 @@ static int uart_port_activate(struct tty_port *port, struct tty_struct *tty) /* * Start up the serial port. */ - return uart_startup(tty, state, 0); + ret = uart_startup(tty, state, 0); + if (ret > 0) + tty_port_set_active(port, 1); + + return ret; }
static const char *uart_type(struct uart_port *port)
[ Upstream commit 508595515f4bcfe36246e4a565cf280937aeaade ]
In some cases the "Allocate & copy" block in ffs_epfile_io() is not executed. Consequently, in such a case ffs_alloc_buffer() is never called and struct ffs_io_data is not initialized properly. This in turn leads to problems when ffs_free_buffer() is called at the end of ffs_epfile_io().
This patch uses kzalloc() instead of kmalloc() in the aio case and memset() in non-aio case to properly initialize struct ffs_io_data.
Signed-off-by: Andrzej Pietrasiewicz andrzej.p@collabora.com Signed-off-by: Felipe Balbi felipe.balbi@linux.intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/gadget/function/f_fs.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index c7ed90084d1a..213ff03c8a9f 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -1183,11 +1183,12 @@ static ssize_t ffs_epfile_write_iter(struct kiocb *kiocb, struct iov_iter *from) ENTER();
if (!is_sync_kiocb(kiocb)) { - p = kmalloc(sizeof(io_data), GFP_KERNEL); + p = kzalloc(sizeof(io_data), GFP_KERNEL); if (unlikely(!p)) return -ENOMEM; p->aio = true; } else { + memset(p, 0, sizeof(*p)); p->aio = false; }
@@ -1219,11 +1220,12 @@ static ssize_t ffs_epfile_read_iter(struct kiocb *kiocb, struct iov_iter *to) ENTER();
if (!is_sync_kiocb(kiocb)) { - p = kmalloc(sizeof(io_data), GFP_KERNEL); + p = kzalloc(sizeof(io_data), GFP_KERNEL); if (unlikely(!p)) return -ENOMEM; p->aio = true; } else { + memset(p, 0, sizeof(*p)); p->aio = false; }
[ Upstream commit dc1b5d9aed1794b5a1c6b0da46e372cc09974cbc ]
The required clocks needs to be enabled before the first register access. After commit fe8abf332b8f ("usb: dwc3: support clocks and resets for DWC3 core"), this happens when the dwc3_core_is_valid function is called, but the mentioned commit adds that call in the wrong place, before the clocks are enabled. So, move that call after the clk_bulk_enable() to ensure the clocks are enabled and the reset deasserted.
I detected this while, as experiment, I tried to move the clocks and resets from the glue layer to the DWC3 core on a Samsung Chromebook Plus.
That was not detected before because, in most cases, the glue layer initializes SoC-specific things and then populates the child "snps,dwc3" with those clocks already enabled.
Fixes: b873e2d0ea1ef ("usb: dwc3: Do core validation early on probe") Signed-off-by: Enric Balletbo i Serra enric.balletbo@collabora.com Signed-off-by: Felipe Balbi felipe.balbi@linux.intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/dwc3/core.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 4aff1d8dbc4f..6e9e172010fc 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -1423,11 +1423,6 @@ static int dwc3_probe(struct platform_device *pdev) dwc->regs = regs; dwc->regs_size = resource_size(&dwc_res);
- if (!dwc3_core_is_valid(dwc)) { - dev_err(dwc->dev, "this is not a DesignWare USB3 DRD Core\n"); - return -ENODEV; - } - dwc3_get_properties(dwc);
dwc->reset = devm_reset_control_get_optional_shared(dev, NULL); @@ -1460,6 +1455,12 @@ static int dwc3_probe(struct platform_device *pdev) if (ret) goto unprepare_clks;
+ if (!dwc3_core_is_valid(dwc)) { + dev_err(dwc->dev, "this is not a DesignWare USB3 DRD Core\n"); + ret = -ENODEV; + goto disable_clks; + } + platform_set_drvdata(pdev, dwc); dwc3_cache_hwparams(dwc);
@@ -1525,6 +1526,7 @@ static int dwc3_probe(struct platform_device *pdev) pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev);
+disable_clks: clk_bulk_disable(dwc->num_clks, dwc->clks); unprepare_clks: clk_bulk_unprepare(dwc->num_clks, dwc->clks);
[ Upstream commit c1a9acbc5295e278d788e9f7510f543bc9864fa2 ]
Intel SDM vol. 3, 5.3: The processor causes a general-protection exception (or, if the segment is SS, a stack-fault exception) any time an attempt is made to access the following addresses in a segment: - A byte at an offset greater than the effective limit - A word at an offset greater than the (effective-limit – 1) - A doubleword at an offset greater than the (effective-limit – 3) - A quadword at an offset greater than the (effective-limit – 7)
Therefore, the generic limit checking error condition must be
exn = (off > limit + 1 - access_len) = (off + access_len - 1 > limit)
but not
exn = (off + access_len > limit)
as for now.
Also avoid integer overflow of `off` at 32-bit KVM by casting it to u64.
Note: access length is currently sizeof(u64) which is incorrect. This will be fixed in the subsequent patch.
Signed-off-by: Eugene Korenevsky ekorenevsky@gmail.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/kvm/vmx/nested.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index b101127e13b6..543d7d82479b 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -4120,7 +4120,7 @@ int get_vmx_mem_address(struct kvm_vcpu *vcpu, unsigned long exit_qualification, */ if (!(s.base == 0 && s.limit == 0xffffffff && ((s.type & 8) || !(s.type & 4)))) - exn = exn || (off + sizeof(u64) > s.limit); + exn = exn || ((u64)off + sizeof(u64) - 1 > s.limit); } if (exn) { kvm_queue_exception_e(vcpu,
[ Upstream commit de23f0b757766d9fae59df97da6e8bdc5b231351 ]
The O2 controller supports 8-bit EMMC access.
JESD84-B51 section A.6.3.a defines the bus testing procedure that `mmc_select_bus_width()` implements. This is used to determine the actual bus width of the eMMC.
Signed-off-by: Raul E Rangel rrangel@chromium.org Acked-by: Adrian Hunter adrian.hunter@intel.com Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mmc/host/sdhci-pci-o2micro.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/host/sdhci-pci-o2micro.c b/drivers/mmc/host/sdhci-pci-o2micro.c index dd21315922c8..9dc4548271b4 100644 --- a/drivers/mmc/host/sdhci-pci-o2micro.c +++ b/drivers/mmc/host/sdhci-pci-o2micro.c @@ -395,11 +395,21 @@ int sdhci_pci_o2_probe_slot(struct sdhci_pci_slot *slot) { struct sdhci_pci_chip *chip; struct sdhci_host *host; - u32 reg; + u32 reg, caps; int ret;
chip = slot->chip; host = slot->host; + + caps = sdhci_readl(host, SDHCI_CAPABILITIES); + + /* + * mmc_select_bus_width() will test the bus to determine the actual bus + * width. + */ + if (caps & SDHCI_CAN_DO_8BIT) + host->mmc->caps |= MMC_CAP_8_BIT_DATA; + switch (chip->pdev->device) { case PCI_DEVICE_ID_O2_SDS0: case PCI_DEVICE_ID_O2_SEABIRD0:
[ Upstream commit b643780562af5378ef7fe731c65b8f93e49c59c6 ]
VMMs frequently read the guest's CS and SS AR bytes to detect 64-bit mode and CPL respectively, but effectively never write said fields once the VM is initialized. Intercepting VMWRITEs for the two fields saves ~55 cycles in copy_shadow_to_vmcs12().
Because some Intel CPUs, e.g. Haswell, drop the reserved bits of the guest access rights fields on VMWRITE, exposing the fields to L1 for VMREAD but not VMWRITE leads to inconsistent behavior between L1 and L2. On hardware that drops the bits, L1 will see the stripped down value due to reading the value from hardware, while L2 will see the full original value as stored by KVM. To avoid such an inconsistency, emulate the behavior on all CPUS, but only for intercepted VMWRITEs so as to avoid introducing pointless latency into copy_shadow_to_vmcs12(), e.g. if the emulation were added to vmcs12_write_any().
Since the AR_BYTES emulation is done only for intercepted VMWRITE, if a future patch (re)exposed AR_BYTES for both VMWRITE and VMREAD, then KVM would end up with incosistent behavior on pre-Haswell hardware, e.g. KVM would drop the reserved bits on intercepted VMWRITE, but direct VMWRITE to the shadow VMCS would not drop the bits. Add a WARN in the shadow field initialization to detect any attempt to expose an AR_BYTES field without updating vmcs12_write_any().
Note, emulation of the AR_BYTES reserved bit behavior is based on a patch[1] from Jim Mattson that applied the emulation to all writes to vmcs12 so that live migration across different generations of hardware would not introduce divergent behavior. But given that live migration of nested state has already been enabled, that ship has sailed (not to mention that no sane VMM will be affected by this behavior).
[1] https://patchwork.kernel.org/patch/10483321/
Cc: Jim Mattson jmattson@google.com Cc: Liran Alon liran.alon@oracle.com Signed-off-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/nested.c | 15 +++++++++++++++ arch/x86/kvm/vmx/vmcs_shadow_fields.h | 4 ++-- 2 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 543d7d82479b..ac98b1328124 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -91,6 +91,10 @@ static void init_vmcs_shadow_fields(void) pr_err("Missing field from shadow_read_write_field %x\n", field + 1);
+ WARN_ONCE(field >= GUEST_ES_AR_BYTES && + field <= GUEST_TR_AR_BYTES, + "Update vmcs12_write_any() to expose AR_BYTES RW"); + /* * PML and the preemption timer can be emulated, but the * processor cannot vmwrite to fields that don't exist @@ -4500,6 +4504,17 @@ static int handle_vmwrite(struct kvm_vcpu *vcpu) vmcs12 = get_shadow_vmcs12(vcpu); }
+ /* + * Some Intel CPUs intentionally drop the reserved bits of the AR byte + * fields on VMWRITE. Emulate this behavior to ensure consistent KVM + * behavior regardless of the underlying hardware, e.g. if an AR_BYTE + * field is intercepted for VMWRITE but not VMREAD (in L1), then VMREAD + * from L1 will return a different value than VMREAD from L2 (L1 sees + * the stripped down value, L2 sees the full value as stored by KVM). + */ + if (field >= GUEST_ES_AR_BYTES && field <= GUEST_TR_AR_BYTES) + field_value &= 0x1f0ff; + if (vmcs12_write_any(vmcs12, field, field_value) < 0) return nested_vmx_failValid(vcpu, VMXERR_UNSUPPORTED_VMCS_COMPONENT); diff --git a/arch/x86/kvm/vmx/vmcs_shadow_fields.h b/arch/x86/kvm/vmx/vmcs_shadow_fields.h index 132432f375c2..97dd5295be31 100644 --- a/arch/x86/kvm/vmx/vmcs_shadow_fields.h +++ b/arch/x86/kvm/vmx/vmcs_shadow_fields.h @@ -40,14 +40,14 @@ SHADOW_FIELD_RO(VM_EXIT_INSTRUCTION_LEN) SHADOW_FIELD_RO(IDT_VECTORING_INFO_FIELD) SHADOW_FIELD_RO(IDT_VECTORING_ERROR_CODE) SHADOW_FIELD_RO(VM_EXIT_INTR_ERROR_CODE) +SHADOW_FIELD_RO(GUEST_CS_AR_BYTES) +SHADOW_FIELD_RO(GUEST_SS_AR_BYTES) SHADOW_FIELD_RW(CPU_BASED_VM_EXEC_CONTROL) SHADOW_FIELD_RW(EXCEPTION_BITMAP) SHADOW_FIELD_RW(VM_ENTRY_EXCEPTION_ERROR_CODE) SHADOW_FIELD_RW(VM_ENTRY_INTR_INFO_FIELD) SHADOW_FIELD_RW(VM_ENTRY_INSTRUCTION_LEN) SHADOW_FIELD_RW(TPR_THRESHOLD) -SHADOW_FIELD_RW(GUEST_CS_AR_BYTES) -SHADOW_FIELD_RW(GUEST_SS_AR_BYTES) SHADOW_FIELD_RW(GUEST_INTERRUPTIBILITY_INFO) SHADOW_FIELD_RW(VMX_PREEMPTION_TIMER_VALUE)
[ Upstream commit fdb28619a8f033c13f5d9b9e8b5536bb6e68a2c3 ]
There is an imperfection in get_vmx_mem_address(): access length is ignored when checking the limit. To fix this, pass access length as a function argument. The access length is usually obvious since it is used by callers after get_vmx_mem_address() call, but for vmread/vmwrite it depends on the state of 64-bit mode.
Signed-off-by: Eugene Korenevsky ekorenevsky@gmail.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/kvm/vmx/nested.c | 28 ++++++++++++++++------------ arch/x86/kvm/vmx/nested.h | 2 +- arch/x86/kvm/vmx/vmx.c | 3 ++- 3 files changed, 19 insertions(+), 14 deletions(-)
diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index ac98b1328124..c1d118f4dc72 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -4017,7 +4017,7 @@ void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 exit_reason, * #UD or #GP. */ int get_vmx_mem_address(struct kvm_vcpu *vcpu, unsigned long exit_qualification, - u32 vmx_instruction_info, bool wr, gva_t *ret) + u32 vmx_instruction_info, bool wr, int len, gva_t *ret) { gva_t off; bool exn; @@ -4124,7 +4124,7 @@ int get_vmx_mem_address(struct kvm_vcpu *vcpu, unsigned long exit_qualification, */ if (!(s.base == 0 && s.limit == 0xffffffff && ((s.type & 8) || !(s.type & 4)))) - exn = exn || ((u64)off + sizeof(u64) - 1 > s.limit); + exn = exn || ((u64)off + len - 1 > s.limit); } if (exn) { kvm_queue_exception_e(vcpu, @@ -4143,7 +4143,8 @@ static int nested_vmx_get_vmptr(struct kvm_vcpu *vcpu, gpa_t *vmpointer) struct x86_exception e;
if (get_vmx_mem_address(vcpu, vmcs_readl(EXIT_QUALIFICATION), - vmcs_read32(VMX_INSTRUCTION_INFO), false, &gva)) + vmcs_read32(VMX_INSTRUCTION_INFO), false, + sizeof(*vmpointer), &gva)) return 1;
if (kvm_read_guest_virt(vcpu, gva, vmpointer, sizeof(*vmpointer), &e)) { @@ -4394,6 +4395,7 @@ static int handle_vmread(struct kvm_vcpu *vcpu) u64 field_value; unsigned long exit_qualification = vmcs_readl(EXIT_QUALIFICATION); u32 vmx_instruction_info = vmcs_read32(VMX_INSTRUCTION_INFO); + int len; gva_t gva = 0; struct vmcs12 *vmcs12;
@@ -4431,12 +4433,12 @@ static int handle_vmread(struct kvm_vcpu *vcpu) kvm_register_writel(vcpu, (((vmx_instruction_info) >> 3) & 0xf), field_value); } else { + len = is_64_bit_mode(vcpu) ? 8 : 4; if (get_vmx_mem_address(vcpu, exit_qualification, - vmx_instruction_info, true, &gva)) + vmx_instruction_info, true, len, &gva)) return 1; /* _system ok, nested_vmx_check_permission has verified cpl=0 */ - kvm_write_guest_virt_system(vcpu, gva, &field_value, - (is_long_mode(vcpu) ? 8 : 4), NULL); + kvm_write_guest_virt_system(vcpu, gva, &field_value, len, NULL); }
return nested_vmx_succeed(vcpu); @@ -4446,6 +4448,7 @@ static int handle_vmread(struct kvm_vcpu *vcpu) static int handle_vmwrite(struct kvm_vcpu *vcpu) { unsigned long field; + int len; gva_t gva; struct vcpu_vmx *vmx = to_vmx(vcpu); unsigned long exit_qualification = vmcs_readl(EXIT_QUALIFICATION); @@ -4471,11 +4474,11 @@ static int handle_vmwrite(struct kvm_vcpu *vcpu) field_value = kvm_register_readl(vcpu, (((vmx_instruction_info) >> 3) & 0xf)); else { + len = is_64_bit_mode(vcpu) ? 8 : 4; if (get_vmx_mem_address(vcpu, exit_qualification, - vmx_instruction_info, false, &gva)) + vmx_instruction_info, false, len, &gva)) return 1; - if (kvm_read_guest_virt(vcpu, gva, &field_value, - (is_64_bit_mode(vcpu) ? 8 : 4), &e)) { + if (kvm_read_guest_virt(vcpu, gva, &field_value, len, &e)) { kvm_inject_page_fault(vcpu, &e); return 1; } @@ -4634,7 +4637,8 @@ static int handle_vmptrst(struct kvm_vcpu *vcpu) if (unlikely(to_vmx(vcpu)->nested.hv_evmcs)) return 1;
- if (get_vmx_mem_address(vcpu, exit_qual, instr_info, true, &gva)) + if (get_vmx_mem_address(vcpu, exit_qual, instr_info, + true, sizeof(gpa_t), &gva)) return 1; /* *_system ok, nested_vmx_check_permission has verified cpl=0 */ if (kvm_write_guest_virt_system(vcpu, gva, (void *)¤t_vmptr, @@ -4680,7 +4684,7 @@ static int handle_invept(struct kvm_vcpu *vcpu) * operand is read even if it isn't needed (e.g., for type==global) */ if (get_vmx_mem_address(vcpu, vmcs_readl(EXIT_QUALIFICATION), - vmx_instruction_info, false, &gva)) + vmx_instruction_info, false, sizeof(operand), &gva)) return 1; if (kvm_read_guest_virt(vcpu, gva, &operand, sizeof(operand), &e)) { kvm_inject_page_fault(vcpu, &e); @@ -4742,7 +4746,7 @@ static int handle_invvpid(struct kvm_vcpu *vcpu) * operand is read even if it isn't needed (e.g., for type==global) */ if (get_vmx_mem_address(vcpu, vmcs_readl(EXIT_QUALIFICATION), - vmx_instruction_info, false, &gva)) + vmx_instruction_info, false, sizeof(operand), &gva)) return 1; if (kvm_read_guest_virt(vcpu, gva, &operand, sizeof(operand), &e)) { kvm_inject_page_fault(vcpu, &e); diff --git a/arch/x86/kvm/vmx/nested.h b/arch/x86/kvm/vmx/nested.h index e847ff1019a2..29d205bb4e4f 100644 --- a/arch/x86/kvm/vmx/nested.h +++ b/arch/x86/kvm/vmx/nested.h @@ -21,7 +21,7 @@ void nested_sync_from_vmcs12(struct kvm_vcpu *vcpu); int vmx_set_vmx_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data); int vmx_get_vmx_msr(struct nested_vmx_msrs *msrs, u32 msr_index, u64 *pdata); int get_vmx_mem_address(struct kvm_vcpu *vcpu, unsigned long exit_qualification, - u32 vmx_instruction_info, bool wr, gva_t *ret); + u32 vmx_instruction_info, bool wr, int len, gva_t *ret);
static inline struct vmcs12 *get_vmcs12(struct kvm_vcpu *vcpu) { diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 306ed28569c0..924c2a79e4a9 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -5349,7 +5349,8 @@ static int handle_invpcid(struct kvm_vcpu *vcpu) * is read even if it isn't needed (e.g., for type==all) */ if (get_vmx_mem_address(vcpu, vmcs_readl(EXIT_QUALIFICATION), - vmx_instruction_info, false, &gva)) + vmx_instruction_info, false, + sizeof(operand), &gva)) return 1;
if (kvm_read_guest_virt(vcpu, gva, &operand, sizeof(operand), &e)) {
[ Upstream commit 6672e11cad662ce6631e04c38f92a140a99c042c ]
Before loading the zap shader we should ensure that the reserved memory region is big enough to hold the loaded file.
Signed-off-by: Jordan Crouse jcrouse@codeaurora.org Reviewed-by: Bjorn Andersson bjorn.andersson@linaro.org Reviewed-by: Jeffrey Hugo jeffrey.l.hugo@gmail.com Signed-off-by: Rob Clark robdclark@chromium.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index a9c0ac937b00..9acbbc0f3232 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -56,7 +56,6 @@ static int zap_shader_load_mdt(struct msm_gpu *gpu, const char *fwname, return ret;
mem_phys = r.start; - mem_size = resource_size(&r);
/* Request the MDT file for the firmware */ fw = adreno_request_fw(to_adreno_gpu(gpu), fwname); @@ -72,6 +71,13 @@ static int zap_shader_load_mdt(struct msm_gpu *gpu, const char *fwname, goto out; }
+ if (mem_size > resource_size(&r)) { + DRM_DEV_ERROR(dev, + "memory region is too small to load the MDT\n"); + ret = -E2BIG; + goto out; + } + /* Allocate memory for the firmware image */ mem_region = memremap(mem_phys, mem_size, MEMREMAP_WC); if (!mem_region) {
[ Upstream commit df5be5be8735ef2ae80d5ae1f2453cd81a035c4b ]
When the firmware does PCI BAR resource allocation, it passes the assigned addresses and flags (prefetch/64bit/...) via the "reg" property of a PCI device device tree node so the kernel does not need to do resource allocation.
The flags are stored in resource::flags - the lower byte stores PCI_BASE_ADDRESS_SPACE/etc bits and the other bytes are IORESOURCE_IO/etc. Some flags from PCI_BASE_ADDRESS_xxx and IORESOURCE_xxx are duplicated, such as PCI_BASE_ADDRESS_MEM_PREFETCH/PCI_BASE_ADDRESS_MEM_TYPE_64/etc. When parsing the "reg" property, we copy the prefetch flag but we skip on PCI_BASE_ADDRESS_MEM_TYPE_64 which leaves the flags out of sync.
The missing IORESOURCE_MEM_64 flag comes into play under 2 conditions: 1. we remove PCI_PROBE_ONLY for pseries (by hacking pSeries_setup_arch() or by passing "/chosen/linux,pci-probe-only"); 2. we request resource alignment (by passing pci=resource_alignment= via the kernel cmd line to request PAGE_SIZE alignment or defining ppc_md.pcibios_default_alignment which returns anything but 0). Note that the alignment requests are ignored if PCI_PROBE_ONLY is enabled.
With 1) and 2), the generic PCI code in the kernel unconditionally decides to: - reassign the BARs in pci_specified_resource_alignment() (works fine) - write new BARs to the device - this fails for 64bit BARs as the generic code looks at IORESOURCE_MEM_64 (not set) and writes only lower 32bits of the BAR and leaves the upper 32bit unmodified which breaks BAR mapping in the hypervisor.
This fixes the issue by copying the flag. This is useful if we want to enforce certain BAR alignment per platform as handling subpage sized BARs is proven to cause problems with hotplug (SLOF already aligns BARs to 64k).
Signed-off-by: Alexey Kardashevskiy aik@ozlabs.ru Reviewed-by: Sam Bobroff sbobroff@linux.ibm.com Reviewed-by: Oliver O'Halloran oohall@gmail.com Reviewed-by: Shawn Anastasio shawn@anastas.io Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/kernel/pci_of_scan.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c index 24522aa37665..c63c53b37e8e 100644 --- a/arch/powerpc/kernel/pci_of_scan.c +++ b/arch/powerpc/kernel/pci_of_scan.c @@ -42,6 +42,8 @@ unsigned int pci_parse_of_flags(u32 addr0, int bridge) if (addr0 & 0x02000000) { flags = IORESOURCE_MEM | PCI_BASE_ADDRESS_SPACE_MEMORY; flags |= (addr0 >> 22) & PCI_BASE_ADDRESS_MEM_TYPE_64; + if (flags & PCI_BASE_ADDRESS_MEM_TYPE_64) + flags |= IORESOURCE_MEM_64; flags |= (addr0 >> 28) & PCI_BASE_ADDRESS_MEM_TYPE_1M; if (addr0 & 0x40000000) flags |= IORESOURCE_PREFETCH
[ Upstream commit 4368a1539c6b41ac3cddc06f5a5117952998804c ]
add_display_components() calls of_platform_populate, and we depopluate on pdev remove, but not when probe fails. So if we get a probe deferral in one of the components, we won't depopulate the platform. This causes the core to keep references to devices which should be destroyed, which causes issues when those same devices try to re-initialize on the next probe attempt.
I think this is the reason we had issues with the gmu's device-managed resources on deferral (worked around in commit 94e3a17f33a5).
Reviewed-by: Rob Clark robdclark@chromium.org Signed-off-by: Sean Paul seanpaul@chromium.org Link: https://patchwork.freedesktop.org/patch/msgid/20190617201301.133275-3-sean@p... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/msm_drv.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index f38d7367bd3b..4a0fe8a25ad7 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -1306,16 +1306,24 @@ static int msm_pdev_probe(struct platform_device *pdev)
ret = add_gpu_components(&pdev->dev, &match); if (ret) - return ret; + goto fail;
/* on all devices that I am aware of, iommu's which can map * any address the cpu can see are used: */ ret = dma_set_mask_and_coherent(&pdev->dev, ~0); if (ret) - return ret; + goto fail; + + ret = component_master_add_with_match(&pdev->dev, &msm_drm_ops, match); + if (ret) + goto fail;
- return component_master_add_with_match(&pdev->dev, &msm_drm_ops, match); + return 0; + +fail: + of_platform_depopulate(&pdev->dev); + return ret; }
static int msm_pdev_remove(struct platform_device *pdev)
[ Upstream commit d99482673f950817b30caf3fcdfb31179b050ce1 ]
This patch adds a check for the GPIOs property existence, before the GPIO is requested. This fixes an issue seen when the 8250 mctrl_gpio support is added (2nd patch in this patch series) on x86 platforms using ACPI.
Here Mika's comments from 2016-08-09:
" I noticed that with v4.8-rc1 serial console of some of our Broxton systems does not work properly anymore. I'm able to see output but input does not work.
I bisected it down to commit 4ef03d328769eddbfeca1f1c958fdb181a69c341 ("tty/serial/8250: use mctrl_gpio helpers").
The reason why it fails is that in ACPI we do not have names for GPIOs (except when _DSD is used) so we use the "idx" to index into _CRS GPIO resources. Now mctrl_gpio_init_noauto() goes through a list of GPIOs calling devm_gpiod_get_index_optional() passing "idx" of 0 for each. The UART device in Broxton has following (simplified) ACPI description:
Device (URT4) { ... Name (_CRS, ResourceTemplate () { GpioIo (Exclusive, PullDefault, 0x0000, 0x0000, IoRestrictionOutputOnly, "\_SB.GPO0", 0x00, ResourceConsumer) { 0x003A } GpioIo (Exclusive, PullDefault, 0x0000, 0x0000, IoRestrictionOutputOnly, "\_SB.GPO0", 0x00, ResourceConsumer) { 0x003D } })
In this case it finds the first GPIO (0x003A which happens to be RX pin for that UART), turns it into GPIO which then breaks input for the UART device. This also breaks systems with bluetooth connected to UART (those typically have some GPIOs in their _CRS).
Any ideas how to fix this?
We cannot just drop the _CRS index lookup fallback because that would break many existing machines out there so maybe we can limit this to only DT enabled machines. Or alternatively probe if the property first exists before trying to acquire the GPIOs (using device_property_present()). "
This patch implements the fix suggested by Mika in his statement above.
Signed-off-by: Stefan Roese sr@denx.de Reviewed-by: Mika Westerberg mika.westerberg@linux.intel.com Reviewed-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Tested-by: Yegor Yefremov yegorslists@googlemail.com Cc: Mika Westerberg mika.westerberg@linux.intel.com Cc: Andy Shevchenko andriy.shevchenko@linux.intel.com Cc: Yegor Yefremov yegorslists@googlemail.com Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: Giulio Benetti giulio.benetti@micronovasrl.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/serial_mctrl_gpio.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
diff --git a/drivers/tty/serial/serial_mctrl_gpio.c b/drivers/tty/serial/serial_mctrl_gpio.c index 39ed56214cd3..2b400189be91 100644 --- a/drivers/tty/serial/serial_mctrl_gpio.c +++ b/drivers/tty/serial/serial_mctrl_gpio.c @@ -12,6 +12,7 @@ #include <linux/termios.h> #include <linux/serial_core.h> #include <linux/module.h> +#include <linux/property.h>
#include "serial_mctrl_gpio.h"
@@ -116,6 +117,19 @@ struct mctrl_gpios *mctrl_gpio_init_noauto(struct device *dev, unsigned int idx)
for (i = 0; i < UART_GPIO_MAX; i++) { enum gpiod_flags flags; + char *gpio_str; + bool present; + + /* Check if GPIO property exists and continue if not */ + gpio_str = kasprintf(GFP_KERNEL, "%s-gpios", + mctrl_gpios_desc[i].name); + if (!gpio_str) + continue; + + present = device_property_present(dev, gpio_str); + kfree(gpio_str); + if (!present) + continue;
if (mctrl_gpios_desc[i].dir_out) flags = GPIOD_OUT_LOW;
[ Upstream commit 5c9dc6379f539c68a0fdd39e39a9d359545649e9 ]
The powered flag should be set for any other phys anyway. Also the flag should be locked by the channel. Otherwise, after we have revised the device tree for the usb phy, the following warning happened during a second system suspend. And if the driver doesn't lock the flag, an imbalance is possible when enabling the regulator during system resume. So, this patch fixes the issues.
< The warning > [ 56.026531] unbalanced disables for USB20_VBUS0 [ 56.031108] WARNING: CPU: 3 PID: 513 at drivers/regulator/core.c:2593 _regula tor_disable+0xe0/0x1c0 [ 56.040146] Modules linked in: rcar_du_drm rcar_lvds drm_kms_helper drm drm_p anel_orientation_quirks vsp1 videobuf2_vmalloc videobuf2_dma_contig videobuf2_me mops videobuf2_v4l2 videobuf2_common videodev snd_soc_rcar renesas_usbhs snd_soc _audio_graph_card media snd_soc_simple_card_utils crct10dif_ce renesas_usb3 snd_ soc_ak4613 rcar_fcp pwm_rcar usb_dmac phy_rcar_gen3_usb3 pwm_bl ipv6 [ 56.074047] CPU: 3 PID: 513 Comm: kworker/u16:19 Not tainted 5.2.0-rc3-00001- g5f20a19 #6 [ 56.082129] Hardware name: Renesas Salvator-X board based on r8a7795 ES2.0+ ( DT) [ 56.089524] Workqueue: events_unbound async_run_entry_fn [ 56.094832] pstate: 40000005 (nZcv daif -PAN -UAO) [ 56.099617] pc : _regulator_disable+0xe0/0x1c0 [ 56.104054] lr : _regulator_disable+0xe0/0x1c0 [ 56.108489] sp : ffff0000121c3ae0 [ 56.111796] x29: ffff0000121c3ae0 x28: 0000000000000000 [ 56.117102] x27: 0000000000000000 x26: ffff000010fe0e60 [ 56.122407] x25: 0000000000000002 x24: 0000000000000001 [ 56.127712] x23: 0000000000000002 x22: ffff8006f99d4000 [ 56.133017] x21: ffff8006f99cc000 x20: ffff8006f9846800 [ 56.138322] x19: ffff8006f9846800 x18: ffffffffffffffff [ 56.143626] x17: 0000000000000000 x16: 0000000000000000 [ 56.148931] x15: ffff0000112f96c8 x14: ffff0000921c37f7 [ 56.154235] x13: ffff0000121c3805 x12: ffff000011312000 [ 56.159540] x11: 0000000005f5e0ff x10: ffff0000112f9f20 [ 56.164844] x9 : ffff0000112d3018 x8 : 00000000000001ad [ 56.170149] x7 : 00000000ffffffcc x6 : ffff8006ff768180 [ 56.175453] x5 : ffff8006ff768180 x4 : 0000000000000000 [ 56.180758] x3 : ffff8006ff76ef10 x2 : ffff8006ff768180 [ 56.186062] x1 : 3d2eccbaead8fb00 x0 : 0000000000000000 [ 56.191367] Call trace: [ 56.193808] _regulator_disable+0xe0/0x1c0 [ 56.197899] regulator_disable+0x40/0x78 [ 56.201820] rcar_gen3_phy_usb2_power_off+0x3c/0x50 [ 56.206692] phy_power_off+0x48/0xd8 [ 56.210263] usb_phy_roothub_power_off+0x30/0x50 [ 56.214873] usb_phy_roothub_suspend+0x1c/0x50 [ 56.219311] hcd_bus_suspend+0x13c/0x168 [ 56.223226] generic_suspend+0x4c/0x58 [ 56.226969] usb_suspend_both+0x1ac/0x238 [ 56.230972] usb_suspend+0xcc/0x170 [ 56.234455] usb_dev_suspend+0x10/0x18 [ 56.238199] dpm_run_callback.isra.6+0x20/0x68 [ 56.242635] __device_suspend+0x110/0x308 [ 56.246637] async_suspend+0x24/0xa8 [ 56.250205] async_run_entry_fn+0x40/0xf8 [ 56.254210] process_one_work+0x1e0/0x320 [ 56.258211] worker_thread+0x40/0x450 [ 56.261867] kthread+0x124/0x128 [ 56.265094] ret_from_fork+0x10/0x18 [ 56.268661] ---[ end trace 86d7ec5de5c517af ]--- [ 56.273290] phy phy-ee080200.usb-phy.10: phy poweroff failed --> -5
Reported-by: Geert Uytterhoeven geert+renesas@glider.be Fixes: 549b6b55b005 ("phy: renesas: rcar-gen3-usb2: enable/disable independent irqs") Signed-off-by: Yoshihiro Shimoda yoshihiro.shimoda.uh@renesas.com Reviewed-by: Geert Uytterhoeven geert+renesas@glider.be Tested-by: Geert Uytterhoeven geert+renesas@glider.be Reviewed-by: Simon Horman horms+renesas@verge.net.au Signed-off-by: Kishon Vijay Abraham I kishon@ti.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/phy/renesas/phy-rcar-gen3-usb2.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c index 1322185a00a2..8ffba67568ec 100644 --- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c +++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c @@ -13,6 +13,7 @@ #include <linux/interrupt.h> #include <linux/io.h> #include <linux/module.h> +#include <linux/mutex.h> #include <linux/of.h> #include <linux/of_address.h> #include <linux/of_device.h> @@ -106,6 +107,7 @@ struct rcar_gen3_chan { struct rcar_gen3_phy rphys[NUM_OF_PHYS]; struct regulator *vbus; struct work_struct work; + struct mutex lock; /* protects rphys[...].powered */ enum usb_dr_mode dr_mode; bool extcon_host; bool is_otg_channel; @@ -437,15 +439,16 @@ static int rcar_gen3_phy_usb2_power_on(struct phy *p) struct rcar_gen3_chan *channel = rphy->ch; void __iomem *usb2_base = channel->base; u32 val; - int ret; + int ret = 0;
+ mutex_lock(&channel->lock); if (!rcar_gen3_are_all_rphys_power_off(channel)) - return 0; + goto out;
if (channel->vbus) { ret = regulator_enable(channel->vbus); if (ret) - return ret; + goto out; }
val = readl(usb2_base + USB2_USBCTR); @@ -454,7 +457,10 @@ static int rcar_gen3_phy_usb2_power_on(struct phy *p) val &= ~USB2_USBCTR_PLL_RST; writel(val, usb2_base + USB2_USBCTR);
+out: + /* The powered flag should be set for any other phys anyway */ rphy->powered = true; + mutex_unlock(&channel->lock);
return 0; } @@ -465,14 +471,18 @@ static int rcar_gen3_phy_usb2_power_off(struct phy *p) struct rcar_gen3_chan *channel = rphy->ch; int ret = 0;
+ mutex_lock(&channel->lock); rphy->powered = false;
if (!rcar_gen3_are_all_rphys_power_off(channel)) - return 0; + goto out;
if (channel->vbus) ret = regulator_disable(channel->vbus);
+out: + mutex_unlock(&channel->lock); + return ret; }
@@ -639,6 +649,7 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev) if (!phy_usb2_ops) return -EINVAL;
+ mutex_init(&channel->lock); for (i = 0; i < NUM_OF_PHYS; i++) { channel->rphys[i].phy = devm_phy_create(dev, NULL, phy_usb2_ops);
[ Upstream commit dc6b698a86fe40a50525433eb8e92a267847f6f9 ]
With CONFIG_PROVE_LOCKING=y, using sysfs to remove a bridge with a device below it causes a lockdep warning, e.g.,
# echo 1 > /sys/class/pci_bus/0000:00/device/0000:00:00.0/remove ============================================ WARNING: possible recursive locking detected ... pci_bus 0000:01: busn_res: [bus 01] is released
The remove recursively removes the subtree below the bridge. Each call uses a different lock so there's no deadlock, but the locks were all created with the same lockdep key so the lockdep checker can't tell them apart.
Mark the "remove" sysfs attribute with __ATTR_IGNORE_LOCKDEP() as it is safe to ignore the lockdep check between different "remove" kernfs instances.
There's discussion about a similar issue in USB at [1], which resulted in 356c05d58af0 ("sysfs: get rid of some lockdep false positives") and e9b526fe7048 ("i2c: suppress lockdep warning on delete_device"), which do basically the same thing for USB "remove" and i2c "delete_device" files.
[1] https://lore.kernel.org/r/Pine.LNX.4.44L0.1204251436140.1206-100000@iolanthe... Link: https://lore.kernel.org/r/20190526225151.3865-1-marek.vasut@gmail.com Signed-off-by: Marek Vasut marek.vasut+renesas@gmail.com [bhelgaas: trim commit log, details at above links] Signed-off-by: Bjorn Helgaas bhelgaas@google.com Cc: Geert Uytterhoeven geert+renesas@glider.be Cc: Phil Edworthy phil.edworthy@renesas.com Cc: Simon Horman horms+renesas@verge.net.au Cc: Tejun Heo tj@kernel.org Cc: Wolfram Sang wsa@the-dreams.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/pci-sysfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 6d27475e39b2..4e83c347de5d 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -477,7 +477,7 @@ static ssize_t remove_store(struct device *dev, struct device_attribute *attr, pci_stop_and_remove_bus_device_locked(to_pci_dev(dev)); return count; } -static struct device_attribute dev_remove_attr = __ATTR(remove, +static struct device_attribute dev_remove_attr = __ATTR_IGNORE_LOCKDEP(remove, (S_IWUSR|S_IWGRP), NULL, remove_store);
[ Upstream commit 79b4499524ed659fb76323efc30f3dc03967c88f ]
During probe, return the "get_irq" error value instead of -EINVAL which allows the driver to be deferred probed if needed. Fix also the case where of_irq_get() returns a negative value. Note : On failure of_irq_get() returns 0 or a negative value while platform_get_irq() returns a negative value.
Fixes: aeb068c57214 ("i2c: i2c-stm32f7: add driver") Reviewed-by: Pierre-Yves MORDRET pierre-yves.mordret@st.com Signed-off-by: Fabien Dessenne fabien.dessenne@st.com Signed-off-by: Fabrice Gasnier fabrice.gasnier@st.com Signed-off-by: Wolfram Sang wsa@the-dreams.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/i2c/busses/i2c-stm32f7.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-)
diff --git a/drivers/i2c/busses/i2c-stm32f7.c b/drivers/i2c/busses/i2c-stm32f7.c index 48337bef5b87..3d90c0bb049e 100644 --- a/drivers/i2c/busses/i2c-stm32f7.c +++ b/drivers/i2c/busses/i2c-stm32f7.c @@ -25,7 +25,6 @@ #include <linux/module.h> #include <linux/of.h> #include <linux/of_address.h> -#include <linux/of_irq.h> #include <linux/of_platform.h> #include <linux/platform_device.h> #include <linux/pinctrl/consumer.h> @@ -1816,15 +1815,14 @@ static struct i2c_algorithm stm32f7_i2c_algo = {
static int stm32f7_i2c_probe(struct platform_device *pdev) { - struct device_node *np = pdev->dev.of_node; struct stm32f7_i2c_dev *i2c_dev; const struct stm32f7_i2c_setup *setup; struct resource *res; - u32 irq_error, irq_event, clk_rate, rise_time, fall_time; + u32 clk_rate, rise_time, fall_time; struct i2c_adapter *adap; struct reset_control *rst; dma_addr_t phy_addr; - int ret; + int irq_error, irq_event, ret;
i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL); if (!i2c_dev) @@ -1836,16 +1834,20 @@ static int stm32f7_i2c_probe(struct platform_device *pdev) return PTR_ERR(i2c_dev->base); phy_addr = (dma_addr_t)res->start;
- irq_event = irq_of_parse_and_map(np, 0); - if (!irq_event) { - dev_err(&pdev->dev, "IRQ event missing or invalid\n"); - return -EINVAL; + irq_event = platform_get_irq(pdev, 0); + if (irq_event <= 0) { + if (irq_event != -EPROBE_DEFER) + dev_err(&pdev->dev, "Failed to get IRQ event: %d\n", + irq_event); + return irq_event ? : -ENOENT; }
- irq_error = irq_of_parse_and_map(np, 1); - if (!irq_error) { - dev_err(&pdev->dev, "IRQ error missing or invalid\n"); - return -EINVAL; + irq_error = platform_get_irq(pdev, 1); + if (irq_error <= 0) { + if (irq_error != -EPROBE_DEFER) + dev_err(&pdev->dev, "Failed to get IRQ error: %d\n", + irq_error); + return irq_error ? : -ENOENT; }
i2c_dev->clk = devm_clk_get(&pdev->dev, NULL);
[ Upstream commit 25cec756891e8733433efea63b2254ddc93aa5cc ]
empty_child_inc/dec() use the ternary operator for conditional operations. The conditions involve the post/pre in/decrement operator and the operation is only performed when the condition is *not* true. This is hard to parse for humans, use a regular 'if' construct instead and perform the in/decrement separately.
This also fixes two warnings that are emitted about the value of the ternary expression being unused, when building the kernel with clang + "kbuild: Remove unnecessary -Wno-unused-value" (https://lore.kernel.org/patchwork/patch/1089869/):
CC net/ipv4/fib_trie.o net/ipv4/fib_trie.c:351:2: error: expression result unused [-Werror,-Wunused-value] ++tn_info(n)->empty_children ? : ++tn_info(n)->full_children;
Fixes: 95f60ea3e99a ("fib_trie: Add collapse() and should_collapse() to resize") Signed-off-by: Matthias Kaehlcke mka@chromium.org Reviewed-by: Douglas Anderson dianders@chromium.org Reviewed-by: Nick Desaulniers ndesaulniers@google.com Acked-by: Alexander Duyck alexander.h.duyck@linux.intel.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- scripts/Makefile.extrawarn | 1 - 1 file changed, 1 deletion(-)
diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn index 3ab8d1a303cd..b293246e48fe 100644 --- a/scripts/Makefile.extrawarn +++ b/scripts/Makefile.extrawarn @@ -68,7 +68,6 @@ else
ifdef CONFIG_CC_IS_CLANG KBUILD_CFLAGS += -Wno-initializer-overrides -KBUILD_CFLAGS += -Wno-unused-value KBUILD_CFLAGS += -Wno-format KBUILD_CFLAGS += -Wno-sign-compare KBUILD_CFLAGS += -Wno-format-zero-length
Hi Greg,
Toralf just pointed out in another thread that the commit message and the content of this patch don't match (https://lkml.org/lkml/2019/7/29/1475)
I did some minor digging, the content of the queued patch is:
commit 4df607cc6fe8e46b258ff2a53d0a60ca3008ffc7 Author: Nathan Huckleberry nhuck@google.com Date: Mon Jun 17 10:28:29 2019 -0700
kbuild: Remove unnecessary -Wno-unused-value
however the commit message is from:
commit 25cec756891e8733433efea63b2254ddc93aa5cc Author: Matthias Kaehlcke mka@chromium.org Date: Tue Jun 18 14:14:40 2019 -0700
net/ipv4: fib_trie: Avoid cryptic ternary expressions
It seems this hasn't been commited to -stable yet, so we are probably in time to remove it from the queue before it becomes git history and have Nathan re-spin the patch(es).
On Mon, Jul 29, 2019 at 09:21:19PM +0200, Greg Kroah-Hartman wrote:
[ Upstream commit 25cec756891e8733433efea63b2254ddc93aa5cc ]
empty_child_inc/dec() use the ternary operator for conditional operations. The conditions involve the post/pre in/decrement operator and the operation is only performed when the condition is *not* true. This is hard to parse for humans, use a regular 'if' construct instead and perform the in/decrement separately.
This also fixes two warnings that are emitted about the value of the ternary expression being unused, when building the kernel with clang + "kbuild: Remove unnecessary -Wno-unused-value" (https://lore.kernel.org/patchwork/patch/1089869/):
CC net/ipv4/fib_trie.o net/ipv4/fib_trie.c:351:2: error: expression result unused [-Werror,-Wunused-value] ++tn_info(n)->empty_children ? : ++tn_info(n)->full_children;
Fixes: 95f60ea3e99a ("fib_trie: Add collapse() and should_collapse() to resize") Signed-off-by: Matthias Kaehlcke mka@chromium.org Reviewed-by: Douglas Anderson dianders@chromium.org Reviewed-by: Nick Desaulniers ndesaulniers@google.com Acked-by: Alexander Duyck alexander.h.duyck@linux.intel.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org
scripts/Makefile.extrawarn | 1 - 1 file changed, 1 deletion(-)
diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn index 3ab8d1a303cd..b293246e48fe 100644 --- a/scripts/Makefile.extrawarn +++ b/scripts/Makefile.extrawarn @@ -68,7 +68,6 @@ else ifdef CONFIG_CC_IS_CLANG KBUILD_CFLAGS += -Wno-initializer-overrides -KBUILD_CFLAGS += -Wno-unused-value KBUILD_CFLAGS += -Wno-format KBUILD_CFLAGS += -Wno-sign-compare KBUILD_CFLAGS += -Wno-format-zero-length
On Mon, Jul 29, 2019 at 01:54:22PM -0700, Matthias Kaehlcke wrote:
Hi Greg,
Toralf just pointed out in another thread that the commit message and the content of this patch don't match (https://lkml.org/lkml/2019/7/29/1475)
I did some minor digging, the content of the queued patch is:
commit 4df607cc6fe8e46b258ff2a53d0a60ca3008ffc7 Author: Nathan Huckleberry nhuck@google.com Date: Mon Jun 17 10:28:29 2019 -0700
kbuild: Remove unnecessary -Wno-unused-value
however the commit message is from:
commit 25cec756891e8733433efea63b2254ddc93aa5cc Author: Matthias Kaehlcke mka@chromium.org Date: Tue Jun 18 14:14:40 2019 -0700
net/ipv4: fib_trie: Avoid cryptic ternary expressions
It seems this hasn't been commited to -stable yet, so we are probably in time to remove it from the queue before it becomes git history and have Nathan re-spin the patch(es).
s/Nathan/Sasha/
For some reason I thought Nathan backported this and wondered that his SOB is missing. The correct SOB is actually there.
On Mon, Jul 29, 2019 at 09:21:19PM +0200, Greg Kroah-Hartman wrote:
[ Upstream commit 25cec756891e8733433efea63b2254ddc93aa5cc ]
empty_child_inc/dec() use the ternary operator for conditional operations. The conditions involve the post/pre in/decrement operator and the operation is only performed when the condition is *not* true. This is hard to parse for humans, use a regular 'if' construct instead and perform the in/decrement separately.
This also fixes two warnings that are emitted about the value of the ternary expression being unused, when building the kernel with clang + "kbuild: Remove unnecessary -Wno-unused-value" (https://lore.kernel.org/patchwork/patch/1089869/):
CC net/ipv4/fib_trie.o net/ipv4/fib_trie.c:351:2: error: expression result unused [-Werror,-Wunused-value] ++tn_info(n)->empty_children ? : ++tn_info(n)->full_children;
Fixes: 95f60ea3e99a ("fib_trie: Add collapse() and should_collapse() to resize") Signed-off-by: Matthias Kaehlcke mka@chromium.org Reviewed-by: Douglas Anderson dianders@chromium.org Reviewed-by: Nick Desaulniers ndesaulniers@google.com Acked-by: Alexander Duyck alexander.h.duyck@linux.intel.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org
scripts/Makefile.extrawarn | 1 - 1 file changed, 1 deletion(-)
diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn index 3ab8d1a303cd..b293246e48fe 100644 --- a/scripts/Makefile.extrawarn +++ b/scripts/Makefile.extrawarn @@ -68,7 +68,6 @@ else ifdef CONFIG_CC_IS_CLANG KBUILD_CFLAGS += -Wno-initializer-overrides -KBUILD_CFLAGS += -Wno-unused-value KBUILD_CFLAGS += -Wno-format KBUILD_CFLAGS += -Wno-sign-compare KBUILD_CFLAGS += -Wno-format-zero-length
On Mon, Jul 29, 2019 at 1:57 PM Matthias Kaehlcke mka@chromium.org wrote:
On Mon, Jul 29, 2019 at 01:54:22PM -0700, Matthias Kaehlcke wrote:
Hi Greg,
Toralf just pointed out in another thread that the commit message and the content of this patch don't match (https://lkml.org/lkml/2019/7/29/1475)
I did some minor digging, the content of the queued patch is:
commit 4df607cc6fe8e46b258ff2a53d0a60ca3008ffc7 Author: Nathan Huckleberry nhuck@google.com Date: Mon Jun 17 10:28:29 2019 -0700
kbuild: Remove unnecessary -Wno-unused-value
however the commit message is from:
commit 25cec756891e8733433efea63b2254ddc93aa5cc Author: Matthias Kaehlcke mka@chromium.org Date: Tue Jun 18 14:14:40 2019 -0700
net/ipv4: fib_trie: Avoid cryptic ternary expressions
It seems this hasn't been commited to -stable yet, so we are probably in time to remove it from the queue before it becomes git history and have Nathan re-spin the patch(es).
s/Nathan/Sasha/
For some reason I thought Nathan backported this and wondered that his SOB is missing. The correct SOB is actually there.
I don't think Nathan explicitly tried to backport anything. This looks to me like AUTOSEL maybe took a commit message from a different commit, and applied it to this diff.
ie. I don't think this is a bug in a manual backport, I think AUTOSEL did something funny and created a backport with commit message A but commit diff B.
On Mon, Jul 29, 2019 at 02:01:08PM -0700, Nick Desaulniers wrote:
On Mon, Jul 29, 2019 at 1:57 PM Matthias Kaehlcke mka@chromium.org wrote:
On Mon, Jul 29, 2019 at 01:54:22PM -0700, Matthias Kaehlcke wrote:
Hi Greg,
Toralf just pointed out in another thread that the commit message and the content of this patch don't match (https://lkml.org/lkml/2019/7/29/1475)
I did some minor digging, the content of the queued patch is:
commit 4df607cc6fe8e46b258ff2a53d0a60ca3008ffc7 Author: Nathan Huckleberry nhuck@google.com Date: Mon Jun 17 10:28:29 2019 -0700
kbuild: Remove unnecessary -Wno-unused-value
however the commit message is from:
commit 25cec756891e8733433efea63b2254ddc93aa5cc Author: Matthias Kaehlcke mka@chromium.org Date: Tue Jun 18 14:14:40 2019 -0700
net/ipv4: fib_trie: Avoid cryptic ternary expressions
It seems this hasn't been commited to -stable yet, so we are probably in time to remove it from the queue before it becomes git history and have Nathan re-spin the patch(es).
s/Nathan/Sasha/
For some reason I thought Nathan backported this and wondered that his SOB is missing. The correct SOB is actually there.
I don't think Nathan explicitly tried to backport anything. This looks to me like AUTOSEL maybe took a commit message from a different commit, and applied it to this diff.
ie. I don't think this is a bug in a manual backport, I think AUTOSEL did something funny and created a backport with commit message A but commit diff B.
Thanks for reporting this! It is indeed a bug with my scripts.
The story here is that we have commit A which references commit B, but commit B ended up getting merged before commit A, which confused my scripts. I'll go fix up the stable tree and my scripts.
-- Thanks, Sasha
[ Upstream commit 589834b3a0097a4908f4112eac0ca2feb486fa32 ]
In commit ebcc5928c5d9 ("arm64: Silence gcc warnings about arch ABI drift"), the arm64 Makefile added -Wno-psabi to KBUILD_CFLAGS, which is a GCC only option so clang rightfully complains:
warning: unknown warning option '-Wno-psabi' [-Wunknown-warning-option]
https://clang.llvm.org/docs/DiagnosticsReference.html#wunknown-warning-optio...
However, by default, this is merely a warning so the build happily goes on with a slew of these warnings in the process.
Commit c3f0d0bc5b01 ("kbuild, LLVMLinux: Add -Werror to cc-option to support clang") worked around this behavior in cc-option by adding -Werror so that unknown flags cause an error. However, this all happens silently and when an unknown flag is added to the build unconditionally like -Wno-psabi, cc-option will always fail because there is always an unknown flag in the list of flags. This manifested as link time failures in the arm64 libstub because -fno-stack-protector didn't get added to KBUILD_CFLAGS.
To avoid these weird cryptic failures in the future, make clang behave like gcc and immediately error when it encounters an unknown flag by adding -Werror=unknown-warning-option to CLANG_FLAGS. This can be added unconditionally for clang because it is supported by at least 3.0.0, according to godbolt [1] and 4.0.0, according to its documentation [2], which is far earlier than we typically support.
[1]: https://godbolt.org/z/7F7rm3 [2]: https://releases.llvm.org/4.0.0/tools/clang/docs/DiagnosticsReference.html#w...
Link: https://github.com/ClangBuiltLinux/linux/issues/511 Link: https://github.com/ClangBuiltLinux/linux/issues/517 Suggested-by: Peter Smith peter.smith@linaro.org Signed-off-by: Nathan Chancellor natechancellor@gmail.com Tested-by: Nick Desaulniers ndesaulniers@google.com Signed-off-by: Masahiro Yamada yamada.masahiro@socionext.com Signed-off-by: Sasha Levin sashal@kernel.org --- Makefile | 1 + 1 file changed, 1 insertion(+)
diff --git a/Makefile b/Makefile index 68ee97784c4d..fa0f48c43ab2 100644 --- a/Makefile +++ b/Makefile @@ -528,6 +528,7 @@ ifneq ($(GCC_TOOLCHAIN),) CLANG_FLAGS += --gcc-toolchain=$(GCC_TOOLCHAIN) endif CLANG_FLAGS += -no-integrated-as +CLANG_FLAGS += -Werror=unknown-warning-option KBUILD_CFLAGS += $(CLANG_FLAGS) KBUILD_AFLAGS += $(CLANG_FLAGS) export CLANG_FLAGS
[ Upstream commit a222061b85234d8a44486a46bd4df7e2cda52385 ]
__uint128_t crops up in a few files that export symbols to modules, so teach genksyms about it and the other GCC built-in 128-bit integer types so that we don't end up skipping the CRC generation for some symbols due to the parser failing to spot them:
| WARNING: EXPORT symbol "kernel_neon_begin" [vmlinux] version | generation failed, symbol will not be versioned. | ld: arch/arm64/kernel/fpsimd.o: relocation R_AARCH64_ABS32 against | `__crc_kernel_neon_begin' can not be used when making a shared | object | ld: arch/arm64/kernel/fpsimd.o:(.data+0x0): dangerous relocation: | unsupported relocation
Reported-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Will Deacon will.deacon@arm.com Signed-off-by: Masahiro Yamada yamada.masahiro@socionext.com Signed-off-by: Sasha Levin sashal@kernel.org --- scripts/genksyms/keywords.c | 4 ++++ scripts/genksyms/parse.y | 2 ++ 2 files changed, 6 insertions(+)
diff --git a/scripts/genksyms/keywords.c b/scripts/genksyms/keywords.c index e93336baaaed..c586d32dd2c3 100644 --- a/scripts/genksyms/keywords.c +++ b/scripts/genksyms/keywords.c @@ -25,6 +25,10 @@ static struct resword { { "__volatile__", VOLATILE_KEYW }, { "__builtin_va_list", VA_LIST_KEYW },
+ { "__int128", BUILTIN_INT_KEYW }, + { "__int128_t", BUILTIN_INT_KEYW }, + { "__uint128_t", BUILTIN_INT_KEYW }, + // According to rth, c99 defines "_Bool", __restrict", __restrict__", "restrict". KAO { "_Bool", BOOL_KEYW }, { "_restrict", RESTRICT_KEYW }, diff --git a/scripts/genksyms/parse.y b/scripts/genksyms/parse.y index 00a6d7e54971..1ebcf52cd0f9 100644 --- a/scripts/genksyms/parse.y +++ b/scripts/genksyms/parse.y @@ -76,6 +76,7 @@ static void record_compound(struct string_list **keyw, %token ATTRIBUTE_KEYW %token AUTO_KEYW %token BOOL_KEYW +%token BUILTIN_INT_KEYW %token CHAR_KEYW %token CONST_KEYW %token DOUBLE_KEYW @@ -263,6 +264,7 @@ simple_type_specifier: | VOID_KEYW | BOOL_KEYW | VA_LIST_KEYW + | BUILTIN_INT_KEYW | TYPE { (*$1)->tag = SYM_TYPEDEF; $$ = $1; } ;
[ Upstream commit 5fc2aa3ec9efad97dd7c316f3c8e4c6268bbed9b ]
Locking is not needed for the phy_g12a_usb3_pcie_cr_bus_read/write() and currently it causes the following BUG because of the usage of the regmap_read_poll_timeout() running in spinlock_irq, configured by regmap fast_io.
Simply disable locking in the cr_regmap config since it's only used from the PHY init callback function.
BUG: sleeping function called from invalid context at drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c:85 in_atomic(): 1, irqs_disabled(): 128, pid: 60, name: kworker/3:1 [snip] Workqueue: events deferred_probe_work_func Call trace: dump_backtrace+0x0/0x190 show_stack+0x14/0x20 dump_stack+0x90/0xb4 ___might_sleep+0xec/0x110 __might_sleep+0x50/0x88 phy_g12a_usb3_pcie_cr_bus_addr.isra.0+0x80/0x1a8 phy_g12a_usb3_pcie_cr_bus_read+0x34/0x1d8 _regmap_read+0x60/0xe0 _regmap_update_bits+0xc4/0x110 regmap_update_bits_base+0x60/0x90 phy_g12a_usb3_pcie_init+0xdc/0x210 phy_init+0x74/0xd0 dwc3_meson_g12a_probe+0x2cc/0x4d0 platform_drv_probe+0x50/0xa0 really_probe+0x20c/0x3b8 driver_probe_device+0x68/0x150 __device_attach_driver+0xa8/0x170 bus_for_each_drv+0x64/0xc8 __device_attach+0xd8/0x158 device_initial_probe+0x10/0x18 bus_probe_device+0x90/0x98 deferred_probe_work_func+0x94/0xe8 process_one_work+0x1e0/0x338 worker_thread+0x230/0x458 kthread+0x134/0x138 ret_from_fork+0x10/0x1c
Fixes: 36077e16c050 ("phy: amlogic: Add Amlogic G12A USB3 + PCIE Combo PHY Driver") Signed-off-by: Neil Armstrong narmstrong@baylibre.com Tested-by: Kevin Hilman khilman@baylibre.com Signed-off-by: Kishon Vijay Abraham I kishon@ti.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c b/drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c index 6233a7979a93..ac322d643c7a 100644 --- a/drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c +++ b/drivers/phy/amlogic/phy-meson-g12a-usb3-pcie.c @@ -188,7 +188,7 @@ static const struct regmap_config phy_g12a_usb3_pcie_cr_regmap_conf = { .reg_read = phy_g12a_usb3_pcie_cr_bus_read, .reg_write = phy_g12a_usb3_pcie_cr_bus_write, .max_register = 0xffff, - .fast_io = true, + .disable_locking = true, };
static int phy_g12a_usb3_init(struct phy *phy)
[ Upstream commit 181fa434d0514e40ebf6e9721f2b72700287b6e2 ]
According to the PCI Local Bus specification Revision 3.0, section 6.8.1.3 (Message Control for MSI), endpoints that are Multiple Message Capable as defined by bits [3:1] in the Message Control for MSI can request a number of vectors that is power of two aligned.
As specified in section 6.8.1.6 "Message data for MSI", the Multiple Message Enable field (bits [6:4] of the Message Control register) defines the number of low order message data bits the function is permitted to modify to generate its system software allocated vectors.
The MSI controller in the Xilinx NWL PCIe controller supports a number of MSI vectors specified through a bitmap and the hwirq number for an MSI, that is the value written in the MSI data TLP is determined by the bitmap allocation.
For instance, in a situation where two endpoints sitting on the PCI bus request the following MSI configuration, with the current PCI Xilinx bitmap allocation code (that does not align MSI vector allocation on a power of two boundary):
Endpoint #1: Requesting 1 MSI vector - allocated bitmap bits 0 Endpoint #2: Requesting 2 MSI vectors - allocated bitmap bits [1,2]
The bitmap value(s) corresponds to the hwirq number that is programmed into the Message Data for MSI field in the endpoint MSI capability and is detected by the root complex to fire the corresponding MSI irqs. The value written in Message Data for MSI field corresponds to the first bit allocated in the bitmap for Multi MSI vectors.
The current Xilinx NWL MSI allocation code allows a bitmap allocation that is not a power of two boundaries, so endpoint #2, is allowed to toggle Message Data bit[0] to differentiate between its two vectors (meaning that the MSI data will be respectively 0x0 and 0x1 for the two vectors allocated to endpoint #2).
This clearly aliases with the Endpoint #1 vector allocation, resulting in a broken Multi MSI implementation.
Update the code to allocate MSI bitmap ranges with a power of two alignment, fixing the bug.
Fixes: ab597d35ef11 ("PCI: xilinx-nwl: Add support for Xilinx NWL PCIe Host Controller") Suggested-by: Marc Zyngier marc.zyngier@arm.com Signed-off-by: Bharat Kumar Gogada bharat.kumar.gogada@xilinx.com [lorenzo.pieralisi@arm.com: updated commit log] Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Acked-by: Marc Zyngier marc.zyngier@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/pcie-xilinx-nwl.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/drivers/pci/controller/pcie-xilinx-nwl.c b/drivers/pci/controller/pcie-xilinx-nwl.c index 3b031f00a94a..45c0f344ccd1 100644 --- a/drivers/pci/controller/pcie-xilinx-nwl.c +++ b/drivers/pci/controller/pcie-xilinx-nwl.c @@ -482,15 +482,13 @@ static int nwl_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, int i;
mutex_lock(&msi->lock); - bit = bitmap_find_next_zero_area(msi->bitmap, INT_PCI_MSI_NR, 0, - nr_irqs, 0); - if (bit >= INT_PCI_MSI_NR) { + bit = bitmap_find_free_region(msi->bitmap, INT_PCI_MSI_NR, + get_count_order(nr_irqs)); + if (bit < 0) { mutex_unlock(&msi->lock); return -ENOSPC; }
- bitmap_set(msi->bitmap, bit, nr_irqs); - for (i = 0; i < nr_irqs; i++) { irq_domain_set_info(domain, virq + i, bit + i, &nwl_irq_chip, domain->host_data, handle_simple_irq, @@ -508,7 +506,8 @@ static void nwl_irq_domain_free(struct irq_domain *domain, unsigned int virq, struct nwl_msi *msi = &pcie->msi;
mutex_lock(&msi->lock); - bitmap_clear(msi->bitmap, data->hwirq, nr_irqs); + bitmap_release_region(msi->bitmap, data->hwirq, + get_count_order(nr_irqs)); mutex_unlock(&msi->lock); }
[ Upstream commit 208a68c8393d6041a90862992222f3d7943d44d6 ]
On some machines, iio-sensor-proxy was returning all 0's for IIO sensor values. It turns out that the bits_used for this sensor is 32, which makes the mask calculation:
*mask = (1 << 32) - 1;
If the compiler interprets the 1 literals as 32-bit ints, it generates undefined behavior depending on compiler version and optimization level. On my system, it optimizes out the shift, so the mask value becomes
*mask = (1) - 1;
With a mask value of 0, iio-sensor-proxy will always return 0 for every axis.
Avoid incorrect 0 values caused by compiler optimization.
See original fix by Brett Dutro brett.dutro@gmail.com in iio-sensor-proxy: https://github.com/hadess/iio-sensor-proxy/commit/9615ceac7c134d838660e20972...
Signed-off-by: Bastien Nocera hadess@hadess.net Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/iio/iio_utils.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/iio/iio_utils.c b/tools/iio/iio_utils.c index a22b6e8fad46..7399eb7f1378 100644 --- a/tools/iio/iio_utils.c +++ b/tools/iio/iio_utils.c @@ -156,9 +156,9 @@ int iioutils_get_type(unsigned *is_signed, unsigned *bytes, unsigned *bits_used, *be = (endianchar == 'b'); *bytes = padint / 8; if (*bits_used == 64) - *mask = ~0; + *mask = ~(0ULL); else - *mask = (1ULL << *bits_used) - 1; + *mask = (1ULL << *bits_used) - 1ULL;
*is_signed = (signchar == 's'); if (fclose(sysfsfp)) {
[ Upstream commit ef4db28c1f45cda6989bc8a8e45294894786d947 ]
The '#address-cells' and '#size-cells' properties were not defined in the lm3630a bindings and would cause the following error when attempting to validate the examples against the schema:
Documentation/devicetree/bindings/leds/backlight/lm3630a-backlight.example.dt.yaml: '#address-cells', '#size-cells' do not match any of the regexes: '^led@[01]$', 'pinctrl-[0-9]+'
Correct this by adding those two properties.
While we're here, move the ti,linear-mapping-mode property to the led@[01] child nodes to correct the following validation error:
Documentation/devicetree/bindings/leds/backlight/lm3630a-backlight.example.dt.yaml: led@0: 'ti,linear-mapping-mode' does not match any of the regexes: 'pinctrl-[0-9]+'
Fixes: 32fcb75c66a0 ("dt-bindings: backlight: Add lm3630a bindings") Signed-off-by: Brian Masney masneyb@onstation.org Reported-by: Rob Herring robh+dt@kernel.org Acked-by: Daniel Thompson daniel.thompson@linaro.org Acked-by: Dan Murphy dmurphy@ti.com [robh: also drop maxItems from child reg] Signed-off-by: Rob Herring robh@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- .../leds/backlight/lm3630a-backlight.yaml | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/Documentation/devicetree/bindings/leds/backlight/lm3630a-backlight.yaml b/Documentation/devicetree/bindings/leds/backlight/lm3630a-backlight.yaml index 4d61fe0a98a4..dc129d9a329e 100644 --- a/Documentation/devicetree/bindings/leds/backlight/lm3630a-backlight.yaml +++ b/Documentation/devicetree/bindings/leds/backlight/lm3630a-backlight.yaml @@ -23,16 +23,17 @@ properties: reg: maxItems: 1
- ti,linear-mapping-mode: - description: | - Enable linear mapping mode. If disabled, then it will use exponential - mapping mode in which the ramp up/down appears to have a more uniform - transition to the human eye. - type: boolean + '#address-cells': + const: 1 + + '#size-cells': + const: 0
required: - compatible - reg + - '#address-cells' + - '#size-cells'
patternProperties: "^led@[01]$": @@ -48,7 +49,6 @@ patternProperties: in this property. The two current sinks can be controlled independently with both banks, or bank A can be configured to control both sinks with the led-sources property. - maxItems: 1 minimum: 0 maximum: 1
@@ -73,6 +73,13 @@ patternProperties: minimum: 0 maximum: 255
+ ti,linear-mapping-mode: + description: | + Enable linear mapping mode. If disabled, then it will use exponential + mapping mode in which the ramp up/down appears to have a more uniform + transition to the human eye. + type: boolean + required: - reg
[ Upstream commit 04db3ede40ae4fc23a5c4237254c4a53bbe4c1f2 ]
The powerpc's flush_cache_vmap() is defined as a macro and never use both of its arguments, so it will generate a compilation warning,
lib/ioremap.c: In function 'ioremap_page_range': lib/ioremap.c:203:16: warning: variable 'start' set but not used [-Wunused-but-set-variable]
Fix it by making it an inline function.
Signed-off-by: Qian Cai cai@lca.pw Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/include/asm/cacheflush.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/include/asm/cacheflush.h b/arch/powerpc/include/asm/cacheflush.h index 74d60cfe8ce5..fd318f7c3eed 100644 --- a/arch/powerpc/include/asm/cacheflush.h +++ b/arch/powerpc/include/asm/cacheflush.h @@ -29,9 +29,12 @@ * not expect this type of fault. flush_cache_vmap is not exactly the right * place to put this, but it seems to work well enough. */ -#define flush_cache_vmap(start, end) do { asm volatile("ptesync" ::: "memory"); } while (0) +static inline void flush_cache_vmap(unsigned long start, unsigned long end) +{ + asm volatile("ptesync" ::: "memory"); +} #else -#define flush_cache_vmap(start, end) do { } while (0) +static inline void flush_cache_vmap(unsigned long start, unsigned long end) { } #endif
#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
[ Upstream commit aaf06665f7ea3ee9f9754e16c1a507a89f1de5b1 ]
Commit ed49f7fd6438d ("powerpc/xmon: Disable tracing when entering xmon") added code to disable recording trace entries while in xmon. The commit introduced a variable 'tracing_enabled' to record if tracing was enabled on xmon entry, and used this to conditionally enable tracing during exit from xmon.
However, we are not checking the value of 'fromipi' variable in xmon_core() when setting 'tracing_enabled'. Due to this, when secondary cpus enter xmon, they will see tracing as being disabled already and tracing won't be re-enabled on exit. Fix the same.
Fixes: ed49f7fd6438d ("powerpc/xmon: Disable tracing when entering xmon") Signed-off-by: Naveen N. Rao naveen.n.rao@linux.vnet.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/xmon/xmon.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index d0620d762a5a..4a721fd62406 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -465,8 +465,10 @@ static int xmon_core(struct pt_regs *regs, int fromipi) local_irq_save(flags); hard_irq_disable();
- tracing_enabled = tracing_is_on(); - tracing_off(); + if (!fromipi) { + tracing_enabled = tracing_is_on(); + tracing_off(); + }
bp = in_breakpoint_table(regs->nip, &offset); if (bp != NULL) {
[ Upstream commit 9fb603050ffd94f8127df99c699cca2f575eb6a0 ]
The protocol for suspending or migrating an LPAR requires all present processor threads to enter H_JOIN. So if we have threads offline, we have to temporarily bring them up. This can race with administrator actions such as SMT state changes. As of dfd718a2ed1f ("powerpc/rtas: Fix a potential race between CPU-Offline & Migration"), rtas_ibm_suspend_me() accounts for this, but errors out with -EBUSY for what almost certainly is a transient condition in any reasonable scenario.
Callers of rtas_ibm_suspend_me() already retry when -EAGAIN is returned, and it is typical during a migration for that to happen repeatedly for several minutes polling the H_VASI_STATE hcall result before proceeding to the next stage.
So return -EAGAIN instead of -EBUSY when this race is encountered. Additionally: logging this event is still appropriate but use pr_info instead of pr_err; and remove use of unlikely() while here as this is not a hot path at all.
Fixes: dfd718a2ed1f ("powerpc/rtas: Fix a potential race between CPU-Offline & Migration") Signed-off-by: Nathan Lynch nathanl@linux.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/kernel/rtas.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index b824f4c69622..fff2eb22427d 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c @@ -980,10 +980,9 @@ int rtas_ibm_suspend_me(u64 handle) cpu_hotplug_disable();
/* Check if we raced with a CPU-Offline Operation */ - if (unlikely(!cpumask_equal(cpu_present_mask, cpu_online_mask))) { - pr_err("%s: Raced against a concurrent CPU-Offline\n", - __func__); - atomic_set(&data.error, -EBUSY); + if (!cpumask_equal(cpu_present_mask, cpu_online_mask)) { + pr_info("%s: Raced against a concurrent CPU-Offline\n", __func__); + atomic_set(&data.error, -EAGAIN); goto out_hotplug_enable; }
[ Upstream commit 6f9ac9f4427ec0470ccffbf852cfaf326677cc21 ]
When there is not enough space on your storage device, the build will fail with 'No space left on device' error message.
The reason is obvious from the message, so you will free up some disk space, then you will resume the build.
However, sometimes you may still see a mysterious error message:
unterminated call to function 'wildcard': missing ')'.
If you run out of the disk space, fixdep may end up with generating incomplete .*.cmd files.
For example, if the disk-full error occurs while fixdep is running print_dep(), the .*.cmd might be truncated like this:
$(wildcard include/config/
When you run 'make' next time, this broken .*.cmd will be included, then Make will terminate parsing since it is a wrong syntax.
Once this happens, you need to run 'make clean' or delete the broken .*.cmd file manually.
Even if you do not see any error message, the .*.cmd files after any error could be potentially incomplete, and unreliable. You may miss the re-compilation due to missing header dependency.
If printf() cannot output the string for disk shortage or whatever reason, it returns a negative value, but currently fixdep does not check it at all. Consequently, fixdep *successfully* generates a broken .*.cmd file. Make never notices that since fixdep exits with 0, which means success.
Given the intended usage of fixdep, it must respect the return value of not only malloc(), but also printf() and putchar().
This seems a long-standing issue since the introduction of fixdep.
In old days, Kbuild tried to provide an extra safety by letting fixdep output to a temporary file and renaming it after everything is done:
scripts/basic/fixdep $(depfile) $@ '$(make-cmd)' > $(dot-target).tmp;\ rm -f $(depfile); \ mv -f $(dot-target).tmp $(dot-target).cmd)
It was no help to avoid the current issue; fixdep successfully created a truncated tmp file, which would be renamed to a .*.cmd file.
This problem should be fixed by propagating the error status to the build system because:
[1] Since commit 9c2af1c7377a ("kbuild: add .DELETE_ON_ERROR special target"), Make will delete the target automatically on any failure in the recipe.
[2] Since commit 392885ee82d3 ("kbuild: let fixdep directly write to .*.cmd files"), .*.cmd file is included only when the corresponding target already exists.
Signed-off-by: Masahiro Yamada yamada.masahiro@socionext.com Signed-off-by: Sasha Levin sashal@kernel.org --- scripts/basic/fixdep.c | 51 +++++++++++++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 10 deletions(-)
diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c index facbd603adf6..9ba47b0a47b9 100644 --- a/scripts/basic/fixdep.c +++ b/scripts/basic/fixdep.c @@ -99,6 +99,7 @@ #include <unistd.h> #include <fcntl.h> #include <string.h> +#include <stdarg.h> #include <stdlib.h> #include <stdio.h> #include <ctype.h> @@ -109,6 +110,36 @@ static void usage(void) exit(1); }
+/* + * In the intended usage of this program, the stdout is redirected to .*.cmd + * files. The return value of printf() and putchar() must be checked to catch + * any error, e.g. "No space left on device". + */ +static void xprintf(const char *format, ...) +{ + va_list ap; + int ret; + + va_start(ap, format); + ret = vprintf(format, ap); + if (ret < 0) { + perror("fixdep"); + exit(1); + } + va_end(ap); +} + +static void xputchar(int c) +{ + int ret; + + ret = putchar(c); + if (ret == EOF) { + perror("fixdep"); + exit(1); + } +} + /* * Print out a dependency path from a symbol name */ @@ -116,7 +147,7 @@ static void print_dep(const char *m, int slen, const char *dir) { int c, prev_c = '/', i;
- printf(" $(wildcard %s/", dir); + xprintf(" $(wildcard %s/", dir); for (i = 0; i < slen; i++) { c = m[i]; if (c == '_') @@ -124,10 +155,10 @@ static void print_dep(const char *m, int slen, const char *dir) else c = tolower(c); if (c != '/' || prev_c != '/') - putchar(c); + xputchar(c); prev_c = c; } - printf(".h) \\n"); + xprintf(".h) \\n"); }
struct item { @@ -324,13 +355,13 @@ static void parse_dep_file(char *m, const char *target) */ if (!saw_any_target) { saw_any_target = 1; - printf("source_%s := %s\n\n", - target, m); - printf("deps_%s := \\n", target); + xprintf("source_%s := %s\n\n", + target, m); + xprintf("deps_%s := \\n", target); } is_first_dep = 0; } else { - printf(" %s \\n", m); + xprintf(" %s \\n", m); }
buf = read_file(m); @@ -353,8 +384,8 @@ static void parse_dep_file(char *m, const char *target) exit(1); }
- printf("\n%s: $(deps_%s)\n\n", target, target); - printf("$(deps_%s):\n", target); + xprintf("\n%s: $(deps_%s)\n\n", target, target); + xprintf("$(deps_%s):\n", target); }
int main(int argc, char *argv[]) @@ -369,7 +400,7 @@ int main(int argc, char *argv[]) target = argv[2]; cmdline = argv[3];
- printf("cmd_%s := %s\n\n", target, cmdline); + xprintf("cmd_%s := %s\n\n", target, cmdline);
buf = read_file(depfile); parse_dep_file(buf, target);
[ Upstream commit 80e5302e4bc85a6b685b7668c36c6487b5f90e9a ]
An impending change to enable HAVE_C_RECORDMCOUNT on powerpc leads to warnings such as the following:
# modprobe kprobe_example ftrace-powerpc: Not expected bl: opcode is 3c4c0001 WARNING: CPU: 0 PID: 227 at kernel/trace/ftrace.c:2001 ftrace_bug+0x90/0x318 Modules linked in: CPU: 0 PID: 227 Comm: modprobe Not tainted 5.2.0-rc6-00678-g1c329100b942 #2 NIP: c000000000264318 LR: c00000000025d694 CTR: c000000000f5cd30 REGS: c000000001f2b7b0 TRAP: 0700 Not tainted (5.2.0-rc6-00678-g1c329100b942) MSR: 900000010282b033 <SF,HV,VEC,VSX,EE,FP,ME,IR,DR,RI,LE,TM[E]> CR: 28228222 XER: 00000000 CFAR: c0000000002642fc IRQMASK: 0 <snip> NIP [c000000000264318] ftrace_bug+0x90/0x318 LR [c00000000025d694] ftrace_process_locs+0x4f4/0x5e0 Call Trace: [c000000001f2ba40] [0000000000000004] 0x4 (unreliable) [c000000001f2bad0] [c00000000025d694] ftrace_process_locs+0x4f4/0x5e0 [c000000001f2bb90] [c00000000020ff10] load_module+0x25b0/0x30c0 [c000000001f2bd00] [c000000000210cb0] sys_finit_module+0xc0/0x130 [c000000001f2be20] [c00000000000bda4] system_call+0x5c/0x70 Instruction dump: 419e0018 2f83ffff 419e00bc 2f83ffea 409e00cc 4800001c 0fe00000 3c62ff96 39000001 39400000 386386d0 480000c4 <0fe00000> 3ce20003 39000001 3c62ff96 ---[ end trace 4c438d5cebf78381 ]--- ftrace failed to modify [<c0080000012a0008>] 0xc0080000012a0008 actual: 01:00:4c:3c Initializing ftrace call sites ftrace record flags: 2000000 (0) expected tramp: c00000000006af4c
Looking at the relocation records in __mcount_loc shows a few spurious entries:
RELOCATION RECORDS FOR [__mcount_loc]: OFFSET TYPE VALUE 0000000000000000 R_PPC64_ADDR64 .text.unlikely+0x0000000000000008 0000000000000008 R_PPC64_ADDR64 .text.unlikely+0x0000000000000014 0000000000000010 R_PPC64_ADDR64 .text.unlikely+0x0000000000000060 0000000000000018 R_PPC64_ADDR64 .text.unlikely+0x00000000000000b4 0000000000000020 R_PPC64_ADDR64 .init.text+0x0000000000000008 0000000000000028 R_PPC64_ADDR64 .init.text+0x0000000000000014
The first entry in each section is incorrect. Looking at the relocation records, the spurious entries correspond to the R_PPC64_ENTRY records:
RELOCATION RECORDS FOR [.text.unlikely]: OFFSET TYPE VALUE 0000000000000000 R_PPC64_REL64 .TOC.-0x0000000000000008 0000000000000008 R_PPC64_ENTRY *ABS* 0000000000000014 R_PPC64_REL24 _mcount <snip>
The problem is that we are not validating the return value from get_mcountsym() in sift_rel_mcount(). With this entry, mcountsym is 0, but Elf_r_sym(relp) also ends up being 0. Fix this by ensuring mcountsym is valid before processing the entry.
Signed-off-by: Naveen N. Rao naveen.n.rao@linux.vnet.ibm.com Acked-by: Steven Rostedt (VMware) rostedt@goodmis.org Tested-by: Satheesh Rajendran sathnaga@linux.vnet.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Sasha Levin sashal@kernel.org --- scripts/recordmcount.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/scripts/recordmcount.h b/scripts/recordmcount.h index 13c5e6c8829c..47fca2c69a73 100644 --- a/scripts/recordmcount.h +++ b/scripts/recordmcount.h @@ -325,7 +325,8 @@ static uint_t *sift_rel_mcount(uint_t *mlocp, if (!mcountsym) mcountsym = get_mcountsym(sym0, relp, str0);
- if (mcountsym == Elf_r_sym(relp) && !is_fake_mcount(relp)) { + if (mcountsym && mcountsym == Elf_r_sym(relp) && + !is_fake_mcount(relp)) { uint_t const addend = _w(_w(relp->r_offset) - recval + mcount_adjust); mrelp->r_offset = _w(offbase
[ Upstream commit 1bb407f17c5316888c3c446e26cb2bb78943f236 ]
Register driver when EC indicates has precise lid angle calculation code running. Fix incorrect extra resource allocation in cros_ec_sensors_register().
Signed-off-by: Gwendal Grignou gwendal@chromium.org Signed-off-by: Lee Jones lee.jones@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mfd/cros_ec_dev.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/drivers/mfd/cros_ec_dev.c b/drivers/mfd/cros_ec_dev.c index a5391f96eafd..607383b67cf1 100644 --- a/drivers/mfd/cros_ec_dev.c +++ b/drivers/mfd/cros_ec_dev.c @@ -285,13 +285,15 @@ static void cros_ec_sensors_register(struct cros_ec_dev *ec)
resp = (struct ec_response_motion_sense *)msg->data; sensor_num = resp->dump.sensor_count; - /* Allocate 1 extra sensors in FIFO are needed */ - sensor_cells = kcalloc(sensor_num + 1, sizeof(struct mfd_cell), + /* + * Allocate 2 extra sensors if lid angle sensor and/or FIFO are needed. + */ + sensor_cells = kcalloc(sensor_num + 2, sizeof(struct mfd_cell), GFP_KERNEL); if (sensor_cells == NULL) goto error;
- sensor_platforms = kcalloc(sensor_num + 1, + sensor_platforms = kcalloc(sensor_num, sizeof(struct cros_ec_sensor_platform), GFP_KERNEL); if (sensor_platforms == NULL) @@ -351,6 +353,11 @@ static void cros_ec_sensors_register(struct cros_ec_dev *ec) sensor_cells[id].name = "cros-ec-ring"; id++; } + if (cros_ec_check_features(ec, + EC_FEATURE_REFINED_TABLET_MODE_HYSTERESIS)) { + sensor_cells[id].name = "cros-ec-lid-angle"; + id++; + }
ret = mfd_add_devices(ec->dev, 0, sensor_cells, id, NULL, 0, NULL);
[ Upstream commit 5aa3709c0a5c026735b0ddd4ec80810a23d65f5b ]
MODULE_DEVICE_TABLE(of, <of_match_table>) should be called to complete DT OF mathing mechanism and register it.
Before this patch: modinfo ./drivers/mfd/madera.ko | grep alias
After this patch: modinfo ./drivers/mfd/madera.ko | grep alias alias: of:N*T*Ccirrus,wm1840C* alias: of:N*T*Ccirrus,wm1840 alias: of:N*T*Ccirrus,cs47l91C* alias: of:N*T*Ccirrus,cs47l91 alias: of:N*T*Ccirrus,cs47l90C* alias: of:N*T*Ccirrus,cs47l90 alias: of:N*T*Ccirrus,cs47l85C* alias: of:N*T*Ccirrus,cs47l85 alias: of:N*T*Ccirrus,cs47l35C* alias: of:N*T*Ccirrus,cs47l35
Reported-by: Javier Martinez Canillas javier@dowhile0.org Signed-off-by: Daniel Gomez dagmcr@gmail.com Signed-off-by: Lee Jones lee.jones@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mfd/madera-core.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/mfd/madera-core.c b/drivers/mfd/madera-core.c index 2a77988d0462..826b971ccb86 100644 --- a/drivers/mfd/madera-core.c +++ b/drivers/mfd/madera-core.c @@ -286,6 +286,7 @@ const struct of_device_id madera_of_match[] = { { .compatible = "cirrus,wm1840", .data = (void *)WM1840 }, {} }; +MODULE_DEVICE_TABLE(of, madera_of_match); EXPORT_SYMBOL_GPL(madera_of_match);
static int madera_get_reset_gpio(struct madera *madera)
[ Upstream commit c176c6d7e932662668bcaec2d763657096589d85 ]
The logic for setting the of_node on devices created by mfd did not set the fwnode pointer to match, which caused fwnode-based APIs to malfunction on these devices since the fwnode pointer was null. Fix this.
Signed-off-by: Robert Hancock hancock@sedsystems.ca Signed-off-by: Lee Jones lee.jones@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mfd/mfd-core.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c index dbf684c4ebfb..23276a80e3b4 100644 --- a/drivers/mfd/mfd-core.c +++ b/drivers/mfd/mfd-core.c @@ -175,6 +175,7 @@ static int mfd_add_device(struct device *parent, int id, for_each_child_of_node(parent->of_node, np) { if (of_device_is_compatible(np, cell->of_compatible)) { pdev->dev.of_node = np; + pdev->dev.fwnode = &np->fwnode; break; } }
[ Upstream commit 5da6cbcd2f395981aa9bfc571ace99f1c786c985 ]
When the driver is used with a subdevice that is disabled in the kernel configuration, clang gets a little confused about the control flow and fails to notice that n_subdevs is only uninitialized when subdevs is NULL, and we check for that, leading to a false-positive warning:
drivers/mfd/arizona-core.c:1423:19: error: variable 'n_subdevs' is uninitialized when used here [-Werror,-Wuninitialized] subdevs, n_subdevs, NULL, 0, NULL); ^~~~~~~~~ drivers/mfd/arizona-core.c:999:15: note: initialize the variable 'n_subdevs' to silence this warning int n_subdevs, ret, i; ^ = 0
Ideally, we would rearrange the code to avoid all those early initializations and have an explicit exit in each disabled case, but it's much easier to chicken out and add one more initialization here to shut up the warning.
Signed-off-by: Arnd Bergmann arnd@arndb.de Reviewed-by: Nathan Chancellor natechancellor@gmail.com Signed-off-by: Charles Keepax ckeepax@opensource.cirrus.com Signed-off-by: Lee Jones lee.jones@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mfd/arizona-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c index 2bdc7b02157a..4a31907a4525 100644 --- a/drivers/mfd/arizona-core.c +++ b/drivers/mfd/arizona-core.c @@ -993,7 +993,7 @@ int arizona_dev_init(struct arizona *arizona) unsigned int reg, val; int (*apply_patch)(struct arizona *) = NULL; const struct mfd_cell *subdevs = NULL; - int n_subdevs, ret, i; + int n_subdevs = 0, ret, i;
dev_set_drvdata(arizona->dev, arizona); mutex_init(&arizona->clk_lock);
[ Upstream commit 7efd105c27fd2323789b41b64763a0e33ed79c08 ]
Since devm_regmap_init_mmio_clk can fail, add return value checking.
Signed-off-by: Axel Lin axel.lin@ingics.com Acked-by: Chen Feng puck.chen@hisilicon.com Signed-off-by: Lee Jones lee.jones@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mfd/hi655x-pmic.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/mfd/hi655x-pmic.c b/drivers/mfd/hi655x-pmic.c index f1c51ce309fa..7e3959aaa285 100644 --- a/drivers/mfd/hi655x-pmic.c +++ b/drivers/mfd/hi655x-pmic.c @@ -109,6 +109,8 @@ static int hi655x_pmic_probe(struct platform_device *pdev)
pmic->regmap = devm_regmap_init_mmio_clk(dev, NULL, base, &hi655x_regmap_config); + if (IS_ERR(pmic->regmap)) + return PTR_ERR(pmic->regmap);
regmap_read(pmic->regmap, HI655X_BUS_ADDR(HI655X_VER_REG), &pmic->ver); if ((pmic->ver < PMU_VER_START) || (pmic->ver > PMU_VER_END)) {
[ Upstream commit c5d6c45e90c49150670346967971e14576afd7f1 ]
release_pages() is an optimized version of a loop around put_page(). Unfortunately for devmap pages the logic is not entirely correct in release_pages(). This is because device pages can be more than type MEMORY_DEVICE_PUBLIC. There are in fact 4 types, private, public, FS DAX, and PCI P2PDMA. Some of these have specific needs to "put" the page while others do not.
This logic to handle any special needs is contained in put_devmap_managed_page(). Therefore all devmap pages should be processed by this function where we can contain the correct logic for a page put.
Handle all device type pages within release_pages() by calling put_devmap_managed_page() on all devmap pages. If put_devmap_managed_page() returns true the page has been put and we continue with the next page. A false return of put_devmap_managed_page() means the page did not require special processing and should fall to "normal" processing.
This was found via code inspection while determining if release_pages() and the new put_user_pages() could be interchangeable.[1]
[1] https://lkml.kernel.org/r/20190523172852.GA27175@iweiny-DESK2.sc.intel.com
Link: https://lkml.kernel.org/r/20190605214922.17684-1-ira.weiny@intel.com Cc: Jérôme Glisse jglisse@redhat.com Cc: Michal Hocko mhocko@suse.com Reviewed-by: Dan Williams dan.j.williams@intel.com Reviewed-by: John Hubbard jhubbard@nvidia.com Signed-off-by: Ira Weiny ira.weiny@intel.com Signed-off-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Sasha Levin sashal@kernel.org --- mm/swap.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/mm/swap.c b/mm/swap.c index 7ede3eddc12a..607c48229a1d 100644 --- a/mm/swap.c +++ b/mm/swap.c @@ -740,15 +740,20 @@ void release_pages(struct page **pages, int nr) if (is_huge_zero_page(page)) continue;
- /* Device public page can not be huge page */ - if (is_device_public_page(page)) { + if (is_zone_device_page(page)) { if (locked_pgdat) { spin_unlock_irqrestore(&locked_pgdat->lru_lock, flags); locked_pgdat = NULL; } - put_devmap_managed_page(page); - continue; + /* + * ZONE_DEVICE pages that return 'false' from + * put_devmap_managed_page() do not require special + * processing, and instead, expect a call to + * put_page_testzero(). + */ + if (put_devmap_managed_page(page)) + continue; }
page = compound_head(page);
[ Upstream commit 80bf6ceaf9310b3f61934c69b382d4912deee049 ]
When we get into activate_mm(), lockdep complains that we're doing something strange:
WARNING: possible circular locking dependency detected 5.1.0-10252-gb00152307319-dirty #121 Not tainted ------------------------------------------------------ inside.sh/366 is trying to acquire lock: (____ptrval____) (&(&p->alloc_lock)->rlock){+.+.}, at: flush_old_exec+0x703/0x8d7
but task is already holding lock: (____ptrval____) (&mm->mmap_sem){++++}, at: flush_old_exec+0x6c5/0x8d7
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #1 (&mm->mmap_sem){++++}: [...] __lock_acquire+0x12ab/0x139f lock_acquire+0x155/0x18e down_write+0x3f/0x98 flush_old_exec+0x748/0x8d7 load_elf_binary+0x2ca/0xddb [...]
-> #0 (&(&p->alloc_lock)->rlock){+.+.}: [...] __lock_acquire+0x12ab/0x139f lock_acquire+0x155/0x18e _raw_spin_lock+0x30/0x83 flush_old_exec+0x703/0x8d7 load_elf_binary+0x2ca/0xddb [...]
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0 CPU1 ---- ---- lock(&mm->mmap_sem); lock(&(&p->alloc_lock)->rlock); lock(&mm->mmap_sem); lock(&(&p->alloc_lock)->rlock);
*** DEADLOCK ***
2 locks held by inside.sh/366: #0: (____ptrval____) (&sig->cred_guard_mutex){+.+.}, at: __do_execve_file+0x12d/0x869 #1: (____ptrval____) (&mm->mmap_sem){++++}, at: flush_old_exec+0x6c5/0x8d7
stack backtrace: CPU: 0 PID: 366 Comm: inside.sh Not tainted 5.1.0-10252-gb00152307319-dirty #121 Stack: [...] Call Trace: [<600420de>] show_stack+0x13b/0x155 [<6048906b>] dump_stack+0x2a/0x2c [<6009ae64>] print_circular_bug+0x332/0x343 [<6009c5c6>] check_prev_add+0x669/0xdad [<600a06b4>] __lock_acquire+0x12ab/0x139f [<6009f3d0>] lock_acquire+0x155/0x18e [<604a07e0>] _raw_spin_lock+0x30/0x83 [<60151e6a>] flush_old_exec+0x703/0x8d7 [<601a8eb8>] load_elf_binary+0x2ca/0xddb [...]
I think it's because in exec_mmap() we have
down_read(&old_mm->mmap_sem); ... task_lock(tsk); ... activate_mm(active_mm, mm); (which does down_write(&mm->mmap_sem))
I'm not really sure why lockdep throws in the whole knowledge about the task lock, but it seems that old_mm and mm shouldn't ever be the same (and it doesn't deadlock) so tell lockdep that they're different.
Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Richard Weinberger richard@nod.at Signed-off-by: Sasha Levin sashal@kernel.org --- arch/um/include/asm/mmu_context.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/um/include/asm/mmu_context.h b/arch/um/include/asm/mmu_context.h index 9f4b4bb78120..00cefd33afdd 100644 --- a/arch/um/include/asm/mmu_context.h +++ b/arch/um/include/asm/mmu_context.h @@ -52,7 +52,7 @@ static inline void activate_mm(struct mm_struct *old, struct mm_struct *new) * when the new ->mm is used for the first time. */ __switch_mm(&new->context.id); - down_write(&new->mmap_sem); + down_write_nested(&new->mmap_sem, 1); uml_setup_stubs(new); up_write(&new->mmap_sem); }
[ Upstream commit 56659ce838456c6f2315ce8a4bd686ac4b23e9d1 ]
The discard thread should issue upto dpolicy->max_requests at once and wait for all those discard requests at once it reaches dpolicy->max_requests. It should then sleep for dpolicy->min_interval timeout before issuing the next batch of discard requests. But in the current code of is_idle(), it checks for dcc_info->queued_discard and aborts issuing the discard batch of max_requests. This dcc_info->queued_discard will be true always once one discard command is issued.
It is thus resulting into this type of discard request pattern -
- Issue discard request#1 - is_idle() returns false, discard thread waits for request#1 and then sleeps for min_interval 50ms. - Issue discard request#2 - is_idle() returns false, discard thread waits for request#2 and then sleeps for min_interval 50ms. - and so on for all other discard requests, assuming f2fs is idle w.r.t other conditions.
With this fix, the pattern will look like this -
- Issue discard request#1 - Issue discard request#2 and so on upto max_requests of 8 - Issue discard request#8 - wait for min_interval 50ms.
Signed-off-by: Sahitya Tummala stummala@codeaurora.org Reviewed-by: Chao Yu yuchao0@huawei.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/f2fs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 9e6721e15b24..cbdc2f88a98c 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -2204,7 +2204,7 @@ static inline bool is_idle(struct f2fs_sb_info *sbi, int type) get_pages(sbi, F2FS_DIO_WRITE)) return false;
- if (SM_I(sbi) && SM_I(sbi)->dcc_info && + if (type != DISCARD_TIME && SM_I(sbi) && SM_I(sbi)->dcc_info && atomic_read(&SM_I(sbi)->dcc_info->queued_discard)) return false;
[ Upstream commit 548c54acba5bd1388d50727a9a126a42d0cd4ad0 ]
In commit c1fe190c0672 ("powerpc: Add force enable of DAWR on P9 option") the following piece of code was added:
smp_call_function((smp_call_func_t)set_dawr, &null_brk, 0);
Since GCC 8 this triggers the following warning about incompatible function types:
arch/powerpc/kernel/hw_breakpoint.c:408:21: error: cast between incompatible function types from 'int (*)(struct arch_hw_breakpoint *)' to 'void (*)(void *)' [-Werror=cast-function-type]
Since the warning is there for a reason, and should not be hidden behind a cast, provide an intermediate callback function to avoid the warning.
Fixes: c1fe190c0672 ("powerpc: Add force enable of DAWR on P9 option") Suggested-by: Christoph Hellwig hch@infradead.org Signed-off-by: Mathieu Malaterre malat@debian.org Signed-off-by: Michael Neuling mikey@neuling.org Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/kernel/hw_breakpoint.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c index a293a53b4365..50262597c222 100644 --- a/arch/powerpc/kernel/hw_breakpoint.c +++ b/arch/powerpc/kernel/hw_breakpoint.c @@ -370,6 +370,11 @@ void hw_breakpoint_pmu_read(struct perf_event *bp) bool dawr_force_enable; EXPORT_SYMBOL_GPL(dawr_force_enable);
+static void set_dawr_cb(void *info) +{ + set_dawr(info); +} + static ssize_t dawr_write_file_bool(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) @@ -389,7 +394,7 @@ static ssize_t dawr_write_file_bool(struct file *file,
/* If we are clearing, make sure all CPUs have the DAWR cleared */ if (!dawr_force_enable) - smp_call_function((smp_call_func_t)set_dawr, &null_brk, 0); + smp_call_function(set_dawr_cb, &null_brk, 0);
return rc; }
[ Upstream commit 3ab3a0689e74e6aa5b41360bc18861040ddef5b1 ]
When testing out gpio-keys with a button, a spurious interrupt (and therefore a key press or release event) gets triggered as soon as the driver enables the irq line for the first time.
This patch clears any potential bogus generated interrupt that was caused by the switching of the associated irq's type and polarity.
Signed-off-by: Christian Lamparter chunkeey@gmail.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/platforms/4xx/uic.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/powerpc/platforms/4xx/uic.c b/arch/powerpc/platforms/4xx/uic.c index 31f12ad37a98..36fb66ce54cf 100644 --- a/arch/powerpc/platforms/4xx/uic.c +++ b/arch/powerpc/platforms/4xx/uic.c @@ -154,6 +154,7 @@ static int uic_set_irq_type(struct irq_data *d, unsigned int flow_type)
mtdcr(uic->dcrbase + UIC_PR, pr); mtdcr(uic->dcrbase + UIC_TR, tr); + mtdcr(uic->dcrbase + UIC_SR, ~mask);
raw_spin_unlock_irqrestore(&uic->lock, flags);
[ Upstream commit 6d3ca7e73642ce17398f4cd5df1780da4a1ccdaf ]
With CONFIG_OPTIMIZE_INLINING enabled, Laura Abbott reported error with gcc 9.1.1:
arch/powerpc/mm/book3s64/radix_tlb.c: In function '_tlbiel_pid': arch/powerpc/mm/book3s64/radix_tlb.c:104:2: warning: asm operand 3 probably doesn't match constraints 104 | asm volatile(PPC_TLBIEL(%0, %4, %3, %2, %1) | ^~~ arch/powerpc/mm/book3s64/radix_tlb.c:104:2: error: impossible constraint in 'asm'
Fixing _tlbiel_pid() is enough to address the warning above, but I inlined more functions to fix all potential issues.
To meet the "i" (immediate) constraint for the asm operands, functions propagating "ric" must be always inlined.
Fixes: 9012d011660e ("compiler: allow all arches to enable CONFIG_OPTIMIZE_INLINING") Reported-by: Laura Abbott labbott@redhat.com Signed-off-by: Masahiro Yamada yamada.masahiro@socionext.com Reviewed-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/book3s64/hash_native.c | 2 +- arch/powerpc/mm/book3s64/radix_tlb.c | 32 +++++++++++++------------- 2 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/arch/powerpc/mm/book3s64/hash_native.c b/arch/powerpc/mm/book3s64/hash_native.c index 30d62ffe3310..1322c59cb5dd 100644 --- a/arch/powerpc/mm/book3s64/hash_native.c +++ b/arch/powerpc/mm/book3s64/hash_native.c @@ -56,7 +56,7 @@ static inline void tlbiel_hash_set_isa206(unsigned int set, unsigned int is) * tlbiel instruction for hash, set invalidation * i.e., r=1 and is=01 or is=10 or is=11 */ -static inline void tlbiel_hash_set_isa300(unsigned int set, unsigned int is, +static __always_inline void tlbiel_hash_set_isa300(unsigned int set, unsigned int is, unsigned int pid, unsigned int ric, unsigned int prs) { diff --git a/arch/powerpc/mm/book3s64/radix_tlb.c b/arch/powerpc/mm/book3s64/radix_tlb.c index bb9835681315..d0cd5271a57c 100644 --- a/arch/powerpc/mm/book3s64/radix_tlb.c +++ b/arch/powerpc/mm/book3s64/radix_tlb.c @@ -25,7 +25,7 @@ * tlbiel instruction for radix, set invalidation * i.e., r=1 and is=01 or is=10 or is=11 */ -static inline void tlbiel_radix_set_isa300(unsigned int set, unsigned int is, +static __always_inline void tlbiel_radix_set_isa300(unsigned int set, unsigned int is, unsigned int pid, unsigned int ric, unsigned int prs) { @@ -146,8 +146,8 @@ static __always_inline void __tlbie_lpid(unsigned long lpid, unsigned long ric) trace_tlbie(lpid, 0, rb, rs, ric, prs, r); }
-static inline void __tlbiel_lpid_guest(unsigned long lpid, int set, - unsigned long ric) +static __always_inline void __tlbiel_lpid_guest(unsigned long lpid, int set, + unsigned long ric) { unsigned long rb,rs,prs,r;
@@ -163,8 +163,8 @@ static inline void __tlbiel_lpid_guest(unsigned long lpid, int set, }
-static inline void __tlbiel_va(unsigned long va, unsigned long pid, - unsigned long ap, unsigned long ric) +static __always_inline void __tlbiel_va(unsigned long va, unsigned long pid, + unsigned long ap, unsigned long ric) { unsigned long rb,rs,prs,r;
@@ -179,8 +179,8 @@ static inline void __tlbiel_va(unsigned long va, unsigned long pid, trace_tlbie(0, 1, rb, rs, ric, prs, r); }
-static inline void __tlbie_va(unsigned long va, unsigned long pid, - unsigned long ap, unsigned long ric) +static __always_inline void __tlbie_va(unsigned long va, unsigned long pid, + unsigned long ap, unsigned long ric) { unsigned long rb,rs,prs,r;
@@ -195,8 +195,8 @@ static inline void __tlbie_va(unsigned long va, unsigned long pid, trace_tlbie(0, 0, rb, rs, ric, prs, r); }
-static inline void __tlbie_lpid_va(unsigned long va, unsigned long lpid, - unsigned long ap, unsigned long ric) +static __always_inline void __tlbie_lpid_va(unsigned long va, unsigned long lpid, + unsigned long ap, unsigned long ric) { unsigned long rb,rs,prs,r;
@@ -235,7 +235,7 @@ static inline void fixup_tlbie_lpid(unsigned long lpid) /* * We use 128 set in radix mode and 256 set in hpt mode. */ -static inline void _tlbiel_pid(unsigned long pid, unsigned long ric) +static __always_inline void _tlbiel_pid(unsigned long pid, unsigned long ric) { int set;
@@ -337,7 +337,7 @@ static inline void _tlbie_lpid(unsigned long lpid, unsigned long ric) asm volatile("eieio; tlbsync; ptesync": : :"memory"); }
-static inline void _tlbiel_lpid_guest(unsigned long lpid, unsigned long ric) +static __always_inline void _tlbiel_lpid_guest(unsigned long lpid, unsigned long ric) { int set;
@@ -377,8 +377,8 @@ static inline void __tlbiel_va_range(unsigned long start, unsigned long end, __tlbiel_va(addr, pid, ap, RIC_FLUSH_TLB); }
-static inline void _tlbiel_va(unsigned long va, unsigned long pid, - unsigned long psize, unsigned long ric) +static __always_inline void _tlbiel_va(unsigned long va, unsigned long pid, + unsigned long psize, unsigned long ric) { unsigned long ap = mmu_get_ap(psize);
@@ -409,8 +409,8 @@ static inline void __tlbie_va_range(unsigned long start, unsigned long end, __tlbie_va(addr, pid, ap, RIC_FLUSH_TLB); }
-static inline void _tlbie_va(unsigned long va, unsigned long pid, - unsigned long psize, unsigned long ric) +static __always_inline void _tlbie_va(unsigned long va, unsigned long pid, + unsigned long psize, unsigned long ric) { unsigned long ap = mmu_get_ap(psize);
@@ -420,7 +420,7 @@ static inline void _tlbie_va(unsigned long va, unsigned long pid, asm volatile("eieio; tlbsync; ptesync": : :"memory"); }
-static inline void _tlbie_lpid_va(unsigned long va, unsigned long lpid, +static __always_inline void _tlbie_lpid_va(unsigned long va, unsigned long lpid, unsigned long psize, unsigned long ric) { unsigned long ap = mmu_get_ap(psize);
[ Upstream commit 2e67e775845373905d2c2aecb9062c2c4352a535 ]
The API for ib_query_qp requires the driver to set qp_state and cur_qp_state on return, add the missing sets.
Fixes: d37498417947 ("i40iw: add files for iwarp interface") Signed-off-by: Changcheng Liu changcheng.liu@aliyun.com Acked-by: Shiraz Saleem shiraz.saleem@intel.com Reviewed-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/i40iw/i40iw_verbs.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/infiniband/hw/i40iw/i40iw_verbs.c b/drivers/infiniband/hw/i40iw/i40iw_verbs.c index 5689d742bafb..4c88d6f72574 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_verbs.c +++ b/drivers/infiniband/hw/i40iw/i40iw_verbs.c @@ -772,6 +772,8 @@ static int i40iw_query_qp(struct ib_qp *ibqp, struct i40iw_qp *iwqp = to_iwqp(ibqp); struct i40iw_sc_qp *qp = &iwqp->sc_qp;
+ attr->qp_state = iwqp->ibqp_state; + attr->cur_qp_state = attr->qp_state; attr->qp_access_flags = 0; attr->cap.max_send_wr = qp->qp_uk.sq_size; attr->cap.max_recv_wr = qp->qp_uk.rq_size;
[ Upstream commit 775b7ffd7d6d5db320d99b0a485c51e04dfcf9f1 ]
While the .flush_buffer() callback clears sci_port.tx_dma_len since commit 1cf4a7efdc71cab8 ("serial: sh-sci: Fix race condition causing garbage during shutdown"), it does not terminate a transmit DMA operation that may be in progress.
Fix this by terminating any pending DMA operations, and resetting the corresponding cookie.
Signed-off-by: Geert Uytterhoeven geert+renesas@glider.be Reviewed-by: Eugeniu Rosca erosca@de.adit-jv.com Tested-by: Eugeniu Rosca erosca@de.adit-jv.com
Link: https://lore.kernel.org/r/20190624123540.20629-3-geert+renesas@glider.be Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/sh-sci.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index abc705716aa0..1d25c4e2d0d2 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1648,11 +1648,18 @@ static void sci_free_dma(struct uart_port *port)
static void sci_flush_buffer(struct uart_port *port) { + struct sci_port *s = to_sci_port(port); + /* * In uart_flush_buffer(), the xmit circular buffer has just been - * cleared, so we have to reset tx_dma_len accordingly. + * cleared, so we have to reset tx_dma_len accordingly, and stop any + * pending transfers */ - to_sci_port(port)->tx_dma_len = 0; + s->tx_dma_len = 0; + if (s->chan_tx) { + dmaengine_terminate_async(s->chan_tx); + s->cookie_tx = -EINVAL; + } } #else /* !CONFIG_SERIAL_SH_SCI_DMA */ static inline void sci_request_dma(struct uart_port *port)
[ Upstream commit 8493eab02608b0e82f67b892aa72882e510c31d0 ]
When uart_flush_buffer() is called, the .flush_buffer() callback zeroes the tx_dma_len field. This may race with the work queue function handling transmit DMA requests:
1. If the buffer is flushed before the first DMA API call, dmaengine_prep_slave_single() may be called with a zero length, causing the DMA request to never complete, leading to messages like:
rcar-dmac e7300000.dma-controller: Channel Address Error happen
and, with debug enabled:
sh-sci e6e88000.serial: sci_dma_tx_work_fn: ffff800639b55000: 0...0, cookie 126
and DMA timeouts.
2. If the buffer is flushed after the first DMA API call, but before the second, dma_sync_single_for_device() may be called with a zero length, causing the transmit data not to be flushed to RAM, and leading to stale data being output.
Fix this by: 1. Letting sci_dma_tx_work_fn() return immediately if the transmit buffer is empty, 2. Extending the critical section to cover all DMA preparational work, so tx_dma_len stays consistent for all of it, 3. Using local copies of circ_buf.head and circ_buf.tail, to make sure they match the actual operation above.
Reported-by: Eugeniu Rosca erosca@de.adit-jv.com Suggested-by: Yoshihiro Shimoda yoshihiro.shimoda.uh@renesas.com Signed-off-by: Geert Uytterhoeven geert+renesas@glider.be Reviewed-by: Eugeniu Rosca erosca@de.adit-jv.com Tested-by: Eugeniu Rosca erosca@de.adit-jv.com Link: https://lore.kernel.org/r/20190624123540.20629-2-geert+renesas@glider.be Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/sh-sci.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-)
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 1d25c4e2d0d2..d18c680aa64b 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1398,6 +1398,7 @@ static void sci_dma_tx_work_fn(struct work_struct *work) struct circ_buf *xmit = &port->state->xmit; unsigned long flags; dma_addr_t buf; + int head, tail;
/* * DMA is idle now. @@ -1407,16 +1408,23 @@ static void sci_dma_tx_work_fn(struct work_struct *work) * consistent xmit buffer state. */ spin_lock_irq(&port->lock); - buf = s->tx_dma_addr + (xmit->tail & (UART_XMIT_SIZE - 1)); + head = xmit->head; + tail = xmit->tail; + buf = s->tx_dma_addr + (tail & (UART_XMIT_SIZE - 1)); s->tx_dma_len = min_t(unsigned int, - CIRC_CNT(xmit->head, xmit->tail, UART_XMIT_SIZE), - CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE)); - spin_unlock_irq(&port->lock); + CIRC_CNT(head, tail, UART_XMIT_SIZE), + CIRC_CNT_TO_END(head, tail, UART_XMIT_SIZE)); + if (!s->tx_dma_len) { + /* Transmit buffer has been flushed */ + spin_unlock_irq(&port->lock); + return; + }
desc = dmaengine_prep_slave_single(chan, buf, s->tx_dma_len, DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (!desc) { + spin_unlock_irq(&port->lock); dev_warn(port->dev, "Failed preparing Tx DMA descriptor\n"); goto switch_to_pio; } @@ -1424,18 +1432,18 @@ static void sci_dma_tx_work_fn(struct work_struct *work) dma_sync_single_for_device(chan->device->dev, buf, s->tx_dma_len, DMA_TO_DEVICE);
- spin_lock_irq(&port->lock); desc->callback = sci_dma_tx_complete; desc->callback_param = s; - spin_unlock_irq(&port->lock); s->cookie_tx = dmaengine_submit(desc); if (dma_submit_error(s->cookie_tx)) { + spin_unlock_irq(&port->lock); dev_warn(port->dev, "Failed submitting Tx DMA descriptor\n"); goto switch_to_pio; }
+ spin_unlock_irq(&port->lock); dev_dbg(port->dev, "%s: %p: %d...%d, cookie %d\n", - __func__, xmit->buf, xmit->tail, xmit->head, s->cookie_tx); + __func__, xmit->buf, tail, head, s->cookie_tx);
dma_async_issue_pending(chan); return;
[ Upstream commit 2f40cf30c8644360d37287861d5288f00eab35e5 ]
Currently during dual port IB device registration in below code flow,
ib_register_device() ib_device_register_sysfs() ib_setup_port_attrs() add_port() get_counter_table() get_perf_mad() process_mad() mlx5_ib_process_mad()
mlx5_ib_process_mad() fails on 2nd port when both the ports are not fully setup at the device level (because 2nd port is unaffiliated).
As a result, get_perf_mad() registers different PMA counter group for 1st and 2nd port, namely pma_counter_ext and pma_counter. However both ports have the same capability and counter offsets.
Due to this when counters are read by the user via sysfs in below code flow, counters are queried from wrong location from the device mainly from PPCNT instead of VPORT counters.
show_pma_counter() get_perf_mad() process_mad() mlx5_ib_process_mad() process_pma_cmd()
This shows all zero counters for 2nd port.
To overcome this, process_pma_cmd() is invoked, and when unaffiliated port is not yet setup during device registration phase, make the query on the first port. while at it, only process_pma_cmd() needs to work on the native port number and underlying mdev, so shift the get, put calls to where its needed inside process_pma_cmd().
Fixes: 212f2a87b74f ("IB/mlx5: Route MADs for dual port RoCE") Signed-off-by: Parav Pandit parav@mellanox.com Reviewed-by: Daniel Jurgens danielj@mellanox.com Signed-off-by: Leon Romanovsky leonro@mellanox.com Signed-off-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/mlx5/mad.c | 60 +++++++++++++++++++------------- 1 file changed, 36 insertions(+), 24 deletions(-)
diff --git a/drivers/infiniband/hw/mlx5/mad.c b/drivers/infiniband/hw/mlx5/mad.c index 6c529e6f3a01..348c1df69cdc 100644 --- a/drivers/infiniband/hw/mlx5/mad.c +++ b/drivers/infiniband/hw/mlx5/mad.c @@ -200,19 +200,33 @@ static void pma_cnt_assign(struct ib_pma_portcounters *pma_cnt, vl_15_dropped); }
-static int process_pma_cmd(struct mlx5_core_dev *mdev, u8 port_num, +static int process_pma_cmd(struct mlx5_ib_dev *dev, u8 port_num, const struct ib_mad *in_mad, struct ib_mad *out_mad) { - int err; + struct mlx5_core_dev *mdev; + bool native_port = true; + u8 mdev_port_num; void *out_cnt; + int err;
+ mdev = mlx5_ib_get_native_port_mdev(dev, port_num, &mdev_port_num); + if (!mdev) { + /* Fail to get the native port, likely due to 2nd port is still + * unaffiliated. In such case default to 1st port and attached + * PF device. + */ + native_port = false; + mdev = dev->mdev; + mdev_port_num = 1; + } /* Declaring support of extended counters */ if (in_mad->mad_hdr.attr_id == IB_PMA_CLASS_PORT_INFO) { struct ib_class_port_info cpi = {};
cpi.capability_mask = IB_PMA_CLASS_CAP_EXT_WIDTH; memcpy((out_mad->data + 40), &cpi, sizeof(cpi)); - return IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY; + err = IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY; + goto done; }
if (in_mad->mad_hdr.attr_id == IB_PMA_PORT_COUNTERS_EXT) { @@ -221,11 +235,13 @@ static int process_pma_cmd(struct mlx5_core_dev *mdev, u8 port_num, int sz = MLX5_ST_SZ_BYTES(query_vport_counter_out);
out_cnt = kvzalloc(sz, GFP_KERNEL); - if (!out_cnt) - return IB_MAD_RESULT_FAILURE; + if (!out_cnt) { + err = IB_MAD_RESULT_FAILURE; + goto done; + }
err = mlx5_core_query_vport_counter(mdev, 0, 0, - port_num, out_cnt, sz); + mdev_port_num, out_cnt, sz); if (!err) pma_cnt_ext_assign(pma_cnt_ext, out_cnt); } else { @@ -234,20 +250,23 @@ static int process_pma_cmd(struct mlx5_core_dev *mdev, u8 port_num, int sz = MLX5_ST_SZ_BYTES(ppcnt_reg);
out_cnt = kvzalloc(sz, GFP_KERNEL); - if (!out_cnt) - return IB_MAD_RESULT_FAILURE; + if (!out_cnt) { + err = IB_MAD_RESULT_FAILURE; + goto done; + }
- err = mlx5_core_query_ib_ppcnt(mdev, port_num, + err = mlx5_core_query_ib_ppcnt(mdev, mdev_port_num, out_cnt, sz); if (!err) pma_cnt_assign(pma_cnt, out_cnt); - } - + } kvfree(out_cnt); - if (err) - return IB_MAD_RESULT_FAILURE; - - return IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY; + err = err ? IB_MAD_RESULT_FAILURE : + IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY; +done: + if (native_port) + mlx5_ib_put_native_port_mdev(dev, port_num); + return err; }
int mlx5_ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num, @@ -259,8 +278,6 @@ int mlx5_ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num, struct mlx5_ib_dev *dev = to_mdev(ibdev); const struct ib_mad *in_mad = (const struct ib_mad *)in; struct ib_mad *out_mad = (struct ib_mad *)out; - struct mlx5_core_dev *mdev; - u8 mdev_port_num; int ret;
if (WARN_ON_ONCE(in_mad_size != sizeof(*in_mad) || @@ -269,19 +286,14 @@ int mlx5_ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
memset(out_mad->data, 0, sizeof(out_mad->data));
- mdev = mlx5_ib_get_native_port_mdev(dev, port_num, &mdev_port_num); - if (!mdev) - return IB_MAD_RESULT_FAILURE; - - if (MLX5_CAP_GEN(mdev, vport_counters) && + if (MLX5_CAP_GEN(dev->mdev, vport_counters) && in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_PERF_MGMT && in_mad->mad_hdr.method == IB_MGMT_METHOD_GET) { - ret = process_pma_cmd(mdev, mdev_port_num, in_mad, out_mad); + ret = process_pma_cmd(dev, port_num, in_mad, out_mad); } else { ret = process_mad(ibdev, mad_flags, port_num, in_wc, in_grh, in_mad, out_mad); } - mlx5_ib_put_native_port_mdev(dev, port_num); return ret; }
[ Upstream commit 2230ebf6e6dd0b7751e2921b40f6cfe34f09bb16 ]
This fixes kernel crash that arises due to not handling page table allocation failures while allocating hugetlb page table.
Fixes: e2b3d202d1db ("powerpc: Switch 16GB and 16MB explicit hugepages to a different page table format") Signed-off-by: Aneesh Kumar K.V aneesh.kumar@linux.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/mm/hugetlbpage.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index b5d92dc32844..1de0f43a68e5 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -130,6 +130,8 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr, unsigned long sz } else { pdshift = PUD_SHIFT; pu = pud_alloc(mm, pg, addr); + if (!pu) + return NULL; if (pshift == PUD_SHIFT) return (pte_t *)pu; else if (pshift > PMD_SHIFT) { @@ -138,6 +140,8 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr, unsigned long sz } else { pdshift = PMD_SHIFT; pm = pmd_alloc(mm, pu, addr); + if (!pm) + return NULL; if (pshift == PMD_SHIFT) /* 16MB hugepage */ return (pte_t *)pm; @@ -154,12 +158,16 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr, unsigned long sz } else { pdshift = PUD_SHIFT; pu = pud_alloc(mm, pg, addr); + if (!pu) + return NULL; if (pshift >= PUD_SHIFT) { ptl = pud_lockptr(mm, pu); hpdp = (hugepd_t *)pu; } else { pdshift = PMD_SHIFT; pm = pmd_alloc(mm, pu, addr); + if (!pm) + return NULL; ptl = pmd_lockptr(mm, pm); hpdp = (hugepd_t *)pm; }
[ Upstream commit 91b01061fef9c57d2f5b712a6322ef51061f4efd ]
Despite failure in ipoib_dev_init() we continue with initialization flow and creation of child device. It causes to the situation where this child device is added too early to parent device list.
Change the logic, so in case of failure we properly return error from ipoib_dev_init() and add child only in success path.
Fixes: eaeb39842508 ("IB/ipoib: Move init code to ndo_init") Signed-off-by: Valentine Fatiev valentinef@mellanox.com Reviewed-by: Feras Daoud ferasda@mellanox.com Signed-off-by: Leon Romanovsky leonro@mellanox.com Reviewed-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/ulp/ipoib/ipoib_main.c | 34 +++++++++++++---------- 1 file changed, 20 insertions(+), 14 deletions(-)
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 04ea7db08e87..ac0583ff280d 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -1893,12 +1893,6 @@ static void ipoib_child_init(struct net_device *ndev) struct ipoib_dev_priv *priv = ipoib_priv(ndev); struct ipoib_dev_priv *ppriv = ipoib_priv(priv->parent);
- dev_hold(priv->parent); - - down_write(&ppriv->vlan_rwsem); - list_add_tail(&priv->list, &ppriv->child_intfs); - up_write(&ppriv->vlan_rwsem); - priv->max_ib_mtu = ppriv->max_ib_mtu; set_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags); memcpy(priv->dev->dev_addr, ppriv->dev->dev_addr, INFINIBAND_ALEN); @@ -1941,6 +1935,17 @@ static int ipoib_ndo_init(struct net_device *ndev) if (rc) { pr_warn("%s: failed to initialize device: %s port %d (ret = %d)\n", priv->ca->name, priv->dev->name, priv->port, rc); + return rc; + } + + if (priv->parent) { + struct ipoib_dev_priv *ppriv = ipoib_priv(priv->parent); + + dev_hold(priv->parent); + + down_write(&ppriv->vlan_rwsem); + list_add_tail(&priv->list, &ppriv->child_intfs); + up_write(&ppriv->vlan_rwsem); }
return 0; @@ -1958,6 +1963,14 @@ static void ipoib_ndo_uninit(struct net_device *dev) */ WARN_ON(!list_empty(&priv->child_intfs));
+ if (priv->parent) { + struct ipoib_dev_priv *ppriv = ipoib_priv(priv->parent); + + down_write(&ppriv->vlan_rwsem); + list_del(&priv->list); + up_write(&ppriv->vlan_rwsem); + } + ipoib_neigh_hash_uninit(dev);
ipoib_ib_dev_cleanup(dev); @@ -1969,15 +1982,8 @@ static void ipoib_ndo_uninit(struct net_device *dev) priv->wq = NULL; }
- if (priv->parent) { - struct ipoib_dev_priv *ppriv = ipoib_priv(priv->parent); - - down_write(&ppriv->vlan_rwsem); - list_del(&priv->list); - up_write(&ppriv->vlan_rwsem); - + if (priv->parent) dev_put(priv->parent); - } }
static int ipoib_set_vf_link_state(struct net_device *dev, int vf, int link_state)
[ Upstream commit 2b68a2a963a157f024c67c0697b16f5f792c8a35 ]
The ESB-instruction is a nop on CPUs that don't implement the RAS extensions. This lets us use it in places like the vectors without having to use alternatives.
If someone disables CONFIG_ARM64_RAS_EXTN, this instruction still has its RAS extensions behaviour, but we no longer read DISR_EL1 as this register does depend on alternatives.
This could go wrong if we want to synchronize an SError from a KVM guest. On a CPU that has the RAS extensions, but the KConfig option was disabled, we consume the pending SError with no chance of ever reading it.
Hide the ESB-instruction behind the CONFIG_ARM64_RAS_EXTN option, outputting a regular nop if the feature has been disabled.
Reported-by: Julien Thierry julien.thierry@arm.com Signed-off-by: James Morse james.morse@arm.com Signed-off-by: Marc Zyngier marc.zyngier@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/include/asm/assembler.h | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h index 570d195a184d..e3a15c751b13 100644 --- a/arch/arm64/include/asm/assembler.h +++ b/arch/arm64/include/asm/assembler.h @@ -96,7 +96,11 @@ * RAS Error Synchronization barrier */ .macro esb +#ifdef CONFIG_ARM64_RAS_EXTN hint #16 +#else + nop +#endif .endm
/*
[ Upstream commit f087a02941feacf7d6f097522bc67c602fda18e6 ]
KVM does not have 100% coverage of VMX consistency checks, i.e. some checks that cause VM-Fail may only be detected by hardware during a nested VM-Entry. In such a case, KVM must restore L1's state to the pre-VM-Enter state as L2's state has already been loaded into KVM's software model.
L1's CR3 and PDPTRs in particular are loaded from vmcs01.GUEST_*. But when EPT is disabled, the associated fields hold KVM's shadow values, not L1's "real" values. Fortunately, when EPT is disabled the PDPTRs come from memory, i.e. are not cached in the VMCS. Which leaves CR3 as the sole anomaly.
A previously applied workaround to handle CR3 was to force nested early checks if EPT is disabled:
commit 2b27924bb1d48 ("KVM: nVMX: always use early vmcs check when EPT is disabled")
Forcing nested early checks is undesirable as doing so adds hundreds of cycles to every nested VM-Entry. Rather than take this performance hit, handle CR3 by overwriting vmcs01.GUEST_CR3 with L1's CR3 during nested VM-Entry when EPT is disabled *and* nested early checks are disabled. By stuffing vmcs01.GUEST_CR3, nested_vmx_restore_host_state() will naturally restore the correct vcpu->arch.cr3 from vmcs01.GUEST_CR3.
These shenanigans work because nested_vmx_restore_host_state() does a full kvm_mmu_reset_context(), i.e. unloads the current MMU, which guarantees vmcs01.GUEST_CR3 will be rewritten with a new shadow CR3 prior to re-entering L1.
vcpu->arch.root_mmu.root_hpa is set to INVALID_PAGE via:
nested_vmx_restore_host_state() -> kvm_mmu_reset_context() -> kvm_mmu_unload() -> kvm_mmu_free_roots()
kvm_mmu_unload() has WARN_ON(root_hpa != INVALID_PAGE), i.e. we can bank on 'root_hpa == INVALID_PAGE' unless the implementation of kvm_mmu_reset_context() is changed.
On the way into L1, VMCS.GUEST_CR3 is guaranteed to be written (on a successful entry) via:
vcpu_enter_guest() -> kvm_mmu_reload() -> kvm_mmu_load() -> kvm_mmu_load_cr3() -> vmx_set_cr3()
Stuff vmcs01.GUEST_CR3 if and only if nested early checks are disabled as a "late" VM-Fail should never happen win that case (KVM WARNs), and the conditional write avoids the need to restore the correct GUEST_CR3 when nested_vmx_check_vmentry_hw() fails.
Signed-off-by: Sean Christopherson sean.j.christopherson@intel.com Message-Id: 20190607185534.24368-1-sean.j.christopherson@intel.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/include/uapi/asm/vmx.h | 1 - arch/x86/kvm/vmx/nested.c | 44 +++++++++++++++++---------------- 2 files changed, 23 insertions(+), 22 deletions(-)
diff --git a/arch/x86/include/uapi/asm/vmx.h b/arch/x86/include/uapi/asm/vmx.h index d213ec5c3766..f0b0c90dd398 100644 --- a/arch/x86/include/uapi/asm/vmx.h +++ b/arch/x86/include/uapi/asm/vmx.h @@ -146,7 +146,6 @@
#define VMX_ABORT_SAVE_GUEST_MSR_FAIL 1 #define VMX_ABORT_LOAD_HOST_PDPTE_FAIL 2 -#define VMX_ABORT_VMCS_CORRUPTED 3 #define VMX_ABORT_LOAD_HOST_MSR_FAIL 4
#endif /* _UAPIVMX_H */ diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index c1d118f4dc72..ef6575ab60ed 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -2973,6 +2973,25 @@ int nested_vmx_enter_non_root_mode(struct kvm_vcpu *vcpu, bool from_vmentry) !(vmcs12->vm_entry_controls & VM_ENTRY_LOAD_BNDCFGS)) vmx->nested.vmcs01_guest_bndcfgs = vmcs_read64(GUEST_BNDCFGS);
+ /* + * Overwrite vmcs01.GUEST_CR3 with L1's CR3 if EPT is disabled *and* + * nested early checks are disabled. In the event of a "late" VM-Fail, + * i.e. a VM-Fail detected by hardware but not KVM, KVM must unwind its + * software model to the pre-VMEntry host state. When EPT is disabled, + * GUEST_CR3 holds KVM's shadow CR3, not L1's "real" CR3, which causes + * nested_vmx_restore_host_state() to corrupt vcpu->arch.cr3. Stuffing + * vmcs01.GUEST_CR3 results in the unwind naturally setting arch.cr3 to + * the correct value. Smashing vmcs01.GUEST_CR3 is safe because nested + * VM-Exits, and the unwind, reset KVM's MMU, i.e. vmcs01.GUEST_CR3 is + * guaranteed to be overwritten with a shadow CR3 prior to re-entering + * L1. Don't stuff vmcs01.GUEST_CR3 when using nested early checks as + * KVM modifies vcpu->arch.cr3 if and only if the early hardware checks + * pass, and early VM-Fails do not reset KVM's MMU, i.e. the VM-Fail + * path would need to manually save/restore vmcs01.GUEST_CR3. + */ + if (!enable_ept && !nested_early_check) + vmcs_writel(GUEST_CR3, vcpu->arch.cr3); + vmx_switch_vmcs(vcpu, &vmx->nested.vmcs02);
prepare_vmcs02_early(vmx, vmcs12); @@ -3784,18 +3803,8 @@ static void nested_vmx_restore_host_state(struct kvm_vcpu *vcpu) vmx_set_cr4(vcpu, vmcs_readl(CR4_READ_SHADOW));
nested_ept_uninit_mmu_context(vcpu); - - /* - * This is only valid if EPT is in use, otherwise the vmcs01 GUEST_CR3 - * points to shadow pages! Fortunately we only get here after a WARN_ON - * if EPT is disabled, so a VMabort is perfectly fine. - */ - if (enable_ept) { - vcpu->arch.cr3 = vmcs_readl(GUEST_CR3); - __set_bit(VCPU_EXREG_CR3, (ulong *)&vcpu->arch.regs_avail); - } else { - nested_vmx_abort(vcpu, VMX_ABORT_VMCS_CORRUPTED); - } + vcpu->arch.cr3 = vmcs_readl(GUEST_CR3); + __set_bit(VCPU_EXREG_CR3, (ulong *)&vcpu->arch.regs_avail);
/* * Use ept_save_pdptrs(vcpu) to load the MMU's cached PDPTRs @@ -3803,7 +3812,8 @@ static void nested_vmx_restore_host_state(struct kvm_vcpu *vcpu) * VMFail, like everything else we just need to ensure our * software model is up-to-date. */ - ept_save_pdptrs(vcpu); + if (enable_ept) + ept_save_pdptrs(vcpu);
kvm_mmu_reset_context(vcpu);
@@ -5772,14 +5782,6 @@ __init int nested_vmx_hardware_setup(int (*exit_handlers[])(struct kvm_vcpu *)) { int i;
- /* - * Without EPT it is not possible to restore L1's CR3 and PDPTR on - * VMfail, because they are not available in vmcs01. Just always - * use hardware checks. - */ - if (!enable_ept) - nested_early_check = 1; - if (!cpu_has_vmx_shadow_vmcs()) enable_shadow_vmcs = 0; if (enable_shadow_vmcs) {
[ Upstream commit f99536e9d2f55996038158a6559d4254a7cc1693 ]
The outbound memory windows PCI base addresses should be taken from the 'ranges' property of DT node to setup MEM/IO outbound windows decoding correctly instead of being hardcoded to zero.
Update the code to retrieve the PCI base address for each range and use it to program the outbound windows address decoders
Fixes: 9af6bcb11e12 ("PCI: mobiveil: Add Mobiveil PCIe Host Bridge IP driver") Signed-off-by: Hou Zhiqiang Zhiqiang.Hou@nxp.com Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Reviewed-by: Minghuan Lian Minghuan.Lian@nxp.com Reviewed-by: Subrahmanya Lingappa l.subrahmanya@mobiveil.co.in Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/pcie-mobiveil.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/pci/controller/pcie-mobiveil.c b/drivers/pci/controller/pcie-mobiveil.c index 77052a0712d0..03d697b63e2a 100644 --- a/drivers/pci/controller/pcie-mobiveil.c +++ b/drivers/pci/controller/pcie-mobiveil.c @@ -552,8 +552,9 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie) if (type) { /* configure outbound translation window */ program_ob_windows(pcie, pcie->ob_wins_configured, - win->res->start, 0, type, - resource_size(win->res)); + win->res->start, + win->res->start - win->offset, + type, resource_size(win->res)); } }
[ Upstream commit 0122af0a08243f344a438f924e5c2486486555b3 ]
Fix up the Class Code field in PCI configuration space and set it to PCI_CLASS_BRIDGE_PCI.
Move the Class Code fixup to function mobiveil_host_init() where it belongs.
Fixes: 9af6bcb11e12 ("PCI: mobiveil: Add Mobiveil PCIe Host Bridge IP driver") Signed-off-by: Hou Zhiqiang Zhiqiang.Hou@nxp.com Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Reviewed-by: Minghuan Lian Minghuan.Lian@nxp.com Reviewed-by: Subrahmanya Lingappa l.subrahmanya@mobiveil.co.in Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/pcie-mobiveil.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/pci/controller/pcie-mobiveil.c b/drivers/pci/controller/pcie-mobiveil.c index 03d697b63e2a..88e9b70081fc 100644 --- a/drivers/pci/controller/pcie-mobiveil.c +++ b/drivers/pci/controller/pcie-mobiveil.c @@ -558,6 +558,12 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie) } }
+ /* fixup for PCIe class register */ + value = csr_readl(pcie, PAB_INTP_AXI_PIO_CLASS); + value &= 0xff; + value |= (PCI_CLASS_BRIDGE_PCI << 16); + csr_writel(pcie, value, PAB_INTP_AXI_PIO_CLASS); + /* setup MSI hardware registers */ mobiveil_pcie_enable_msi(pcie);
@@ -798,9 +804,6 @@ static int mobiveil_pcie_probe(struct platform_device *pdev) goto error; }
- /* fixup for PCIe class register */ - csr_writel(pcie, 0x060402ab, PAB_INTP_AXI_PIO_CLASS); - /* initialize the IRQ domains */ ret = mobiveil_pcie_init_irq_domain(pcie); if (ret) {
[ Upstream commit 33177f01ca3fe550146bb9001bec2fd806b2f40c ]
gcc asan instrumentation emits the following sequence to store frame pc when the kernel is built with CONFIG_RELOCATABLE: debug/vsprintf.s: .section .data.rel.ro.local,"aw" .align 8 .LC3: .quad .LASANPC4826@GOTOFF .text .align 8 .type number, @function number: .LASANPC4826:
and in case reloc is issued for LASANPC label it also gets into .symtab with the same address as actual function symbol: $ nm -n vmlinux | grep 0000000001397150 0000000001397150 t .LASANPC4826 0000000001397150 t number
In the end kernel backtraces are almost unreadable: [ 143.748476] Call Trace: [ 143.748484] ([<000000002da3e62c>] .LASANPC2671+0x114/0x190) [ 143.748492] [<000000002eca1a58>] .LASANPC2612+0x110/0x160 [ 143.748502] [<000000002de9d830>] print_address_description+0x80/0x3b0 [ 143.748511] [<000000002de9dd64>] __kasan_report+0x15c/0x1c8 [ 143.748521] [<000000002ecb56d4>] strrchr+0x34/0x60 [ 143.748534] [<000003ff800a9a40>] kasan_strings+0xb0/0x148 [test_kasan] [ 143.748547] [<000003ff800a9bba>] kmalloc_tests_init+0xe2/0x528 [test_kasan] [ 143.748555] [<000000002da2117c>] .LASANPC4069+0x354/0x748 [ 143.748563] [<000000002dbfbb16>] do_init_module+0x136/0x3b0 [ 143.748571] [<000000002dbff3f4>] .LASANPC3191+0x2164/0x25d0 [ 143.748580] [<000000002dbffc4c>] .LASANPC3196+0x184/0x1b8 [ 143.748587] [<000000002ecdf2ec>] system_call+0xd8/0x2d8
Since LASANPC labels are not even unique and get into .symtab only due to relocs filter them out in kallsyms.
Signed-off-by: Vasily Gorbik gor@linux.ibm.com Signed-off-by: Masahiro Yamada yamada.masahiro@socionext.com Signed-off-by: Sasha Levin sashal@kernel.org --- scripts/kallsyms.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index e17837f1d3f2..ae6504d07fd6 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c @@ -150,6 +150,9 @@ static int read_symbol(FILE *in, struct sym_entry *s) /* exclude debugging symbols */ else if (stype == 'N' || stype == 'n') return -1; + /* exclude s390 kasan local symbols */ + else if (!strncmp(sym, ".LASANPC", 8)) + return -1;
/* include the type field in the symbol name, so that it gets * compressed together */
[ Upstream commit 6f3ab451aa5c2cbff33197d82fe8489cbd55ad91 ]
The reset value of Primary, Secondary and Subordinate bus numbers is zero which is a broken setup.
Program a sensible default value for Primary/Secondary/Subordinate bus numbers.
Signed-off-by: Hou Zhiqiang Zhiqiang.Hou@nxp.com Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Reviewed-by: Minghuan Lian Minghuan.Lian@nxp.com Reviewed-by: Subrahmanya Lingappa l.subrahmanya@mobiveil.co.in Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/pcie-mobiveil.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/drivers/pci/controller/pcie-mobiveil.c b/drivers/pci/controller/pcie-mobiveil.c index 88e9b70081fc..e4a1964e1b43 100644 --- a/drivers/pci/controller/pcie-mobiveil.c +++ b/drivers/pci/controller/pcie-mobiveil.c @@ -501,6 +501,12 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie) return err; }
+ /* setup bus numbers */ + value = csr_readl(pcie, PCI_PRIMARY_BUS); + value &= 0xff000000; + value |= 0x00ff0100; + csr_writel(pcie, value, PCI_PRIMARY_BUS); + /* * program Bus Master Enable Bit in Command Register in PAB Config * Space
[ Upstream commit f7fee1b42fe4f8171a4b1cad05c61907c33c53f6 ]
The inbound and outbound windows have completely separate control registers sets in the host controller MMIO space. Windows control register are accessed through an MMIO base address and an offset that depends on the window index.
Since inbound and outbound windows control registers are completely separate there is no real need to use different window indexes in the inbound/outbound windows initialization routines to prevent clashing.
To fix this inconsistency, change the MEM inbound window index to 0, mirroring the outbound window set-up.
Signed-off-by: Hou Zhiqiang Zhiqiang.Hou@nxp.com [lorenzo.pieralisi@arm.com: update commit log] Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Reviewed-by: Minghuan Lian Minghuan.Lian@nxp.com Reviewed-by: Subrahmanya Lingappa l.subrahmanya@mobiveil.co.in Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/pcie-mobiveil.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/pci/controller/pcie-mobiveil.c b/drivers/pci/controller/pcie-mobiveil.c index e4a1964e1b43..387a20f3c240 100644 --- a/drivers/pci/controller/pcie-mobiveil.c +++ b/drivers/pci/controller/pcie-mobiveil.c @@ -546,7 +546,7 @@ static int mobiveil_host_init(struct mobiveil_pcie *pcie) resource_size(pcie->ob_io_res));
/* memory inbound translation window */ - program_ib_windows(pcie, WIN_NUM_1, 0, MEM_WINDOW_TYPE, IB_WIN_SIZE); + program_ib_windows(pcie, WIN_NUM_0, 0, MEM_WINDOW_TYPE, IB_WIN_SIZE);
/* Get the I/O and memory ranges from DT */ resource_list_for_each_entry_safe(win, tmp, &pcie->resources) {
[ Upstream commit 4e4cf62b37da5ff45c904a3acf242ab29ed5881d ]
Running the 'perf test' command after building perf with a memory sanitizer causes a warning that says:
WARNING: MemorySanitizer: use-of-uninitialized-value... in mmap-thread-lookup.c
Initializing the go variable to 0 silences this harmless warning.
Committer warning:
This was harmless, just a simple test writing whatever was at that sizeof(int) memory area just to signal another thread blocked reading that file created with pipe(). Initialize it tho so that we don't get this warning.
Signed-off-by: Numfor Mbiziwo-Tiapo nums@google.com Cc: Alexander Shishkin alexander.shishkin@linux.intel.com Cc: Ian Rogers irogers@google.com Cc: Jiri Olsa jolsa@redhat.com Cc: Mark Drayton mbd@fb.com Cc: Namhyung Kim namhyung@kernel.org Cc: Peter Zijlstra peterz@infradead.org Cc: Song Liu songliubraving@fb.com Cc: Stephane Eranian eranian@google.com Link: http://lkml.kernel.org/r/20190702173716.181223-1-nums@google.com Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/tests/mmap-thread-lookup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/perf/tests/mmap-thread-lookup.c b/tools/perf/tests/mmap-thread-lookup.c index ba87e6e8d18c..0a4301a5155c 100644 --- a/tools/perf/tests/mmap-thread-lookup.c +++ b/tools/perf/tests/mmap-thread-lookup.c @@ -53,7 +53,7 @@ static void *thread_fn(void *arg) { struct thread_data *td = arg; ssize_t ret; - int go; + int go = 0;
if (thread_init(td)) return NULL;
[ Upstream commit c74b05030edb3b52f4208d8415b8c933bc509a29 ]
Based on the following report from Smatch, fix the use-after-freed pointer.
tools/perf/builtin-stat.c:1353 add_default_attributes() warn: passing freed memory 'str'.
The pointer 'str' has been freed but later it is still passed into the function parse_events_print_error(). This patch fixes this use-after-freed issue.
Signed-off-by: Leo Yan leo.yan@linaro.org Acked-by: Jiri Olsa jolsa@kernel.org Cc: Adrian Hunter adrian.hunter@intel.com Cc: Alexander Shishkin alexander.shishkin@linux.intel.com Cc: Alexey Budankov alexey.budankov@linux.intel.com Cc: Alexios Zavras alexios.zavras@intel.com Cc: Andi Kleen ak@linux.intel.com Cc: Changbin Du changbin.du@intel.com Cc: Davidlohr Bueso dave@stgolabs.net Cc: David S. Miller davem@davemloft.net Cc: Eric Saint-Etienne eric.saint.etienne@oracle.com Cc: Jin Yao yao.jin@linux.intel.com Cc: Konstantin Khlebnikov khlebnikov@yandex-team.ru Cc: linux-arm-kernel@lists.infradead.org Cc: Mathieu Poirier mathieu.poirier@linaro.org Cc: Namhyung Kim namhyung@kernel.org Cc: Peter Zijlstra peterz@infradead.org Cc: Rasmus Villemoes linux@rasmusvillemoes.dk Cc: Song Liu songliubraving@fb.com Cc: Suzuki Poulouse suzuki.poulose@arm.com Cc: Thomas Gleixner tglx@linutronix.de Cc: Thomas Richter tmricht@linux.ibm.com Link: http://lkml.kernel.org/r/20190702103420.27540-3-leo.yan@linaro.org Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/builtin-stat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 1ae66f09dc7d..e28002d90573 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -1276,8 +1276,8 @@ static int add_default_attributes(void) fprintf(stderr, "Cannot set up top down events %s: %d\n", str, err); - free(str); parse_events_print_error(&errinfo, str); + free(str); return -1; } } else {
[ Upstream commit ee8a84c60bcc1f1615bd9cb3edfe501e26cdc85b ]
Using ".arm .inst" for the arm signature introduces build issues for programs compiled in Thumb mode because the assembler stays in the arm mode for the rest of the inline assembly. Revert to using a ".word" to express the signature as data instead.
The choice of signature is a valid trap instruction on arm32 little endian, where both code and data are little endian.
ARMv6+ big endian (BE8) generates mixed endianness code vs data: little-endian code and big-endian data. The data value of the signature needs to have its byte order reversed to generate the trap instruction.
Prior to ARMv6, -mbig-endian generates big-endian code and data (which match), so the endianness of the data representation of the signature should not be reversed. However, the choice between BE32 and BE8 is done by the linker, so we cannot know whether code and data endianness will be mixed before the linker is invoked. So rather than try to play tricks with the linker, the rseq signature is simply data (not a trap instruction) prior to ARMv6 on big endian. This is why the signature is expressed as data (.word) rather than as instruction (.inst) in assembler.
Because a ".word" is used to emit the signature, it will be interpreted as a literal pool by a disassembler, not as an actual instruction. Considering that the signature is not meant to be executed except in scenarios where the program execution is completely bogus, this should not be an issue.
Signed-off-by: Mathieu Desnoyers mathieu.desnoyers@efficios.com Acked-by: Will Deacon will.deacon@arm.com CC: Peter Zijlstra peterz@infradead.org CC: Thomas Gleixner tglx@linutronix.de CC: Joel Fernandes joelaf@google.com CC: Catalin Marinas catalin.marinas@arm.com CC: Dave Watson davejwatson@fb.com CC: Will Deacon will.deacon@arm.com CC: Shuah Khan shuah@kernel.org CC: Andi Kleen andi@firstfloor.org CC: linux-kselftest@vger.kernel.org CC: "H . Peter Anvin" hpa@zytor.com CC: Chris Lameter cl@linux.com CC: Russell King linux@arm.linux.org.uk CC: Michael Kerrisk mtk.manpages@gmail.com CC: "Paul E . McKenney" paulmck@linux.vnet.ibm.com CC: Paul Turner pjt@google.com CC: Boqun Feng boqun.feng@gmail.com CC: Josh Triplett josh@joshtriplett.org CC: Steven Rostedt rostedt@goodmis.org CC: Ben Maurer bmaurer@fb.com CC: linux-api@vger.kernel.org CC: Andy Lutomirski luto@amacapital.net CC: Andrew Morton akpm@linux-foundation.org CC: Linus Torvalds torvalds@linux-foundation.org CC: Carlos O'Donell carlos@redhat.com CC: Florian Weimer fweimer@redhat.com Signed-off-by: Shuah Khan skhan@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/rseq/rseq-arm.h | 61 +++++++++++++------------ 1 file changed, 33 insertions(+), 28 deletions(-)
diff --git a/tools/testing/selftests/rseq/rseq-arm.h b/tools/testing/selftests/rseq/rseq-arm.h index 84f28f147fb6..5943c816c07c 100644 --- a/tools/testing/selftests/rseq/rseq-arm.h +++ b/tools/testing/selftests/rseq/rseq-arm.h @@ -6,6 +6,8 @@ */
/* + * - ARM little endian + * * RSEQ_SIG uses the udf A32 instruction with an uncommon immediate operand * value 0x5de3. This traps if user-space reaches this instruction by mistake, * and the uncommon operand ensures the kernel does not move the instruction @@ -22,36 +24,40 @@ * def3 udf #243 ; 0xf3 * e7f5 b.n <7f5> * - * pre-ARMv6 big endian code: - * e7f5 b.n <7f5> - * def3 udf #243 ; 0xf3 + * - ARMv6+ big endian (BE8): * * ARMv6+ -mbig-endian generates mixed endianness code vs data: little-endian - * code and big-endian data. Ensure the RSEQ_SIG data signature matches code - * endianness. Prior to ARMv6, -mbig-endian generates big-endian code and data - * (which match), so there is no need to reverse the endianness of the data - * representation of the signature. However, the choice between BE32 and BE8 - * is done by the linker, so we cannot know whether code and data endianness - * will be mixed before the linker is invoked. + * code and big-endian data. The data value of the signature needs to have its + * byte order reversed to generate the trap instruction: + * + * Data: 0xf3def5e7 + * + * Translates to this A32 instruction pattern: + * + * e7f5def3 udf #24035 ; 0x5de3 + * + * Translates to this T16 instruction pattern: + * + * def3 udf #243 ; 0xf3 + * e7f5 b.n <7f5> + * + * - Prior to ARMv6 big endian (BE32): + * + * Prior to ARMv6, -mbig-endian generates big-endian code and data + * (which match), so the endianness of the data representation of the + * signature should not be reversed. However, the choice between BE32 + * and BE8 is done by the linker, so we cannot know whether code and + * data endianness will be mixed before the linker is invoked. So rather + * than try to play tricks with the linker, the rseq signature is simply + * data (not a trap instruction) prior to ARMv6 on big endian. This is + * why the signature is expressed as data (.word) rather than as + * instruction (.inst) in assembler. */
-#define RSEQ_SIG_CODE 0xe7f5def3 - -#ifndef __ASSEMBLER__ - -#define RSEQ_SIG_DATA \ - ({ \ - int sig; \ - asm volatile ("b 2f\n\t" \ - "1: .inst " __rseq_str(RSEQ_SIG_CODE) "\n\t" \ - "2:\n\t" \ - "ldr %[sig], 1b\n\t" \ - : [sig] "=r" (sig)); \ - sig; \ - }) - -#define RSEQ_SIG RSEQ_SIG_DATA - +#ifdef __ARMEB__ +#define RSEQ_SIG 0xf3def5e7 /* udf #24035 ; 0x5de3 (ARMv6+) */ +#else +#define RSEQ_SIG 0xe7f5def3 /* udf #24035 ; 0x5de3 */ #endif
#define rseq_smp_mb() __asm__ __volatile__ ("dmb" ::: "memory", "cc") @@ -125,8 +131,7 @@ do { \ __rseq_str(table_label) ":\n\t" \ ".word " __rseq_str(version) ", " __rseq_str(flags) "\n\t" \ ".word " __rseq_str(start_ip) ", 0x0, " __rseq_str(post_commit_offset) ", 0x0, " __rseq_str(abort_ip) ", 0x0\n\t" \ - ".arm\n\t" \ - ".inst " __rseq_str(RSEQ_SIG_CODE) "\n\t" \ + ".word " __rseq_str(RSEQ_SIG) "\n\t" \ __rseq_str(label) ":\n\t" \ teardown \ "b %l[" __rseq_str(abort_label) "]\n\t"
[ Upstream commit 111442cfc8abdeaa7ec1407f07ef7b3e5f76654e ]
Based on the following report from Smatch, fix the potential NULL pointer dereference check.
tools/perf/builtin-top.c:109 perf_top__parse_source() warn: variable dereferenced before check 'he' (see line 103)
tools/perf/builtin-top.c:233 perf_top__show_details() warn: variable dereferenced before check 'he' (see line 228)
tools/perf/builtin-top.c 101 static int perf_top__parse_source(struct perf_top *top, struct hist_entry *he) 102 { 103 struct perf_evsel *evsel = hists_to_evsel(he->hists); ^^^^ 104 struct symbol *sym; 105 struct annotation *notes; 106 struct map *map; 107 int err = -1; 108 109 if (!he || !he->ms.sym) 110 return -1;
This patch moves the values assignment after validating pointer 'he'.
Signed-off-by: Leo Yan leo.yan@linaro.org Acked-by: Jiri Olsa jolsa@kernel.org Cc: Adrian Hunter adrian.hunter@intel.com Cc: Alexander Shishkin alexander.shishkin@linux.intel.com Cc: Alexey Budankov alexey.budankov@linux.intel.com Cc: Alexios Zavras alexios.zavras@intel.com Cc: Andi Kleen ak@linux.intel.com Cc: Changbin Du changbin.du@intel.com Cc: David S. Miller davem@davemloft.net Cc: Davidlohr Bueso dave@stgolabs.net Cc: Eric Saint-Etienne eric.saint.etienne@oracle.com Cc: Jin Yao yao.jin@linux.intel.com Cc: Konstantin Khlebnikov khlebnikov@yandex-team.ru Cc: Mathieu Poirier mathieu.poirier@linaro.org Cc: Namhyung Kim namhyung@kernel.org Cc: Peter Zijlstra peterz@infradead.org Cc: Rasmus Villemoes linux@rasmusvillemoes.dk Cc: Song Liu songliubraving@fb.com Cc: Suzuki Poulouse suzuki.poulose@arm.com Cc: Thomas Gleixner tglx@linutronix.de Cc: Thomas Richter tmricht@linux.ibm.com Cc: linux-arm-kernel@lists.infradead.org Link: http://lkml.kernel.org/r/20190702103420.27540-4-leo.yan@linaro.org Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/builtin-top.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 466621cd1017..8a9ff4b11df0 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -100,7 +100,7 @@ static void perf_top__resize(struct perf_top *top)
static int perf_top__parse_source(struct perf_top *top, struct hist_entry *he) { - struct perf_evsel *evsel = hists_to_evsel(he->hists); + struct perf_evsel *evsel; struct symbol *sym; struct annotation *notes; struct map *map; @@ -109,6 +109,8 @@ static int perf_top__parse_source(struct perf_top *top, struct hist_entry *he) if (!he || !he->ms.sym) return -1;
+ evsel = hists_to_evsel(he->hists); + sym = he->ms.sym; map = he->ms.map;
@@ -225,7 +227,7 @@ static void perf_top__record_precise_ip(struct perf_top *top, static void perf_top__show_details(struct perf_top *top) { struct hist_entry *he = top->sym_filter_entry; - struct perf_evsel *evsel = hists_to_evsel(he->hists); + struct perf_evsel *evsel; struct annotation *notes; struct symbol *symbol; int more; @@ -233,6 +235,8 @@ static void perf_top__show_details(struct perf_top *top) if (!he) return;
+ evsel = hists_to_evsel(he->hists); + symbol = he->ms.sym; notes = symbol__annotation(symbol);
[ Upstream commit 7a6d49dc8cad8fa1f3d63994102af8f9ae9c859f ]
Based on the following report from Smatch, fix the potential NULL pointer dereference check.
tools/perf/builtin-trace.c:1044 thread_trace__new() error: we previously assumed 'ttrace' could be null (see line 1041).
tools/perf/builtin-trace.c 1037 static struct thread_trace *thread_trace__new(void) 1038 { 1039 struct thread_trace *ttrace = zalloc(sizeof(struct thread_trace)); 1040 1041 if (ttrace) 1042 ttrace->files.max = -1; 1043 1044 ttrace->syscall_stats = intlist__new(NULL); ^^^^^^^^ 1045 1046 return ttrace; 1047 }
Signed-off-by: Leo Yan leo.yan@linaro.org Acked-by: Jiri Olsa jolsa@kernel.org Cc: Adrian Hunter adrian.hunter@intel.com Cc: Alexander Shishkin alexander.shishkin@linux.intel.com Cc: Alexey Budankov alexey.budankov@linux.intel.com Cc: Alexios Zavras alexios.zavras@intel.com Cc: Andi Kleen ak@linux.intel.com Cc: Changbin Du changbin.du@intel.com Cc: David S. Miller davem@davemloft.net Cc: Davidlohr Bueso dave@stgolabs.net Cc: Eric Saint-Etienne eric.saint.etienne@oracle.com Cc: Jin Yao yao.jin@linux.intel.com Cc: Konstantin Khlebnikov khlebnikov@yandex-team.ru Cc: Mathieu Poirier mathieu.poirier@linaro.org Cc: Namhyung Kim namhyung@kernel.org Cc: Peter Zijlstra peterz@infradead.org Cc: Rasmus Villemoes linux@rasmusvillemoes.dk Cc: Song Liu songliubraving@fb.com Cc: Suzuki Poulouse suzuki.poulose@arm.com Cc: Thomas Gleixner tglx@linutronix.de Cc: Thomas Richter tmricht@linux.ibm.com Cc: linux-arm-kernel@lists.infradead.org Link: http://lkml.kernel.org/r/20190702103420.27540-6-leo.yan@linaro.org [ Just made it look like other tools/perf constructors, same end result ] Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/builtin-trace.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 52fadc858ef0..909e68545bb8 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -997,10 +997,10 @@ static struct thread_trace *thread_trace__new(void) { struct thread_trace *ttrace = zalloc(sizeof(struct thread_trace));
- if (ttrace) + if (ttrace) { ttrace->files.max = -1; - - ttrace->syscall_stats = intlist__new(NULL); + ttrace->syscall_stats = intlist__new(NULL); + }
return ttrace; }
[ Upstream commit f3c8d90757724982e5f07cd77d315eb64ca145ac ]
Based on the following report from Smatch, fix the potential NULL pointer dereference check.
tools/perf/util/session.c:1252 dump_read() error: we previously assumed 'evsel' could be null (see line 1249)
tools/perf/util/session.c 1240 static void dump_read(struct perf_evsel *evsel, union perf_event *event) 1241 { 1242 struct read_event *read_event = &event->read; 1243 u64 read_format; 1244 1245 if (!dump_trace) 1246 return; 1247 1248 printf(": %d %d %s %" PRIu64 "\n", event->read.pid, event->read.tid, 1249 evsel ? perf_evsel__name(evsel) : "FAIL", 1250 event->read.value); 1251 1252 read_format = evsel->attr.read_format; ^^^^^^^
'evsel' could be NULL pointer, for this case this patch directly bails out without dumping read_event.
Signed-off-by: Leo Yan leo.yan@linaro.org Acked-by: Jiri Olsa jolsa@kernel.org Cc: Adrian Hunter adrian.hunter@intel.com Cc: Alexander Shishkin alexander.shishkin@linux.intel.com Cc: Alexey Budankov alexey.budankov@linux.intel.com Cc: Alexios Zavras alexios.zavras@intel.com Cc: Andi Kleen ak@linux.intel.com Cc: Changbin Du changbin.du@intel.com Cc: David S. Miller davem@davemloft.net Cc: Davidlohr Bueso dave@stgolabs.net Cc: Eric Saint-Etienne eric.saint.etienne@oracle.com Cc: Jin Yao yao.jin@linux.intel.com Cc: Konstantin Khlebnikov khlebnikov@yandex-team.ru Cc: Mathieu Poirier mathieu.poirier@linaro.org Cc: Namhyung Kim namhyung@kernel.org Cc: Peter Zijlstra peterz@infradead.org Cc: Rasmus Villemoes linux@rasmusvillemoes.dk Cc: Song Liu songliubraving@fb.com Cc: Suzuki Poulouse suzuki.poulose@arm.com Cc: Thomas Gleixner tglx@linutronix.de Cc: Thomas Richter tmricht@linux.ibm.com Cc: linux-arm-kernel@lists.infradead.org Link: http://lkml.kernel.org/r/20190702103420.27540-9-leo.yan@linaro.org Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/util/session.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 54cf163347f7..2e61dd6a3574 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -1249,6 +1249,9 @@ static void dump_read(struct perf_evsel *evsel, union perf_event *event) evsel ? perf_evsel__name(evsel) : "FAIL", event->read.value);
+ if (!evsel) + return; + read_format = evsel->attr.read_format;
if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
[ Upstream commit 363bbaef63ffebcc745239fe80a953ebb5ac9ec9 ]
Based on the following report from Smatch, fix the potential NULL pointer dereference check.
tools/perf/util/map.c:479 map__fprintf_srccode() error: we previously assumed 'state' could be null (see line 466)
tools/perf/util/map.c 465 /* Avoid redundant printing */ 466 if (state && 467 state->srcfile && 468 !strcmp(state->srcfile, srcfile) && 469 state->line == line) { 470 free(srcfile); 471 return 0; 472 } 473 474 srccode = find_sourceline(srcfile, line, &len); 475 if (!srccode) 476 goto out_free_line; 477 478 ret = fprintf(fp, "|%-8d %.*s", line, len, srccode); 479 state->srcfile = srcfile; ^^^^^^^ 480 state->line = line; ^^^^^^^
This patch validates 'state' pointer before access its elements.
Signed-off-by: Leo Yan leo.yan@linaro.org Acked-by: Jiri Olsa jolsa@kernel.org Cc: Adrian Hunter adrian.hunter@intel.com Cc: Alexander Shishkin alexander.shishkin@linux.intel.com Cc: Alexey Budankov alexey.budankov@linux.intel.com Cc: Alexios Zavras alexios.zavras@intel.com Cc: Andi Kleen ak@linux.intel.com Cc: Changbin Du changbin.du@intel.com Cc: David S. Miller davem@davemloft.net Cc: Davidlohr Bueso dave@stgolabs.net Cc: Eric Saint-Etienne eric.saint.etienne@oracle.com Cc: Jin Yao yao.jin@linux.intel.com Cc: Konstantin Khlebnikov khlebnikov@yandex-team.ru Cc: Mathieu Poirier mathieu.poirier@linaro.org Cc: Namhyung Kim namhyung@kernel.org Cc: Peter Zijlstra peterz@infradead.org Cc: Rasmus Villemoes linux@rasmusvillemoes.dk Cc: Song Liu songliubraving@fb.com Cc: Suzuki Poulouse suzuki.poulose@arm.com Cc: Thomas Gleixner tglx@linutronix.de Cc: Thomas Richter tmricht@linux.ibm.com Cc: linux-arm-kernel@lists.infradead.org Fixes: dd2e18e9ac20 ("perf tools: Support 'srccode' output") Link: http://lkml.kernel.org/r/20190702103420.27540-8-leo.yan@linaro.org Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/util/map.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index ee71efb9db62..9c81ee092784 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -470,8 +470,11 @@ int map__fprintf_srccode(struct map *map, u64 addr, goto out_free_line;
ret = fprintf(fp, "|%-8d %.*s", line, len, srccode); - state->srcfile = srcfile; - state->line = line; + + if (state) { + state->srcfile = srcfile; + state->line = line; + } return ret;
out_free_line:
[ Upstream commit 600c787dbf6521d8d07ee717ab7606d5070103ea ]
Based on the following report from Smatch, fix the potential dereferencing freed memory check.
tools/perf/util/annotate.c:1125 disasm_line__parse() error: dereferencing freed memory 'namep'
tools/perf/util/annotate.c 1100 static int disasm_line__parse(char *line, const char **namep, char **rawp) 1101 { 1102 char tmp, *name = ltrim(line);
[...]
1114 *namep = strdup(name); 1115 1116 if (*namep == NULL) 1117 goto out_free_name;
[...]
1124 out_free_name: 1125 free((void *)namep); ^^^^^ 1126 *namep = NULL; ^^^^^^ 1127 return -1; 1128 }
If strdup() fails to allocate memory space for *namep, we don't need to free memory with pointer 'namep', which is resident in data structure disasm_line::ins::name; and *namep is NULL pointer for this failure, so it's pointless to assign NULL to *namep again.
Committer note:
Freeing namep, which is the address of the first entry of the 'struct ins' that is the first member of struct disasm_line would in fact free that disasm_line instance, if it was allocated via malloc/calloc, which, later, would a dereference of freed memory.
Signed-off-by: Leo Yan leo.yan@linaro.org Acked-by: Jiri Olsa jolsa@kernel.org Cc: Adrian Hunter adrian.hunter@intel.com Cc: Alexander Shishkin alexander.shishkin@linux.intel.com Cc: Alexey Budankov alexey.budankov@linux.intel.com Cc: Alexios Zavras alexios.zavras@intel.com Cc: Andi Kleen ak@linux.intel.com Cc: Changbin Du changbin.du@intel.com Cc: David S. Miller davem@davemloft.net Cc: Davidlohr Bueso dave@stgolabs.net Cc: Eric Saint-Etienne eric.saint.etienne@oracle.com Cc: Jin Yao yao.jin@linux.intel.com Cc: Konstantin Khlebnikov khlebnikov@yandex-team.ru Cc: Mathieu Poirier mathieu.poirier@linaro.org Cc: Namhyung Kim namhyung@kernel.org Cc: Peter Zijlstra peterz@infradead.org Cc: Rasmus Villemoes linux@rasmusvillemoes.dk Cc: Song Liu songliubraving@fb.com Cc: Suzuki Poulouse suzuki.poulose@arm.com Cc: Thomas Gleixner tglx@linutronix.de Cc: Thomas Richter tmricht@linux.ibm.com Cc: linux-arm-kernel@lists.infradead.org Link: http://lkml.kernel.org/r/20190702103420.27540-5-leo.yan@linaro.org Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/util/annotate.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index c8ce13419d9b..b8dfcfe08bb1 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -1113,16 +1113,14 @@ static int disasm_line__parse(char *line, const char **namep, char **rawp) *namep = strdup(name);
if (*namep == NULL) - goto out_free_name; + goto out;
(*rawp)[0] = tmp; *rawp = ltrim(*rawp);
return 0;
-out_free_name: - free((void *)namep); - *namep = NULL; +out: return -1; }
[ Upstream commit ceb75476db1617a88cc29b09839acacb69aa076e ]
Based on the following report from Smatch, fix the potential NULL pointer dereference check.
tools/perf/ui/browsers/hists.c:641 hist_browser__run() error: we previously assumed 'hbt' could be null (see line 625)
tools/perf/ui/browsers/hists.c:3088 perf_evsel__hists_browse() error: we previously assumed 'browser->he_selection' could be null (see line 2902)
tools/perf/ui/browsers/hists.c:3272 perf_evsel_menu__run() error: we previously assumed 'hbt' could be null (see line 3260)
This patch firstly validating the pointers before access them, so can fix potential NULL pointer dereference.
Signed-off-by: Leo Yan leo.yan@linaro.org Acked-by: Jiri Olsa jolsa@kernel.org Cc: Adrian Hunter adrian.hunter@intel.com Cc: Alexander Shishkin alexander.shishkin@linux.intel.com Cc: Andi Kleen ak@linux.intel.com Cc: Mathieu Poirier mathieu.poirier@linaro.org Cc: Namhyung Kim namhyung@kernel.org Cc: Suzuki Poulouse suzuki.poulose@arm.com Cc: linux-arm-kernel@lists.infradead.org Link: http://lkml.kernel.org/r/20190708143937.7722-2-leo.yan@linaro.org Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/ui/browsers/hists.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 3421ecbdd3f0..c1dd9b54dc6e 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -638,7 +638,11 @@ int hist_browser__run(struct hist_browser *browser, const char *help, switch (key) { case K_TIMER: { u64 nr_entries; - hbt->timer(hbt->arg); + + WARN_ON_ONCE(!hbt); + + if (hbt) + hbt->timer(hbt->arg);
if (hist_browser__has_filter(browser) || symbol_conf.report_hierarchy) @@ -2819,7 +2823,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, { struct hists *hists = evsel__hists(evsel); struct hist_browser *browser = perf_evsel_browser__new(evsel, hbt, env, annotation_opts); - struct branch_info *bi; + struct branch_info *bi = NULL; #define MAX_OPTIONS 16 char *options[MAX_OPTIONS]; struct popup_action actions[MAX_OPTIONS]; @@ -3085,7 +3089,9 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, goto skip_annotation;
if (sort__mode == SORT_MODE__BRANCH) { - bi = browser->he_selection->branch_info; + + if (browser->he_selection) + bi = browser->he_selection->branch_info;
if (bi == NULL) goto skip_annotation; @@ -3269,7 +3275,8 @@ static int perf_evsel_menu__run(struct perf_evsel_menu *menu,
switch (key) { case K_TIMER: - hbt->timer(hbt->arg); + if (hbt) + hbt->timer(hbt->arg);
if (!menu->lost_events_warned && menu->lost_events &&
[ Upstream commit bdce1290493caa3f8119f24b5dacc3fb7ca27389 ]
Calculate the correct byte_len on the receiving side when a work completion is generated with IB_WC_RECV_RDMA_WITH_IMM opcode.
According to the IBA byte_len must indicate the number of written bytes, whereas it was always equal to zero for the IB_WC_RECV_RDMA_WITH_IMM opcode, even though data was transferred.
Fixes: 8700e3e7c485 ("Soft RoCE driver") Signed-off-by: Konstantin Taranov konstantin.taranov@inf.ethz.ch Signed-off-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/sw/rxe/rxe_resp.c | 5 ++++- drivers/infiniband/sw/rxe/rxe_verbs.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/infiniband/sw/rxe/rxe_resp.c b/drivers/infiniband/sw/rxe/rxe_resp.c index aca9f60f9b21..1cbfbd98eb22 100644 --- a/drivers/infiniband/sw/rxe/rxe_resp.c +++ b/drivers/infiniband/sw/rxe/rxe_resp.c @@ -431,6 +431,7 @@ static enum resp_states check_rkey(struct rxe_qp *qp, qp->resp.va = reth_va(pkt); qp->resp.rkey = reth_rkey(pkt); qp->resp.resid = reth_len(pkt); + qp->resp.length = reth_len(pkt); } access = (pkt->mask & RXE_READ_MASK) ? IB_ACCESS_REMOTE_READ : IB_ACCESS_REMOTE_WRITE; @@ -856,7 +857,9 @@ static enum resp_states do_complete(struct rxe_qp *qp, pkt->mask & RXE_WRITE_MASK) ? IB_WC_RECV_RDMA_WITH_IMM : IB_WC_RECV; wc->vendor_err = 0; - wc->byte_len = wqe->dma.length - wqe->dma.resid; + wc->byte_len = (pkt->mask & RXE_IMMDT_MASK && + pkt->mask & RXE_WRITE_MASK) ? + qp->resp.length : wqe->dma.length - wqe->dma.resid;
/* fields after byte_len are different between kernel and user * space diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.h b/drivers/infiniband/sw/rxe/rxe_verbs.h index e8be7f44e3be..28bfb3ece104 100644 --- a/drivers/infiniband/sw/rxe/rxe_verbs.h +++ b/drivers/infiniband/sw/rxe/rxe_verbs.h @@ -213,6 +213,7 @@ struct rxe_resp_info { struct rxe_mem *mr; u32 resid; u32 rkey; + u32 length; u64 atomic_orig;
/* SRQ only */
[ Upstream commit 381ed79c8655a40268ee7391f716edd90c5c3a97 ]
If CONFIG_GPIOLIB is not selected the compilation results in the following build errors:
drivers/pci/controller/dwc/pci-dra7xx.c: In function dra7xx_pcie_probe: drivers/pci/controller/dwc/pci-dra7xx.c:777:10: error: implicit declaration of function devm_gpiod_get_optional; did you mean devm_regulator_get_optional? [-Werror=implicit-function-declaration]
reset = devm_gpiod_get_optional(dev, NULL, GPIOD_OUT_HIGH);
drivers/pci/controller/dwc/pci-dra7xx.c:778:45: error: ‘GPIOD_OUT_HIGH’ undeclared (first use in this function); did you mean ‘GPIOF_INIT_HIGH’? reset = devm_gpiod_get_optional(dev, NULL, GPIOD_OUT_HIGH); ^~~~~~~~~~~~~~ GPIOF_INIT_HIGH
Fix them by including the appropriate header file.
Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: YueHaibing yuehaibing@huawei.com [lorenzo.pieralisi@arm.com: commit log] Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Acked-by: Kishon Vijay Abraham I kishon@ti.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/dwc/pci-dra7xx.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/pci/controller/dwc/pci-dra7xx.c b/drivers/pci/controller/dwc/pci-dra7xx.c index 419451efd58c..4234ddb4722f 100644 --- a/drivers/pci/controller/dwc/pci-dra7xx.c +++ b/drivers/pci/controller/dwc/pci-dra7xx.c @@ -26,6 +26,7 @@ #include <linux/types.h> #include <linux/mfd/syscon.h> #include <linux/regmap.h> +#include <linux/gpio/consumer.h>
#include "../../pci.h" #include "pcie-designware.h"
[ Upstream commit 1d481458816d9424c8a05833ce0ebe72194a350e ]
Based on the following report from Smatch, fix the potential NULL pointer dereference check.
tools/perf/util/intel-bts.c:898 intel_bts_process_auxtrace_info() error: we previously assumed 'session->itrace_synth_opts' could be null (see line 894)
tools/perf/util/intel-bts.c:899 intel_bts_process_auxtrace_info() warn: variable dereferenced before check 'session->itrace_synth_opts' (see line 898)
tools/perf/util/intel-bts.c 894 if (session->itrace_synth_opts && session->itrace_synth_opts->set) { 895 bts->synth_opts = *session->itrace_synth_opts; 896 } else { 897 itrace_synth_opts__set_default(&bts->synth_opts, 898 session->itrace_synth_opts->default_no_sample); ^^^^^^^^^^^^^^^^^^^^^^^^^^ 899 if (session->itrace_synth_opts) ^^^^^^^^^^^^^^^^^^^^^^^^^^ 900 bts->synth_opts.thread_stack = 901 session->itrace_synth_opts->thread_stack; 902 }
'session->itrace_synth_opts' is impossible to be a NULL pointer in intel_bts_process_auxtrace_info(), thus this patch removes the NULL test for 'session->itrace_synth_opts'.
Signed-off-by: Leo Yan leo.yan@linaro.org Acked-by: Adrian Hunter adrian.hunter@intel.com Cc: Alexander Shishkin alexander.shishkin@linux.intel.com Cc: Andi Kleen ak@linux.intel.com Cc: Jiri Olsa jolsa@redhat.com Cc: Mathieu Poirier mathieu.poirier@linaro.org Cc: Namhyung Kim namhyung@kernel.org Cc: Suzuki Poulouse suzuki.poulose@arm.com Cc: linux-arm-kernel@lists.infradead.org Link: http://lkml.kernel.org/r/20190708143937.7722-3-leo.yan@linaro.org Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/util/intel-bts.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/tools/perf/util/intel-bts.c b/tools/perf/util/intel-bts.c index e32dbffebb2f..625ad3639a7e 100644 --- a/tools/perf/util/intel-bts.c +++ b/tools/perf/util/intel-bts.c @@ -891,13 +891,12 @@ int intel_bts_process_auxtrace_info(union perf_event *event, if (dump_trace) return 0;
- if (session->itrace_synth_opts && session->itrace_synth_opts->set) { + if (session->itrace_synth_opts->set) { bts->synth_opts = *session->itrace_synth_opts; } else { itrace_synth_opts__set_default(&bts->synth_opts, session->itrace_synth_opts->default_no_sample); - if (session->itrace_synth_opts) - bts->synth_opts.thread_stack = + bts->synth_opts.thread_stack = session->itrace_synth_opts->thread_stack; }
[ Upstream commit d8d9ec7dc5abbb3f11d866e983c4984f5c2de9d6 ]
Use the neighbour lock when copying the MAC address from the neighbour data struct in dst_fetch_ha.
When not using the lock, it is possible for the function to race with neigh_update(), causing it to copy an torn MAC address:
rdma_resolve_addr() rdma_resolve_ip() addr_resolve() addr_resolve_neigh() fetch_ha() dst_fetch_ha() memcpy(dev_addr->dst_dev_addr, n->ha, MAX_ADDR_LEN)
and
net_ioctl() arp_ioctl() arp_rec_delete() arp_invalidate() neigh_update() __neigh_update() memcpy(&neigh->ha, lladdr, dev->addr_len)
It is possible to provoke this error by calling rdma_resolve_addr() in a tight loop, while deleting the corresponding ARP entry in another tight loop.
Fixes: 51d45974515c ("infiniband: addr: Consolidate code to fetch neighbour hardware address from dst.") Signed-off-by: Dag Moxnes dag.moxnes@oracle.com Signed-off-by: Håkon Bugge haakon.bugge@oracle.com Reviewed-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Jason Gunthorpe jgg@mellanox.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/core/addr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index 2f7d14159841..9b76a8fcdd24 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c @@ -337,7 +337,7 @@ static int dst_fetch_ha(const struct dst_entry *dst, neigh_event_send(n, NULL); ret = -ENODATA; } else { - memcpy(dev_addr->dst_dev_addr, n->ha, MAX_ADDR_LEN); + neigh_ha_snapshot(dev_addr->dst_dev_addr, n, dst->dev); }
neigh_release(n);
[ Upstream commit bfac8e9f55cf62a000b643a0081488badbe92d96 ]
Modify nvme_alloc_sq_cmds() to call pci_free_p2pmem() to free the memory it allocated using pci_alloc_p2pmem() in case pci_p2pmem_virt_to_bus() returns null.
Makes sure not to call pci_free_p2pmem() if pci_alloc_p2pmem() returned NULL, which can happen if CONFIG_PCI_P2PDMA is not configured.
The current implementation is not expected to leak since pci_p2pmem_virt_to_bus() is expected to fail only if pci_alloc_p2pmem() returns null. However, checking the return value of pci_alloc_p2pmem() is more explicit.
Signed-off-by: Alan Mikhak alan.mikhak@sifive.com Signed-off-by: Christoph Hellwig hch@lst.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvme/host/pci.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index f5bc1c30cef5..245b6e2151c1 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -1456,11 +1456,15 @@ static int nvme_alloc_sq_cmds(struct nvme_dev *dev, struct nvme_queue *nvmeq,
if (qid && dev->cmb_use_sqes && (dev->cmbsz & NVME_CMBSZ_SQS)) { nvmeq->sq_cmds = pci_alloc_p2pmem(pdev, SQ_SIZE(depth)); - nvmeq->sq_dma_addr = pci_p2pmem_virt_to_bus(pdev, - nvmeq->sq_cmds); - if (nvmeq->sq_dma_addr) { - set_bit(NVMEQ_SQ_CMB, &nvmeq->flags); - return 0; + if (nvmeq->sq_cmds) { + nvmeq->sq_dma_addr = pci_p2pmem_virt_to_bus(pdev, + nvmeq->sq_cmds); + if (nvmeq->sq_dma_addr) { + set_bit(NVMEQ_SQ_CMB, &nvmeq->flags); + return 0; + } + + pci_free_p2pmem(pdev, nvmeq->sq_cmds, SQ_SIZE(depth)); } }
[ Upstream commit 7637de311bd2124b298a072852448b940d8a34b9 ]
When running a NVMe device that is attached to a addressing challenged PCIe root port that requires bounce buffering, our request sizes can easily overflow the swiotlb bounce buffer size. Limit the maximum I/O size to the limit exposed by the DMA mapping subsystem.
Signed-off-by: Christoph Hellwig hch@lst.de Reported-by: Atish Patra Atish.Patra@wdc.com Tested-by: Atish Patra Atish.Patra@wdc.com Reviewed-by: Sagi Grimberg sagi@grimberg.me Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvme/host/pci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 245b6e2151c1..7fbcd72c438f 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -2521,7 +2521,8 @@ static void nvme_reset_work(struct work_struct *work) * Limit the max command size to prevent iod->sg allocations going * over a single page. */ - dev->ctrl.max_hw_sectors = NVME_MAX_KB_SZ << 1; + dev->ctrl.max_hw_sectors = min_t(u32, + NVME_MAX_KB_SZ << 1, dma_max_mapping_size(dev->dev) >> 9); dev->ctrl.max_segments = NVME_MAX_SEGS;
/*
[ Upstream commit 37c15219599f7a4baa73f6e3432afc69ba7cc530 ]
According to commit a10674bf2406 ("tcp: detecting the misuse of .sendpage for Slab objects") and previous discussion, tcp_sendpage should not be used for pages that is managed by SLAB, as SLAB is not taking page reference counters into consideration.
Signed-off-by: Mikhail Skorzhinskii mskorzhinskiy@solarflare.com Reviewed-by: Sagi Grimberg sagi@grimberg.me Signed-off-by: Christoph Hellwig hch@lst.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvme/host/tcp.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c index 08a2501b9357..606b13d35d16 100644 --- a/drivers/nvme/host/tcp.c +++ b/drivers/nvme/host/tcp.c @@ -860,7 +860,14 @@ static int nvme_tcp_try_send_data(struct nvme_tcp_request *req) else flags |= MSG_MORE;
- ret = kernel_sendpage(queue->sock, page, offset, len, flags); + /* can't zcopy slab pages */ + if (unlikely(PageSlab(page))) { + ret = sock_no_sendpage(queue->sock, page, offset, len, + flags); + } else { + ret = kernel_sendpage(queue->sock, page, offset, len, + flags); + } if (ret <= 0) return ret;
[ Upstream commit a4c0b3decb33fb4a2b5ecc6234a50680f0b21e7d ]
INFO: task syz-executor.5:8634 blocked for more than 143 seconds. Not tainted 5.2.0-rc5+ #3 "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. syz-executor.5 D25632 8634 8224 0x00004004 Call Trace: context_switch kernel/sched/core.c:2818 [inline] __schedule+0x658/0x9e0 kernel/sched/core.c:3445 schedule+0x131/0x1d0 kernel/sched/core.c:3509 schedule_timeout+0x9a/0x2b0 kernel/time/timer.c:1783 do_wait_for_common+0x35e/0x5a0 kernel/sched/completion.c:83 __wait_for_common kernel/sched/completion.c:104 [inline] wait_for_common kernel/sched/completion.c:115 [inline] wait_for_completion+0x47/0x60 kernel/sched/completion.c:136 kthread_stop+0xb4/0x150 kernel/kthread.c:559 io_sq_thread_stop fs/io_uring.c:2252 [inline] io_finish_async fs/io_uring.c:2259 [inline] io_ring_ctx_free fs/io_uring.c:2770 [inline] io_ring_ctx_wait_and_kill+0x268/0x880 fs/io_uring.c:2834 io_uring_release+0x5d/0x70 fs/io_uring.c:2842 __fput+0x2e4/0x740 fs/file_table.c:280 ____fput+0x15/0x20 fs/file_table.c:313 task_work_run+0x17e/0x1b0 kernel/task_work.c:113 tracehook_notify_resume include/linux/tracehook.h:185 [inline] exit_to_usermode_loop arch/x86/entry/common.c:168 [inline] prepare_exit_to_usermode+0x402/0x4f0 arch/x86/entry/common.c:199 syscall_return_slowpath+0x110/0x440 arch/x86/entry/common.c:279 do_syscall_64+0x126/0x140 arch/x86/entry/common.c:304 entry_SYSCALL_64_after_hwframe+0x49/0xbe RIP: 0033:0x412fb1 Code: 80 3b 7c 0f 84 c7 02 00 00 c7 85 d0 00 00 00 00 00 00 00 48 8b 05 cf a6 24 00 49 8b 14 24 41 b9 cb 2a 44 00 48 89 ee 48 89 df <48> 85 c0 4c 0f 45 c8 45 31 c0 31 c9 e8 0e 5b 00 00 85 c0 41 89 c7 RSP: 002b:00007ffe7ee6a180 EFLAGS: 00000293 ORIG_RAX: 0000000000000003 RAX: 0000000000000000 RBX: 0000000000000004 RCX: 0000000000412fb1 RDX: 0000001b2d920000 RSI: 0000000000000000 RDI: 0000000000000003 RBP: 0000000000000001 R08: 00000000f3a3e1f8 R09: 00000000f3a3e1fc R10: 00007ffe7ee6a260 R11: 0000000000000293 R12: 000000000075c9a0 R13: 000000000075c9a0 R14: 0000000000024c00 R15: 000000000075bf2c
=============================================
There is an wrong logic, when kthread_park running in front of io_sq_thread.
CPU#0 CPU#1
io_sq_thread_stop: int kthread(void *_create):
kthread_park() __kthread_parkme(self); <<< Wrong kthread_stop() << wait for self->exited << clear_bit KTHREAD_SHOULD_PARK
ret = threadfn(data); | |- io_sq_thread |- kthread_should_park() << false |- schedule() <<< nobody wake up
stuck CPU#0 stuck CPU#1
So, use a new variable sqo_thread_started to ensure that io_sq_thread run first, then io_sq_thread_stop.
Reported-by: syzbot+94324416c485d422fe15@syzkaller.appspotmail.com Suggested-by: Jens Axboe axboe@kernel.dk Signed-off-by: Jackie Liu liuyun01@kylinos.cn Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- fs/io_uring.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/fs/io_uring.c b/fs/io_uring.c index 4ef62a45045d..fef2cd44b2ac 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -231,6 +231,7 @@ struct io_ring_ctx { struct task_struct *sqo_thread; /* if using sq thread polling */ struct mm_struct *sqo_mm; wait_queue_head_t sqo_wait; + struct completion sqo_thread_started;
struct { /* CQ ring */ @@ -403,6 +404,7 @@ static struct io_ring_ctx *io_ring_ctx_alloc(struct io_uring_params *p) ctx->flags = p->flags; init_waitqueue_head(&ctx->cq_wait); init_completion(&ctx->ctx_done); + init_completion(&ctx->sqo_thread_started); mutex_init(&ctx->uring_lock); init_waitqueue_head(&ctx->wait); for (i = 0; i < ARRAY_SIZE(ctx->pending_async); i++) { @@ -2009,6 +2011,8 @@ static int io_sq_thread(void *data) unsigned inflight; unsigned long timeout;
+ complete(&ctx->sqo_thread_started); + old_fs = get_fs(); set_fs(USER_DS);
@@ -2243,6 +2247,7 @@ static int io_sqe_files_unregister(struct io_ring_ctx *ctx) static void io_sq_thread_stop(struct io_ring_ctx *ctx) { if (ctx->sqo_thread) { + wait_for_completion(&ctx->sqo_thread_started); /* * The park is a bit of a work-around, without it we get * warning spews on shutdown with SQPOLL set and affinity
[ Upstream commit 958f2a0f8121ae36a5cbff383ab94fadf1fba5eb ]
There was a few false alarms sighted on target side about wrong data digest while performing high throughput load to XFS filesystem shared through NVMoF TCP.
This flag tells the rest of the kernel to ensure that the data buffer does not change while the write is in flight. It incurs a performance penalty, so only enable it when it is actually needed, i.e. when we are calculating data digests.
Although even with this change in place, ext2 users can steel experience false positives, as ext2 is not respecting this flag. This may be apply to vfat as well.
Signed-off-by: Mikhail Skorzhinskii mskorzhinskiy@solarflare.com Signed-off-by: Mike Playle mplayle@solarflare.com Reviewed-by: Sagi Grimberg sagi@grimberg.me Signed-off-by: Christoph Hellwig hch@lst.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvme/host/core.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 22c68e3b71d5..215bef904b7b 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -11,6 +11,7 @@ #include <linux/hdreg.h> #include <linux/kernel.h> #include <linux/module.h> +#include <linux/backing-dev.h> #include <linux/list_sort.h> #include <linux/slab.h> #include <linux/types.h> @@ -3256,6 +3257,10 @@ static int nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid) goto out_free_ns; }
+ if (ctrl->opts->data_digest) + ns->queue->backing_dev_info->capabilities + |= BDI_CAP_STABLE_WRITES; + blk_queue_flag_set(QUEUE_FLAG_NONROT, ns->queue); if (ctrl->ops->flags & NVME_F_PCI_P2PDMA) blk_queue_flag_set(QUEUE_FLAG_PCI_P2PDMA, ns->queue);
[ Upstream commit 0fc12c022ad25532b66bf6f6c818ee1c1d63e702 ]
When CONFIG_PPC_IRQ_SOFT_MASK_DEBUG is enabled (uncommon), we have a series of WARN_ON's in arch_local_irq_restore().
These are "should never happen" conditions, but if they do happen they can flood the console and render the system unusable. So switch them to WARN_ON_ONCE().
Fixes: e2b36d591720 ("powerpc/64: Don't trace code that runs with the soft irq mask unreconciled") Fixes: 9b81c0211c24 ("powerpc/64s: make PACA_IRQ_HARD_DIS track MSR[EE] closely") Fixes: 7c0482e3d055 ("powerpc/irq: Fix another case of lazy IRQ state getting out of sync") Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20190708061046.7075-1-mpe@ellerman.id.au Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/kernel/irq.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index bc68c53af67c..5645bc9cbc09 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -255,7 +255,7 @@ notrace void arch_local_irq_restore(unsigned long mask) irq_happened = get_irq_happened(); if (!irq_happened) { #ifdef CONFIG_PPC_IRQ_SOFT_MASK_DEBUG - WARN_ON(!(mfmsr() & MSR_EE)); + WARN_ON_ONCE(!(mfmsr() & MSR_EE)); #endif return; } @@ -268,7 +268,7 @@ notrace void arch_local_irq_restore(unsigned long mask) */ if (!(irq_happened & PACA_IRQ_HARD_DIS)) { #ifdef CONFIG_PPC_IRQ_SOFT_MASK_DEBUG - WARN_ON(!(mfmsr() & MSR_EE)); + WARN_ON_ONCE(!(mfmsr() & MSR_EE)); #endif __hard_irq_disable(); #ifdef CONFIG_PPC_IRQ_SOFT_MASK_DEBUG @@ -279,7 +279,7 @@ notrace void arch_local_irq_restore(unsigned long mask) * warn if we are wrong. Only do that when IRQ tracing * is enabled as mfmsr() can be costly. */ - if (WARN_ON(mfmsr() & MSR_EE)) + if (WARN_ON_ONCE(mfmsr() & MSR_EE)) __hard_irq_disable(); #endif }
[ Upstream commit 9e005b761e7ad153dcf40a6cba1d681fe0830ac6 ]
The next commit will make the way of passing CONFIG options more robust. Unfortunately, it would uncover another hidden issue; without this commit, skiroot_defconfig would be broken like this:
| WRAP arch/powerpc/boot/zImage.pseries | arch/powerpc/boot/wrapper.a(decompress.o): In function `bcj_powerpc.isra.10': | decompress.c:(.text+0x720): undefined reference to `get_unaligned_be32' | decompress.c:(.text+0x7a8): undefined reference to `put_unaligned_be32' | make[1]: *** [arch/powerpc/boot/Makefile;383: arch/powerpc/boot/zImage.pseries] Error 1 | make: *** [arch/powerpc/Makefile;295: zImage] Error 2
skiroot_defconfig is the only defconfig that enables CONFIG_KERNEL_XZ for ppc, which has never been correctly built before.
I figured out the root cause in lib/decompress_unxz.c:
| #ifdef CONFIG_PPC | # define XZ_DEC_POWERPC | #endif
CONFIG_PPC is undefined here in the ppc bootwrapper because autoconf.h is not included except by arch/powerpc/boot/serial.c
XZ_DEC_POWERPC is not defined, therefore, bcj_powerpc() is not compiled for the bootwrapper.
With the next commit passing CONFIG_PPC correctly, we would realize that {get,put}_unaligned_be32 was missing.
Unlike the other decompressors, the ppc bootwrapper duplicates all the necessary helpers in arch/powerpc/boot/.
The other architectures define __KERNEL__ and pull in helpers for building the decompressors.
If ppc bootwrapper had defined __KERNEL__, lib/xz/xz_private.h would have included <asm/unaligned.h>:
| #ifdef __KERNEL__ | # include <linux/xz.h> | # include <linux/kernel.h> | # include <asm/unaligned.h>
However, doing so would cause tons of definition conflicts since the bootwrapper has duplicated everything.
I just added copies of {get,put}_unaligned_be32, following the bootwrapper coding convention.
Signed-off-by: Masahiro Yamada yamada.masahiro@socionext.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20190705100144.28785-1-yamada.masahiro@socionext.c... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/boot/xz_config.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)
diff --git a/arch/powerpc/boot/xz_config.h b/arch/powerpc/boot/xz_config.h index e22e5b3770dd..ebfadd39e192 100644 --- a/arch/powerpc/boot/xz_config.h +++ b/arch/powerpc/boot/xz_config.h @@ -20,10 +20,30 @@ static inline uint32_t swab32p(void *p)
#ifdef __LITTLE_ENDIAN__ #define get_le32(p) (*((uint32_t *) (p))) +#define cpu_to_be32(x) swab32(x) +static inline u32 be32_to_cpup(const u32 *p) +{ + return swab32p((u32 *)p); +} #else #define get_le32(p) swab32p(p) +#define cpu_to_be32(x) (x) +static inline u32 be32_to_cpup(const u32 *p) +{ + return *p; +} #endif
+static inline uint32_t get_unaligned_be32(const void *p) +{ + return be32_to_cpup(p); +} + +static inline void put_unaligned_be32(u32 val, void *p) +{ + *((u32 *)p) = cpu_to_be32(val); +} + #define memeq(a, b, size) (memcmp(a, b, size) == 0) #define memzero(buf, size) memset(buf, 0, size)
[ Upstream commit b554db147feea39617b533ab6bca247c91c6198a ]
We discovered a problem in newer kernels where a disconnect of a NBD device while the flush request was pending would result in a hang. This is because the blk mq timeout handler does
if (!refcount_inc_not_zero(&rq->ref)) return true;
to determine if it's ok to run the timeout handler for the request. Flush_rq's don't have a ref count set, so we'd skip running the timeout handler for this request and it would just sit there in limbo forever.
Fix this by always setting the refcount of any request going through blk_init_rq() to 1. I tested this with a nbd-server that dropped flush requests to verify that it hung, and then tested with this patch to verify I got the timeout as expected and the error handling kicked in. Thanks,
Signed-off-by: Josef Bacik josef@toxicpanda.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- block/blk-core.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/block/blk-core.c b/block/blk-core.c index 8340f69670d8..5183fca0818a 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -117,6 +117,7 @@ void blk_rq_init(struct request_queue *q, struct request *rq) rq->internal_tag = -1; rq->start_time_ns = ktime_get_ns(); rq->part = NULL; + refcount_set(&rq->ref, 1); } EXPORT_SYMBOL(blk_rq_init);
[ Upstream commit 8c6166cfc9cd48e93d9176561e50b63cef4330d5 ]
Prior to commit d021fabf525ff ("rds: rdma: add consumer reject")
function "rds_rdma_cm_event_handler_cmn" would always honor a rejected connection attempt by issuing a "rds_conn_drop".
The commit mentioned above added a "break", eliminating the "fallthrough" case and made the "rds_conn_drop" rather conditional:
Now it only happens if a "consumer defined" reject (i.e. "rdma_reject") carries an integer-value of "1" inside "private_data":
if (!conn) break; err = (int *)rdma_consumer_reject_data(cm_id, event, &len); if (!err || (err && ((*err) == RDS_RDMA_REJ_INCOMPAT))) { pr_warn("RDS/RDMA: conn <%pI6c, %pI6c> rejected, dropping connection\n", &conn->c_laddr, &conn->c_faddr); conn->c_proposed_version = RDS_PROTOCOL_COMPAT_VERSION; rds_conn_drop(conn); } rdsdebug("Connection rejected: %s\n", rdma_reject_msg(cm_id, event->status)); break; /* FALLTHROUGH */ A number of issues are worth mentioning here: #1) Previous versions of the RDS code simply rejected a connection by calling "rdma_reject(cm_id, NULL, 0);" So the value of the payload in "private_data" will not be "1", but "0".
#2) Now the code has become dependent on host byte order and sizing. If one peer is big-endian, the other is little-endian, or there's a difference in sizeof(int) (e.g. ILP64 vs LP64), the *err check does not work as intended.
#3) There is no check for "len" to see if the data behind *err is even valid. Luckily, it appears that the "rdma_reject(cm_id, NULL, 0)" will always carry 148 bytes of zeroized payload. But that should probably not be relied upon here.
#4) With the added "break;", we might as well drop the misleading "/* FALLTHROUGH */" comment.
This commit does _not_ address issue #2, as the sender would have to agree on a byte order as well.
Here is the sequence of messages in this observed error-scenario: Host-A is pre-QoS changes (excluding the commit mentioned above) Host-B is post-QoS changes (including the commit mentioned above)
#1 Host-B issues a connection request via function "rds_conn_path_transition" connection state transitions to "RDS_CONN_CONNECTING"
#2 Host-A rejects the incompatible connection request (from #1) It does so by calling "rdma_reject(cm_id, NULL, 0);"
#3 Host-B receives an "RDMA_CM_EVENT_REJECTED" event (from #2) But since the code is changed in the way described above, it won't drop the connection here, simply because "*err == 0".
#4 Host-A issues a connection request
#5 Host-B receives an "RDMA_CM_EVENT_CONNECT_REQUEST" event and ends up calling "rds_ib_cm_handle_connect". But since the state is already in "RDS_CONN_CONNECTING" (as of #1) it will end up issuing a "rdma_reject" without dropping the connection: if (rds_conn_state(conn) == RDS_CONN_CONNECTING) { /* Wait and see - our connect may still be succeeding */ rds_ib_stats_inc(s_ib_connect_raced); } goto out;
#6 Host-A receives an "RDMA_CM_EVENT_REJECTED" event (from #5), drops the connection and tries again (goto #4) until it gives up.
Tested-by: Zhu Yanjun yanjun.zhu@oracle.com Signed-off-by: Gerd Rausch gerd.rausch@oracle.com Signed-off-by: Santosh Shilimkar santosh.shilimkar@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/rds/rdma_transport.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/net/rds/rdma_transport.c b/net/rds/rdma_transport.c index 46bce8389066..9db455d02255 100644 --- a/net/rds/rdma_transport.c +++ b/net/rds/rdma_transport.c @@ -112,7 +112,9 @@ static int rds_rdma_cm_event_handler_cmn(struct rdma_cm_id *cm_id, if (!conn) break; err = (int *)rdma_consumer_reject_data(cm_id, event, &len); - if (!err || (err && ((*err) == RDS_RDMA_REJ_INCOMPAT))) { + if (!err || + (err && len >= sizeof(*err) && + ((*err) <= RDS_RDMA_REJ_INCOMPAT))) { pr_warn("RDS/RDMA: conn <%pI6c, %pI6c> rejected, dropping connection\n", &conn->c_laddr, &conn->c_faddr); conn->c_proposed_version = RDS_PROTOCOL_COMPAT_VERSION; @@ -122,7 +124,6 @@ static int rds_rdma_cm_event_handler_cmn(struct rdma_cm_id *cm_id, rdsdebug("Connection rejected: %s\n", rdma_reject_msg(cm_id, event->status)); break; - /* FALLTHROUGH */ case RDMA_CM_EVENT_ADDR_ERROR: case RDMA_CM_EVENT_ROUTE_ERROR: case RDMA_CM_EVENT_CONNECT_ERROR:
[ Upstream commit 6e0cd4a9dd4df1a0afcb454f1e654b5c80685913 ]
In umount, we give an constand time to handle pending discard, previously, in __issue_discard_cmd() we missed to check timeout condition in loop, result in delaying long time, fix it.
Signed-off-by: Heng Xiao heng.xiao@unisoc.com [Chao Yu: add commit message] 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/segment.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 8903b61457e7..291f7106537c 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -1486,6 +1486,10 @@ static int __issue_discard_cmd(struct f2fs_sb_info *sbi, list_for_each_entry_safe(dc, tmp, pend_list, list) { f2fs_bug_on(sbi, dc->state != D_PREP);
+ if (dpolicy->timeout != 0 && + f2fs_time_over(sbi, dpolicy->timeout)) + break; + if (dpolicy->io_aware && i < dpolicy->io_aware_gran && !is_idle(sbi, DISCARD_TIME)) { io_interrupted = true;
[ Upstream commit 56f3ce675103e3fb9e631cfb4131fc768bc23e9a ]
blkoff_off might over 512 due to fs corrupt or security vulnerability. That should be checked before being using.
Use ENTRIES_IN_SUM to protect invalid value in cur_data_blkoff.
Signed-off-by: Ocean Chen oceanchen@google.com Reviewed-by: Chao Yu yuchao0@huawei.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/segment.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 291f7106537c..ce15fbcd7cff 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -3403,6 +3403,11 @@ static int read_compacted_summaries(struct f2fs_sb_info *sbi) seg_i = CURSEG_I(sbi, i); segno = le32_to_cpu(ckpt->cur_data_segno[i]); blk_off = le16_to_cpu(ckpt->cur_data_blkoff[i]); + if (blk_off > ENTRIES_IN_SUM) { + f2fs_bug_on(sbi, 1); + f2fs_put_page(page, 1); + return -EFAULT; + } seg_i->next_segno = segno; reset_curseg(sbi, i, 0); seg_i->alloc_type = ckpt->alloc_type[i];
[ Upstream commit 25777e5784a7b417967460d4fcf9660d05a0c320 ]
Previously, if mbox_request_channel_byname was used with a name which did not exist in the "mbox-names" property of a mailbox client, the mailbox corresponding to the last entry in the "mbox-names" list would be incorrectly selected. With this patch, -EINVAL is returned if the named mailbox is not found.
Signed-off-by: Morten Borup Petersen morten_bp@live.dk Signed-off-by: Jassi Brar jaswinder.singh@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mailbox/mailbox.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c index f4b1950d35f3..0b821a5b2db8 100644 --- a/drivers/mailbox/mailbox.c +++ b/drivers/mailbox/mailbox.c @@ -418,11 +418,13 @@ struct mbox_chan *mbox_request_channel_byname(struct mbox_client *cl,
of_property_for_each_string(np, "mbox-names", prop, mbox_name) { if (!strncmp(name, mbox_name, strlen(name))) - break; + return mbox_request_channel(cl, index); index++; }
- return mbox_request_channel(cl, index); + dev_err(cl->dev, "%s() could not locate channel named "%s"\n", + __func__, name); + return ERR_PTR(-EINVAL); } EXPORT_SYMBOL_GPL(mbox_request_channel_byname);
[ Upstream commit b355516f450703c9015316e429b66a93dfff0e6f ]
If the DLM lowcomms stack is shut down before any DLM traffic can be generated, flush_workqueue() and destroy_workqueue() can be called on empty send and/or recv workqueues.
Insert guard conditionals to only call flush_workqueue() and destroy_workqueue() on workqueues that are not NULL.
Signed-off-by: David Windsor dwindsor@redhat.com Signed-off-by: David Teigland teigland@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/dlm/lowcomms.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c index 114ebfe30929..3951d39b9b75 100644 --- a/fs/dlm/lowcomms.c +++ b/fs/dlm/lowcomms.c @@ -1628,8 +1628,10 @@ static void clean_writequeues(void)
static void work_stop(void) { - destroy_workqueue(recv_workqueue); - destroy_workqueue(send_workqueue); + if (recv_workqueue) + destroy_workqueue(recv_workqueue); + if (send_workqueue) + destroy_workqueue(send_workqueue); }
static int work_start(void) @@ -1689,13 +1691,17 @@ static void work_flush(void) struct hlist_node *n; struct connection *con;
- flush_workqueue(recv_workqueue); - flush_workqueue(send_workqueue); + if (recv_workqueue) + flush_workqueue(recv_workqueue); + if (send_workqueue) + flush_workqueue(send_workqueue); do { ok = 1; foreach_conn(stop_conn); - flush_workqueue(recv_workqueue); - flush_workqueue(send_workqueue); + if (recv_workqueue) + flush_workqueue(recv_workqueue); + if (send_workqueue) + flush_workqueue(send_workqueue); for (i = 0; i < CONN_HASH_SIZE && ok; i++) { hlist_for_each_entry_safe(con, n, &connection_hash[i], list) {
[ Upstream commit 33439620680be5225c1b8806579a291e0d761ca0 ]
In commit 4a7b06c157a2 ("powerpc/eeh: Handle hugepages in ioremap space") support for using hugepages in the vmalloc and ioremap areas was enabled for radix. Unfortunately this broke EEH MMIO error checking.
Detection works by inserting a hook which checks the results of the ioreadXX() set of functions. When a read returns a 0xFFs response we need to check for an error which we do by mapping the (virtual) MMIO address back to a physical address, then mapping physical address to a PCI device via an interval tree.
When translating virt -> phys we currently assume the ioremap space is only populated by PAGE_SIZE mappings. If a hugepage mapping is found we emit a WARN_ON(), but otherwise handles the check as though a normal page was found. In pathalogical cases such as copying a buffer containing a lot of 0xFFs from BAR memory this can result in the system not booting because it's too busy printing WARN_ON()s.
There's no real reason to assume huge pages can't be present and we're prefectly capable of handling them, so do that.
Fixes: 4a7b06c157a2 ("powerpc/eeh: Handle hugepages in ioremap space") Reported-by: Sachin Sant sachinp@linux.vnet.ibm.com Signed-off-by: Oliver O'Halloran oohall@gmail.com Tested-by: Sachin Sant sachinp@linux.vnet.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20190710150517.27114-1-oohall@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/kernel/eeh.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c index f192d57db47d..c0e4b73191f3 100644 --- a/arch/powerpc/kernel/eeh.c +++ b/arch/powerpc/kernel/eeh.c @@ -354,10 +354,19 @@ static inline unsigned long eeh_token_to_phys(unsigned long token) ptep = find_init_mm_pte(token, &hugepage_shift); if (!ptep) return token; - WARN_ON(hugepage_shift); - pa = pte_pfn(*ptep) << PAGE_SHIFT;
- return pa | (token & (PAGE_SIZE-1)); + pa = pte_pfn(*ptep); + + /* On radix we can do hugepage mappings for io, so handle that */ + if (hugepage_shift) { + pa <<= hugepage_shift; + pa |= token & ((1ul << hugepage_shift) - 1); + } else { + pa <<= PAGE_SHIFT; + pa |= token & (PAGE_SIZE - 1); + } + + return pa; }
/*
[ Upstream commit 7d67c8ac25fbc66ee254aa3e33329d1c9bc152ce ]
Fix Kconfig warning for PCENGINES_APU2 symbol:
WARNING: unmet direct dependencies detected for GPIO_AMD_FCH Depends on [n]: GPIOLIB [=n] && HAS_IOMEM [=y] Selected by [y]: - PCENGINES_APU2 [=y] && X86 [=y] && X86_PLATFORM_DEVICES [=y] && INPUT [=y] && INPUT_KEYBOARD [=y] && LEDS_CLASS [=y]
WARNING: unmet direct dependencies detected for KEYBOARD_GPIO_POLLED Depends on [n]: !UML && INPUT [=y] && INPUT_KEYBOARD [=y] && GPIOLIB [=n] Selected by [y]: - PCENGINES_APU2 [=y] && X86 [=y] && X86_PLATFORM_DEVICES [=y] && INPUT [=y] && INPUT_KEYBOARD [=y] && LEDS_CLASS [=y]
Add GPIOLIB dependency to fix it.
Reported-by: Hulk Robot hulkci@huawei.com Fixes: f8eb0235f659 ("x86: pcengines apuv2 gpio/leds/keys platform driver") Signed-off-by: YueHaibing yuehaibing@huawei.com Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/x86/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 5d5cc6111081..7c2fd1d72e18 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -1317,7 +1317,7 @@ config HUAWEI_WMI
config PCENGINES_APU2 tristate "PC Engines APUv2/3 front button and LEDs driver" - depends on INPUT && INPUT_KEYBOARD + depends on INPUT && INPUT_KEYBOARD && GPIOLIB depends on LEDS_CLASS select GPIO_AMD_FCH select KEYBOARD_GPIO_POLLED
[ Upstream commit e7bf90e5afe3aa1d1282c1635a49e17a32c4ecec ]
In bio_integrity_prep(), a kernel buffer is allocated through kmalloc() to hold integrity metadata. Later on, the buffer will be attached to the bio structure through bio_integrity_add_page(), which returns the number of bytes of integrity metadata attached. Due to unexpected situations, bio_integrity_add_page() may return 0. As a result, bio_integrity_prep() needs to be terminated with 'false' returned to indicate this error. However, the allocated kernel buffer is not freed on this execution path, leading to a memory leak.
To fix this issue, free the allocated buffer before returning from bio_integrity_prep().
Reviewed-by: Ming Lei ming.lei@redhat.com Acked-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Wenwen Wang wenwen@cs.uga.edu Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- block/bio-integrity.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/block/bio-integrity.c b/block/bio-integrity.c index 4db620849515..fb95dbb21dd8 100644 --- a/block/bio-integrity.c +++ b/block/bio-integrity.c @@ -276,8 +276,12 @@ bool bio_integrity_prep(struct bio *bio) ret = bio_integrity_add_page(bio, virt_to_page(buf), bytes, offset);
- if (ret == 0) - return false; + if (ret == 0) { + printk(KERN_ERR "could not attach integrity payload\n"); + kfree(buf); + status = BLK_STS_RESOURCE; + goto err_end_io; + }
if (ret < bytes) break;
[ Upstream commit 7d30c81b80ea9b0812d27030a46a5bf4c4e328f5 ]
git://git.infradead.org/nvme.git nvme-5.3 branch now causes the following NULL deref oops. Check the ctrl->opts first before the deref.
[ 16.337581] BUG: kernel NULL pointer dereference, address: 0000000000000056 [ 16.338551] #PF: supervisor read access in kernel mode [ 16.338551] #PF: error_code(0x0000) - not-present page [ 16.338551] PGD 0 P4D 0 [ 16.338551] Oops: 0000 [#1] SMP PTI [ 16.338551] CPU: 2 PID: 1035 Comm: kworker/u16:5 Not tainted 5.2.0-rc6+ #1 [ 16.338551] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.11.2-0-gf9626ccb91-prebuilt.qemu-project.org 04/01/2014 [ 16.338551] Workqueue: nvme-wq nvme_scan_work [nvme_core] [ 16.338551] RIP: 0010:nvme_validate_ns+0xc9/0x7e0 [nvme_core] [ 16.338551] Code: c0 49 89 c5 0f 84 00 07 00 00 48 8b 7b 58 e8 be 48 39 c1 48 3d 00 f0 ff ff 49 89 45 18 0f 87 a4 06 00 00 48 8b 93 70 0a 00 00 <80> 7a 56 00 74 0c 48 8b 40 68 83 48 3c 08 49 8b 45 18 48 89 c6 bf [ 16.338551] RSP: 0018:ffffc900024c7d10 EFLAGS: 00010283 [ 16.338551] RAX: ffff888135a30720 RBX: ffff88813a4fd1f8 RCX: 0000000000000007 [ 16.338551] RDX: 0000000000000000 RSI: ffffffff8256dd38 RDI: ffff888135a30720 [ 16.338551] RBP: 0000000000000001 R08: 0000000000000007 R09: ffff88813aa6a840 [ 16.338551] R10: 0000000000000001 R11: 000000000002d060 R12: ffff88813a4fd1f8 [ 16.338551] R13: ffff88813a77f800 R14: ffff88813aa35180 R15: 0000000000000001 [ 16.338551] FS: 0000000000000000(0000) GS:ffff88813ba80000(0000) knlGS:0000000000000000 [ 16.338551] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 16.338551] CR2: 0000000000000056 CR3: 000000000240a002 CR4: 0000000000360ee0 [ 16.338551] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 16.338551] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 16.338551] Call Trace: [ 16.338551] nvme_scan_work+0x2c0/0x340 [nvme_core] [ 16.338551] ? __switch_to_asm+0x40/0x70 [ 16.338551] ? _raw_spin_unlock_irqrestore+0x18/0x30 [ 16.338551] ? try_to_wake_up+0x408/0x450 [ 16.338551] process_one_work+0x20b/0x3e0 [ 16.338551] worker_thread+0x1f9/0x3d0 [ 16.338551] ? cancel_delayed_work+0xa0/0xa0 [ 16.338551] kthread+0x117/0x120 [ 16.338551] ? kthread_stop+0xf0/0xf0 [ 16.338551] ret_from_fork+0x3a/0x50 [ 16.338551] Modules linked in: nvme nvme_core [ 16.338551] CR2: 0000000000000056 [ 16.338551] ---[ end trace b9bf761a93e62d84 ]--- [ 16.338551] RIP: 0010:nvme_validate_ns+0xc9/0x7e0 [nvme_core] [ 16.338551] Code: c0 49 89 c5 0f 84 00 07 00 00 48 8b 7b 58 e8 be 48 39 c1 48 3d 00 f0 ff ff 49 89 45 18 0f 87 a4 06 00 00 48 8b 93 70 0a 00 00 <80> 7a 56 00 74 0c 48 8b 40 68 83 48 3c 08 49 8b 45 18 48 89 c6 bf [ 16.338551] RSP: 0018:ffffc900024c7d10 EFLAGS: 00010283 [ 16.338551] RAX: ffff888135a30720 RBX: ffff88813a4fd1f8 RCX: 0000000000000007 [ 16.338551] RDX: 0000000000000000 RSI: ffffffff8256dd38 RDI: ffff888135a30720 [ 16.338551] RBP: 0000000000000001 R08: 0000000000000007 R09: ffff88813aa6a840 [ 16.338551] R10: 0000000000000001 R11: 000000000002d060 R12: ffff88813a4fd1f8 [ 16.338551] R13: ffff88813a77f800 R14: ffff88813aa35180 R15: 0000000000000001 [ 16.338551] FS: 0000000000000000(0000) GS:ffff88813ba80000(0000) knlGS:0000000000000000 [ 16.338551] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 16.338551] CR2: 0000000000000056 CR3: 000000000240a002 CR4: 0000000000360ee0 [ 16.338551] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 16.338551] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Fixes: 958f2a0f8121 ("nvme-tcp: set the STABLE_WRITES flag when data digests are enabled") Cc: Christoph Hellwig hch@lst.de Cc: Keith Busch kbusch@kernel.org Reviewed-by: Sagi Grimberg sagi@grimberg.me Signed-off-by: Minwoo Im minwoo.im.dev@gmail.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvme/host/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 215bef904b7b..4a1d2ab4d161 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -3257,7 +3257,7 @@ static int nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid) goto out_free_ns; }
- if (ctrl->opts->data_digest) + if (ctrl->opts && ctrl->opts->data_digest) ns->queue->backing_dev_info->capabilities |= BDI_CAP_STABLE_WRITES;
[ Upstream commit 733f0025f0fb43e382b84db0930ae502099b7e62 ]
When building drm/exynos for sh, as part of an allmodconfig build, the following warning triggered:
exynos7_drm_decon.c: In function `decon_remove': exynos7_drm_decon.c:769:24: warning: unused variable `ctx' struct decon_context *ctx = dev_get_drvdata(&pdev->dev);
The ctx variable is only used as argument to iounmap().
In sh - allmodconfig CONFIG_MMU is not defined so it ended up in:
#define __iounmap(addr) do { } while (0) #define iounmap __iounmap
Fix the warning by introducing a static inline function for iounmap.
This is similar to several other architectures.
Link: http://lkml.kernel.org/r/20190622114208.24427-1-sam@ravnborg.org Signed-off-by: Sam Ravnborg sam@ravnborg.org Reviewed-by: Geert Uytterhoeven geert+renesas@glider.be Cc: Yoshinori Sato ysato@users.sourceforge.jp Cc: Rich Felker dalias@libc.org Cc: Will Deacon will.deacon@arm.com Cc: Mark Brown broonie@kernel.org Cc: Inki Dae inki.dae@samsung.com Cc: Krzysztof Kozlowski krzk@kernel.org 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 --- arch/sh/include/asm/io.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h index c28e37a344ad..ac0561960c52 100644 --- a/arch/sh/include/asm/io.h +++ b/arch/sh/include/asm/io.h @@ -369,7 +369,11 @@ static inline int iounmap_fixed(void __iomem *addr) { return -EINVAL; }
#define ioremap_nocache ioremap #define ioremap_uc ioremap -#define iounmap __iounmap + +static inline void iounmap(void __iomem *addr) +{ + __iounmap(addr); +}
/* * Convert a physical pointer to a virtual kernel pointer for /dev/mem
[ Upstream commit 6ef9056952532c3b746de46aa10d45b4d7797bd8 ]
in_softirq() is a wrong predicate to check if we are in a softirq context. It also returns true if we have BH disabled, so objects are falsely stamped with "softirq" comm. The correct predicate is in_serving_softirq().
If user does cat from /sys/kernel/debug/kmemleak previously they would see this, which is clearly wrong, this is system call context (see the comm):
unreferenced object 0xffff88805bd661c0 (size 64): comm "softirq", pid 0, jiffies 4294942959 (age 12.400s) hex dump (first 32 bytes): 00 00 00 00 00 00 00 00 ff ff ff ff 00 00 00 00 ................ 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 ................ backtrace: [<0000000007dcb30c>] kmemleak_alloc_recursive include/linux/kmemleak.h:55 [inline] [<0000000007dcb30c>] slab_post_alloc_hook mm/slab.h:439 [inline] [<0000000007dcb30c>] slab_alloc mm/slab.c:3326 [inline] [<0000000007dcb30c>] kmem_cache_alloc_trace+0x13d/0x280 mm/slab.c:3553 [<00000000969722b7>] kmalloc include/linux/slab.h:547 [inline] [<00000000969722b7>] kzalloc include/linux/slab.h:742 [inline] [<00000000969722b7>] ip_mc_add1_src net/ipv4/igmp.c:1961 [inline] [<00000000969722b7>] ip_mc_add_src+0x36b/0x400 net/ipv4/igmp.c:2085 [<00000000a4134b5f>] ip_mc_msfilter+0x22d/0x310 net/ipv4/igmp.c:2475 [<00000000d20248ad>] do_ip_setsockopt.isra.0+0x19fe/0x1c00 net/ipv4/ip_sockglue.c:957 [<000000003d367be7>] ip_setsockopt+0x3b/0xb0 net/ipv4/ip_sockglue.c:1246 [<000000003c7c76af>] udp_setsockopt+0x4e/0x90 net/ipv4/udp.c:2616 [<000000000c1aeb23>] sock_common_setsockopt+0x3e/0x50 net/core/sock.c:3130 [<000000000157b92b>] __sys_setsockopt+0x9e/0x120 net/socket.c:2078 [<00000000a9f3d058>] __do_sys_setsockopt net/socket.c:2089 [inline] [<00000000a9f3d058>] __se_sys_setsockopt net/socket.c:2086 [inline] [<00000000a9f3d058>] __x64_sys_setsockopt+0x26/0x30 net/socket.c:2086 [<000000001b8da885>] do_syscall_64+0x7c/0x1a0 arch/x86/entry/common.c:301 [<00000000ba770c62>] entry_SYSCALL_64_after_hwframe+0x44/0xa9
now they will see this:
unreferenced object 0xffff88805413c800 (size 64): comm "syz-executor.4", pid 8960, jiffies 4294994003 (age 14.350s) hex dump (first 32 bytes): 00 7a 8a 57 80 88 ff ff e0 00 00 01 00 00 00 00 .z.W............ 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 ................ backtrace: [<00000000c5d3be64>] kmemleak_alloc_recursive include/linux/kmemleak.h:55 [inline] [<00000000c5d3be64>] slab_post_alloc_hook mm/slab.h:439 [inline] [<00000000c5d3be64>] slab_alloc mm/slab.c:3326 [inline] [<00000000c5d3be64>] kmem_cache_alloc_trace+0x13d/0x280 mm/slab.c:3553 [<0000000023865be2>] kmalloc include/linux/slab.h:547 [inline] [<0000000023865be2>] kzalloc include/linux/slab.h:742 [inline] [<0000000023865be2>] ip_mc_add1_src net/ipv4/igmp.c:1961 [inline] [<0000000023865be2>] ip_mc_add_src+0x36b/0x400 net/ipv4/igmp.c:2085 [<000000003029a9d4>] ip_mc_msfilter+0x22d/0x310 net/ipv4/igmp.c:2475 [<00000000ccd0a87c>] do_ip_setsockopt.isra.0+0x19fe/0x1c00 net/ipv4/ip_sockglue.c:957 [<00000000a85a3785>] ip_setsockopt+0x3b/0xb0 net/ipv4/ip_sockglue.c:1246 [<00000000ec13c18d>] udp_setsockopt+0x4e/0x90 net/ipv4/udp.c:2616 [<0000000052d748e3>] sock_common_setsockopt+0x3e/0x50 net/core/sock.c:3130 [<00000000512f1014>] __sys_setsockopt+0x9e/0x120 net/socket.c:2078 [<00000000181758bc>] __do_sys_setsockopt net/socket.c:2089 [inline] [<00000000181758bc>] __se_sys_setsockopt net/socket.c:2086 [inline] [<00000000181758bc>] __x64_sys_setsockopt+0x26/0x30 net/socket.c:2086 [<00000000d4b73623>] do_syscall_64+0x7c/0x1a0 arch/x86/entry/common.c:301 [<00000000c1098bec>] entry_SYSCALL_64_after_hwframe+0x44/0xa9
Link: http://lkml.kernel.org/r/20190517171507.96046-1-dvyukov@gmail.com Signed-off-by: Dmitry Vyukov dvyukov@google.com Acked-by: 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 --- mm/kmemleak.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mm/kmemleak.c b/mm/kmemleak.c index 9dd581d11565..3e147ea83182 100644 --- a/mm/kmemleak.c +++ b/mm/kmemleak.c @@ -575,7 +575,7 @@ static struct kmemleak_object *create_object(unsigned long ptr, size_t size, if (in_irq()) { object->pid = 0; strncpy(object->comm, "hardirq", sizeof(object->comm)); - } else if (in_softirq()) { + } else if (in_serving_softirq()) { object->pid = 0; strncpy(object->comm, "softirq", sizeof(object->comm)); } else {
[ Upstream commit f053cbd4366051d7eb6ba1b8d529d20f719c2963 ]
Fix the callback 9p passes to read_cache_page to actually have the proper type expected. Casting around function pointers can easily hide typing bugs, and defeats control flow protection.
Link: http://lkml.kernel.org/r/20190520055731.24538-5-hch@lst.de Signed-off-by: Christoph Hellwig hch@lst.de Reviewed-by: Kees Cook keescook@chromium.org Cc: Sami Tolvanen samitolvanen@google.com Cc: Nick Desaulniers ndesaulniers@google.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/9p/vfs_addr.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c index bc57ae9e2963..cce9ace651a2 100644 --- a/fs/9p/vfs_addr.c +++ b/fs/9p/vfs_addr.c @@ -35,8 +35,9 @@ * @page: structure to page * */ -static int v9fs_fid_readpage(struct p9_fid *fid, struct page *page) +static int v9fs_fid_readpage(void *data, struct page *page) { + struct p9_fid *fid = data; struct inode *inode = page->mapping->host; struct bio_vec bvec = {.bv_page = page, .bv_len = PAGE_SIZE}; struct iov_iter to; @@ -107,7 +108,8 @@ static int v9fs_vfs_readpages(struct file *filp, struct address_space *mapping, if (ret == 0) return ret;
- ret = read_cache_pages(mapping, pages, (void *)v9fs_vfs_readpage, filp); + ret = read_cache_pages(mapping, pages, v9fs_fid_readpage, + filp->private_data); p9_debug(P9_DEBUG_VFS, " = %d\n", ret); return ret; }
[ Upstream commit aeb309b81c6bada783c3695528a3e10748e97285 ]
Via commit 4b3ef9daa4fc ("mm/swap: split swap cache into 64MB trunks"), after swapoff, the address_space associated with the swap device will be freed. So swap_address_space() users which touch the address_space need some kind of mechanism to prevent the address_space from being freed during accessing.
When mincore processes an unmapped range for swapped shmem pages, it doesn't hold the lock to prevent swap device from being swapped off. So the following race is possible:
CPU1 CPU2 do_mincore() swapoff() walk_page_range() mincore_unmapped_range() __mincore_unmapped_range mincore_page as = swap_address_space() ... exit_swap_address_space() ... kvfree(spaces) find_get_page(as)
The address space may be accessed after being freed.
To fix the race, get_swap_device()/put_swap_device() is used to enclose find_get_page() to check whether the swap entry is valid and prevent the swap device from being swapoff during accessing.
Link: http://lkml.kernel.org/r/20190611020510.28251-1-ying.huang@intel.com Fixes: 4b3ef9daa4fc ("mm/swap: split swap cache into 64MB trunks") Signed-off-by: "Huang, Ying" ying.huang@intel.com Reviewed-by: Andrew Morton akpm@linux-foundation.org Acked-by: Michal Hocko mhocko@suse.com Cc: Hugh Dickins hughd@google.com Cc: Paul E. McKenney paulmck@linux.vnet.ibm.com Cc: Minchan Kim minchan@kernel.org Cc: Johannes Weiner hannes@cmpxchg.org Cc: Tim Chen tim.c.chen@linux.intel.com Cc: Mel Gorman mgorman@techsingularity.net Cc: Jérôme Glisse jglisse@redhat.com Cc: Andrea Arcangeli aarcange@redhat.com Cc: Yang Shi yang.shi@linux.alibaba.com Cc: David Rientjes rientjes@google.com Cc: Rik van Riel riel@redhat.com Cc: Jan Kara jack@suse.cz Cc: Dave Jiang dave.jiang@intel.com Cc: Daniel Jordan daniel.m.jordan@oracle.com Cc: Andrea Parri andrea.parri@amarulasolutions.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 --- mm/mincore.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/mm/mincore.c b/mm/mincore.c index c3f058bd0faf..4fe91d497436 100644 --- a/mm/mincore.c +++ b/mm/mincore.c @@ -68,8 +68,16 @@ static unsigned char mincore_page(struct address_space *mapping, pgoff_t pgoff) */ if (xa_is_value(page)) { swp_entry_t swp = radix_to_swp_entry(page); - page = find_get_page(swap_address_space(swp), - swp_offset(swp)); + struct swap_info_struct *si; + + /* Prevent swap device to being swapoff under us */ + si = get_swap_device(swp); + if (si) { + page = find_get_page(swap_address_space(swp), + swp_offset(swp)); + put_swap_device(si); + } else + page = NULL; } } else page = find_get_page(mapping, pgoff);
[ Upstream commit 790c73690c2bbecb3f6f8becbdb11ddc9bcff8cc ]
Several mips builds generate the following build warning.
mm/gup.c:1788:13: warning: 'undo_dev_pagemap' defined but not used
The function is declared unconditionally but only called from behind various ifdefs. Mark it __maybe_unused.
Link: http://lkml.kernel.org/r/1562072523-22311-1-git-send-email-linux@roeck-us.ne... Signed-off-by: Guenter Roeck linux@roeck-us.net Reviewed-by: Andrew Morton akpm@linux-foundation.org Cc: Stephen Rothwell sfr@canb.auug.org.au Cc: Robin Murphy robin.murphy@arm.com Cc: Kirill A. Shutemov kirill.shutemov@linux.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 --- mm/gup.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/mm/gup.c b/mm/gup.c index ddde097cf9e4..22855ff0b448 100644 --- a/mm/gup.c +++ b/mm/gup.c @@ -1696,7 +1696,8 @@ static inline pte_t gup_get_pte(pte_t *ptep) } #endif
-static void undo_dev_pagemap(int *nr, int nr_start, struct page **pages) +static void __maybe_unused undo_dev_pagemap(int *nr, int nr_start, + struct page **pages) { while ((*nr) - nr_start) { struct page *page = pages[--(*nr)];
[ Upstream commit b5d1c39f34d1c9bca0c4b9ae2e339fbbe264a9c7 ]
If we end up without a PGD or PUD entry backing the gate area, don't BUG -- just fail gracefully.
It's not entirely implausible that this could happen some day on x86. It doesn't right now even with an execute-only emulated vsyscall page because the fixmap shares the PUD, but the core mm code shouldn't rely on that particular detail to avoid OOPSing.
Link: http://lkml.kernel.org/r/a1d9f4efb75b9d464e59fd6af00104b21c58f6f7.1561610798... Signed-off-by: Andy Lutomirski luto@kernel.org Reviewed-by: Kees Cook keescook@chromium.org Reviewed-by: Andrew Morton akpm@linux-foundation.org Cc: Florian Weimer fweimer@redhat.com Cc: Jann Horn jannh@google.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 --- mm/gup.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/mm/gup.c b/mm/gup.c index 22855ff0b448..d2c14fc4b5d4 100644 --- a/mm/gup.c +++ b/mm/gup.c @@ -585,11 +585,14 @@ static int get_gate_page(struct mm_struct *mm, unsigned long address, pgd = pgd_offset_k(address); else pgd = pgd_offset_gate(mm, address); - BUG_ON(pgd_none(*pgd)); + if (pgd_none(*pgd)) + return -EFAULT; p4d = p4d_offset(pgd, address); - BUG_ON(p4d_none(*p4d)); + if (p4d_none(*p4d)) + return -EFAULT; pud = pud_offset(p4d, address); - BUG_ON(pud_none(*pud)); + if (pud_none(*pud)) + return -EFAULT; pmd = pmd_offset(pud, address); if (!pmd_present(*pmd)) return -EFAULT;
[ Upstream commit ec165450968b26298bd1c373de37b0ab6d826b33 ]
Commit d46eb14b735b ("fs: fsnotify: account fsnotify metadata to kmemcg") added remote memcg charging for fanotify and inotify event objects. The aim was to charge the memory to the listener who is interested in the events but without triggering the OOM killer. Otherwise there would be security concerns for the listener.
At the time, oom-kill trigger was not in the charging path. A parallel work added the oom-kill back to charging path i.e. commit 29ef680ae7c2 ("memcg, oom: move out_of_memory back to the charge path"). So to not trigger oom-killer in the remote memcg, explicitly add __GFP_RETRY_MAYFAIL to the fanotigy and inotify event allocations.
Link: http://lkml.kernel.org/r/20190514212259.156585-2-shakeelb@google.com Signed-off-by: Shakeel Butt shakeelb@google.com Reviewed-by: Roman Gushchin guro@fb.com Acked-by: Jan Kara jack@suse.cz Cc: Johannes Weiner hannes@cmpxchg.org Cc: Vladimir Davydov vdavydov.dev@gmail.com Cc: Michal Hocko mhocko@suse.com Cc: Amir Goldstein amir73il@gmail.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/notify/fanotify/fanotify.c | 5 ++++- fs/notify/inotify/inotify_fsnotify.c | 8 ++++++-- 2 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index b428c295d13f..5778d1347b35 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c @@ -288,10 +288,13 @@ struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group, /* * For queues with unlimited length lost events are not expected and * can possibly have security implications. Avoid losing events when - * memory is short. + * memory is short. For the limited size queues, avoid OOM killer in the + * target monitoring memcg as it may have security repercussion. */ if (group->max_events == UINT_MAX) gfp |= __GFP_NOFAIL; + else + gfp |= __GFP_RETRY_MAYFAIL;
/* Whoever is interested in the event, pays for the allocation. */ memalloc_use_memcg(group->memcg); diff --git a/fs/notify/inotify/inotify_fsnotify.c b/fs/notify/inotify/inotify_fsnotify.c index 2fda08b2b885..d510223d302c 100644 --- a/fs/notify/inotify/inotify_fsnotify.c +++ b/fs/notify/inotify/inotify_fsnotify.c @@ -90,9 +90,13 @@ int inotify_handle_event(struct fsnotify_group *group, i_mark = container_of(inode_mark, struct inotify_inode_mark, fsn_mark);
- /* Whoever is interested in the event, pays for the allocation. */ + /* + * Whoever is interested in the event, pays for the allocation. Do not + * trigger OOM killer in the target monitoring memcg as it may have + * security repercussion. + */ memalloc_use_memcg(group->memcg); - event = kmalloc(alloc_len, GFP_KERNEL_ACCOUNT); + event = kmalloc(alloc_len, GFP_KERNEL_ACCOUNT | __GFP_RETRY_MAYFAIL); memalloc_unuse_memcg();
if (unlikely(!event)) {
[ Upstream commit 543bdb2d825fe2400d6e951f1786d92139a16931 ]
Make mmu_notifier_register() safer by issuing a memory barrier before registering a new notifier. This fixes a theoretical bug on weakly ordered CPUs. For example, take this simplified use of notifiers by a driver:
my_struct->mn.ops = &my_ops; /* (1) */ mmu_notifier_register(&my_struct->mn, mm) ... hlist_add_head(&mn->hlist, &mm->mmu_notifiers); /* (2) */ ...
Once mmu_notifier_register() releases the mm locks, another thread can invalidate a range:
mmu_notifier_invalidate_range() ... hlist_for_each_entry_rcu(mn, &mm->mmu_notifiers, hlist) { if (mn->ops->invalidate_range)
The read side relies on the data dependency between mn and ops to ensure that the pointer is properly initialized. But the write side doesn't have any dependency between (1) and (2), so they could be reordered and the readers could dereference an invalid mn->ops. mmu_notifier_register() does take all the mm locks before adding to the hlist, but those have acquire semantics which isn't sufficient.
By calling hlist_add_head_rcu() instead of hlist_add_head() we update the hlist using a store-release, ensuring that readers see prior initialization of my_struct. This situation is better illustated by litmus test MP+onceassign+derefonce.
Link: http://lkml.kernel.org/r/20190502133532.24981-1-jean-philippe.brucker@arm.co... Fixes: cddb8a5c14aa ("mmu-notifiers: core") Signed-off-by: Jean-Philippe Brucker jean-philippe.brucker@arm.com Cc: Jérôme Glisse jglisse@redhat.com Cc: Michal Hocko mhocko@suse.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 --- mm/mmu_notifier.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mm/mmu_notifier.c b/mm/mmu_notifier.c index 513b9607409d..b5670620aea0 100644 --- a/mm/mmu_notifier.c +++ b/mm/mmu_notifier.c @@ -274,7 +274,7 @@ static int do_mmu_notifier_register(struct mmu_notifier *mn, * thanks to mm_take_all_locks(). */ spin_lock(&mm->mmu_notifier_mm->lock); - hlist_add_head(&mn->hlist, &mm->mmu_notifier_mm->list); + hlist_add_head_rcu(&mn->hlist, &mm->mmu_notifier_mm->list); spin_unlock(&mm->mmu_notifier_mm->lock);
mm_drop_all_locks(mm);
[ Upstream commit a26a97815548574213fd37f29b4b78ccc6d9ed20 ]
Do not remain stuck forever if something goes wrong. Using a killable lock permits cleanup of stuck tasks and simplifies investigation.
Link: http://lkml.kernel.org/r/156007493429.3335.14666825072272692455.stgit@buzz Signed-off-by: Konstantin Khlebnikov khlebnikov@yandex-team.ru Reviewed-by: Roman Gushchin guro@fb.com Reviewed-by: Cyrill Gorcunov gorcunov@gmail.com Reviewed-by: Kirill Tkhai ktkhai@virtuozzo.com Acked-by: Michal Hocko mhocko@suse.com Cc: Alexey Dobriyan adobriyan@gmail.com Cc: Al Viro viro@zeniv.linux.org.uk Cc: Matthew Wilcox willy@infradead.org Cc: Michal Koutný mkoutny@suse.com Cc: Oleg Nesterov oleg@redhat.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/proc/task_mmu.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 01d4eb0e6bd1..4d9a8e72d91f 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -828,7 +828,10 @@ static int show_smaps_rollup(struct seq_file *m, void *v)
memset(&mss, 0, sizeof(mss));
- down_read(&mm->mmap_sem); + ret = down_read_killable(&mm->mmap_sem); + if (ret) + goto out_put_mm; + hold_task_mempolicy(priv);
for (vma = priv->mm->mmap; vma; vma = vma->vm_next) { @@ -845,8 +848,9 @@ static int show_smaps_rollup(struct seq_file *m, void *v)
release_task_mempolicy(priv); up_read(&mm->mmap_sem); - mmput(mm);
+out_put_mm: + mmput(mm); out_put_task: put_task_struct(priv->task); priv->task = NULL;
[ Upstream commit ad80b932c57d85fd6377f97f359b025baf179a87 ]
Do not remain stuck forever if something goes wrong. Using a killable lock permits cleanup of stuck tasks and simplifies investigation.
Link: http://lkml.kernel.org/r/156007493638.3335.4872164955523928492.stgit@buzz Signed-off-by: Konstantin Khlebnikov khlebnikov@yandex-team.ru Reviewed-by: Roman Gushchin guro@fb.com Reviewed-by: Cyrill Gorcunov gorcunov@gmail.com Reviewed-by: Kirill Tkhai ktkhai@virtuozzo.com Acked-by: Michal Hocko mhocko@suse.com Cc: Alexey Dobriyan adobriyan@gmail.com Cc: Al Viro viro@zeniv.linux.org.uk Cc: Matthew Wilcox willy@infradead.org Cc: Michal Koutný mkoutny@suse.com Cc: Oleg Nesterov oleg@redhat.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/proc/task_mmu.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 4d9a8e72d91f..1d9c63cd8a3c 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -1543,7 +1543,9 @@ static ssize_t pagemap_read(struct file *file, char __user *buf, /* overflow ? */ if (end < start_vaddr || end > end_vaddr) end = end_vaddr; - down_read(&mm->mmap_sem); + ret = down_read_killable(&mm->mmap_sem); + if (ret) + goto out_free; ret = walk_page_range(start_vaddr, end, &pagemap_walk); up_read(&mm->mmap_sem); start_vaddr = end;
[ Upstream commit c46038017fbdcac627b670c9d4176f1d0c2f5fa3 ]
Do not remain stuck forever if something goes wrong. Using a killable lock permits cleanup of stuck tasks and simplifies investigation.
Replace the only unkillable mmap_sem lock in clear_refs_write().
Link: http://lkml.kernel.org/r/156007493826.3335.5424884725467456239.stgit@buzz Signed-off-by: Konstantin Khlebnikov khlebnikov@yandex-team.ru Reviewed-by: Roman Gushchin guro@fb.com Reviewed-by: Cyrill Gorcunov gorcunov@gmail.com Reviewed-by: Kirill Tkhai ktkhai@virtuozzo.com Acked-by: Michal Hocko mhocko@suse.com Cc: Alexey Dobriyan adobriyan@gmail.com Cc: Al Viro viro@zeniv.linux.org.uk Cc: Matthew Wilcox willy@infradead.org Cc: Michal Koutný mkoutny@suse.com Cc: Oleg Nesterov oleg@redhat.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/proc/task_mmu.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 1d9c63cd8a3c..abcd9513efff 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -1136,7 +1136,10 @@ static ssize_t clear_refs_write(struct file *file, const char __user *buf, goto out_mm; }
- down_read(&mm->mmap_sem); + if (down_read_killable(&mm->mmap_sem)) { + count = -EINTR; + goto out_mm; + } tlb_gather_mmu(&tlb, mm, 0, -1); if (type == CLEAR_REFS_SOFT_DIRTY) { for (vma = mm->mmap; vma; vma = vma->vm_next) {
[ Upstream commit cd9e2bb8271c971d9f37c722be2616c7f8ba0664 ]
Do not remain stuck forever if something goes wrong. Using a killable lock permits cleanup of stuck tasks and simplifies investigation.
It seems ->d_revalidate() could return any error (except ECHILD) to abort validation and pass error as result of lookup sequence.
[akpm@linux-foundation.org: fix proc_map_files_lookup() return value, per Andrei] Link: http://lkml.kernel.org/r/156007493995.3335.9595044802115356911.stgit@buzz Signed-off-by: Konstantin Khlebnikov khlebnikov@yandex-team.ru Reviewed-by: Roman Gushchin guro@fb.com Reviewed-by: Cyrill Gorcunov gorcunov@gmail.com Reviewed-by: Kirill Tkhai ktkhai@virtuozzo.com Acked-by: Michal Hocko mhocko@suse.com Cc: Alexey Dobriyan adobriyan@gmail.com Cc: Al Viro viro@zeniv.linux.org.uk Cc: Matthew Wilcox willy@infradead.org Cc: Michal Koutný mkoutny@suse.com Cc: Oleg Nesterov oleg@redhat.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/proc/base.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-)
diff --git a/fs/proc/base.c b/fs/proc/base.c index 255f6754c70d..03517154fe0f 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -1962,9 +1962,12 @@ static int map_files_d_revalidate(struct dentry *dentry, unsigned int flags) goto out;
if (!dname_to_vma_addr(dentry, &vm_start, &vm_end)) { - down_read(&mm->mmap_sem); - exact_vma_exists = !!find_exact_vma(mm, vm_start, vm_end); - up_read(&mm->mmap_sem); + status = down_read_killable(&mm->mmap_sem); + if (!status) { + exact_vma_exists = !!find_exact_vma(mm, vm_start, + vm_end); + up_read(&mm->mmap_sem); + } }
mmput(mm); @@ -2010,8 +2013,11 @@ static int map_files_get_link(struct dentry *dentry, struct path *path) if (rc) goto out_mmput;
+ rc = down_read_killable(&mm->mmap_sem); + if (rc) + goto out_mmput; + rc = -ENOENT; - down_read(&mm->mmap_sem); vma = find_exact_vma(mm, vm_start, vm_end); if (vma && vma->vm_file) { *path = vma->vm_file->f_path; @@ -2107,7 +2113,11 @@ static struct dentry *proc_map_files_lookup(struct inode *dir, if (!mm) goto out_put_task;
- down_read(&mm->mmap_sem); + result = ERR_PTR(-EINTR); + if (down_read_killable(&mm->mmap_sem)) + goto out_put_mm; + + result = ERR_PTR(-ENOENT); vma = find_exact_vma(mm, vm_start, vm_end); if (!vma) goto out_no_vma; @@ -2118,6 +2128,7 @@ static struct dentry *proc_map_files_lookup(struct inode *dir,
out_no_vma: up_read(&mm->mmap_sem); +out_put_mm: mmput(mm); out_put_task: put_task_struct(task); @@ -2160,7 +2171,12 @@ proc_map_files_readdir(struct file *file, struct dir_context *ctx) mm = get_task_mm(task); if (!mm) goto out_put_task; - down_read(&mm->mmap_sem); + + ret = down_read_killable(&mm->mmap_sem); + if (ret) { + mmput(mm); + goto out_put_task; + }
nr_files = 0;
[ Upstream commit 752c2ea2d8e7c23b0f64e2e7d4337f3604d44c9f ]
The cudbg_collect_mem_region() and cudbg_read_fw_mem() both use several hundred kilobytes of kernel stack space. One gets inlined into the other, which causes the stack usage to be combined beyond the warning limit when building with clang:
drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c:1057:12: error: stack frame size of 1244 bytes in function 'cudbg_collect_mem_region' [-Werror,-Wframe-larger-than=]
Restructuring cudbg_collect_mem_region() lets clang do the same optimization that gcc does and reuse the stack slots as it can see that the large variables are never used together.
A better fix might be to avoid using cudbg_meminfo on the stack altogether, but that requires a larger rewrite.
Fixes: a1c69520f785 ("cxgb4: collect MC memory dump") Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- .../net/ethernet/chelsio/cxgb4/cudbg_lib.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c b/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c index a76529a7662d..c2e92786608b 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c @@ -1054,14 +1054,12 @@ static void cudbg_t4_fwcache(struct cudbg_init *pdbg_init, } }
-static int cudbg_collect_mem_region(struct cudbg_init *pdbg_init, - struct cudbg_buffer *dbg_buff, - struct cudbg_error *cudbg_err, - u8 mem_type) +static unsigned long cudbg_mem_region_size(struct cudbg_init *pdbg_init, + struct cudbg_error *cudbg_err, + u8 mem_type) { struct adapter *padap = pdbg_init->adap; struct cudbg_meminfo mem_info; - unsigned long size; u8 mc_idx; int rc;
@@ -1075,7 +1073,16 @@ static int cudbg_collect_mem_region(struct cudbg_init *pdbg_init, if (rc) return rc;
- size = mem_info.avail[mc_idx].limit - mem_info.avail[mc_idx].base; + return mem_info.avail[mc_idx].limit - mem_info.avail[mc_idx].base; +} + +static int cudbg_collect_mem_region(struct cudbg_init *pdbg_init, + struct cudbg_buffer *dbg_buff, + struct cudbg_error *cudbg_err, + u8 mem_type) +{ + unsigned long size = cudbg_mem_region_size(pdbg_init, cudbg_err, mem_type); + return cudbg_read_fw_mem(pdbg_init, dbg_buff, mem_type, size, cudbg_err); }
[ Upstream commit 8a713e7df3352b8d9392476e9cf29e4e185dac32 ]
Do not remain stuck forever if something goes wrong. Using a killable lock permits cleanup of stuck tasks and simplifies investigation.
This function is also used for /proc/pid/smaps.
Link: http://lkml.kernel.org/r/156007493160.3335.14447544314127417266.stgit@buzz Signed-off-by: Konstantin Khlebnikov khlebnikov@yandex-team.ru Reviewed-by: Roman Gushchin guro@fb.com Reviewed-by: Cyrill Gorcunov gorcunov@gmail.com Reviewed-by: Kirill Tkhai ktkhai@virtuozzo.com Acked-by: Michal Hocko mhocko@suse.com Cc: Alexey Dobriyan adobriyan@gmail.com Cc: Al Viro viro@zeniv.linux.org.uk Cc: Matthew Wilcox willy@infradead.org Cc: Michal Koutný mkoutny@suse.com Cc: Oleg Nesterov oleg@redhat.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/proc/task_mmu.c | 6 +++++- fs/proc/task_nommu.c | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index abcd9513efff..7f84d1477b5b 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -166,7 +166,11 @@ static void *m_start(struct seq_file *m, loff_t *ppos) if (!mm || !mmget_not_zero(mm)) return NULL;
- down_read(&mm->mmap_sem); + if (down_read_killable(&mm->mmap_sem)) { + mmput(mm); + return ERR_PTR(-EINTR); + } + hold_task_mempolicy(priv); priv->tail_vma = get_gate_vma(mm);
diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c index 36bf0f2e102e..7907e6419e57 100644 --- a/fs/proc/task_nommu.c +++ b/fs/proc/task_nommu.c @@ -211,7 +211,11 @@ static void *m_start(struct seq_file *m, loff_t *pos) if (!mm || !mmget_not_zero(mm)) return NULL;
- down_read(&mm->mmap_sem); + if (down_read_killable(&mm->mmap_sem)) { + mmput(mm); + return ERR_PTR(-EINTR); + } + /* start from the Nth VMA */ for (p = rb_first(&mm->mm_rb); p; p = rb_next(p)) if (n-- == 0)
[ Upstream commit 68d41d8c94a31dfb8233ab90b9baf41a2ed2da68 ]
The stats variable nr_unused_locks is incremented every time a new lock class is register and decremented when the lock is first used in __lock_acquire(). And after all, it is shown and checked in lockdep_stats.
However, under configurations that either CONFIG_TRACE_IRQFLAGS or CONFIG_PROVE_LOCKING is not defined:
The commit:
091806515124b20 ("locking/lockdep: Consolidate lock usage bit initialization")
missed marking the LOCK_USED flag at IRQ usage initialization because as mark_usage() is not called. And the commit:
886532aee3cd42d ("locking/lockdep: Move mark_lock() inside CONFIG_TRACE_IRQFLAGS && CONFIG_PROVE_LOCKING")
further made mark_lock() not defined such that the LOCK_USED cannot be marked at all when the lock is first acquired.
As a result, we fix this by not showing and checking the stats under such configurations for lockdep_stats.
Reported-by: Qian Cai cai@lca.pw Signed-off-by: Yuyang Du duyuyang@gmail.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Cc: Andrew Morton akpm@linux-foundation.org Cc: Linus Torvalds torvalds@linux-foundation.org Cc: Paul E. McKenney paulmck@linux.vnet.ibm.com Cc: Peter Zijlstra peterz@infradead.org Cc: Thomas Gleixner tglx@linutronix.de Cc: Will Deacon will.deacon@arm.com Cc: arnd@arndb.de Cc: frederic@kernel.org Link: https://lkml.kernel.org/r/20190709101522.9117-1-duyuyang@gmail.com Signed-off-by: Ingo Molnar mingo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/locking/lockdep_proc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/kernel/locking/lockdep_proc.c b/kernel/locking/lockdep_proc.c index 9c49ec645d8b..65b6a1600c8f 100644 --- a/kernel/locking/lockdep_proc.c +++ b/kernel/locking/lockdep_proc.c @@ -210,6 +210,7 @@ static int lockdep_stats_show(struct seq_file *m, void *v) nr_hardirq_read_safe = 0, nr_hardirq_read_unsafe = 0, sum_forward_deps = 0;
+#ifdef CONFIG_PROVE_LOCKING list_for_each_entry(class, &all_lock_classes, lock_entry) {
if (class->usage_mask == 0) @@ -241,12 +242,12 @@ static int lockdep_stats_show(struct seq_file *m, void *v) if (class->usage_mask & LOCKF_ENABLED_HARDIRQ_READ) nr_hardirq_read_unsafe++;
-#ifdef CONFIG_PROVE_LOCKING sum_forward_deps += lockdep_count_forward_deps(class); -#endif } #ifdef CONFIG_DEBUG_LOCKDEP DEBUG_LOCKS_WARN_ON(debug_atomic_read(nr_unused_locks) != nr_unused); +#endif + #endif seq_printf(m, " lock-classes: %11lu [max: %lu]\n", nr_lock_classes, MAX_LOCKDEP_KEYS);
[ Upstream commit 1e426fe28261b03f297992e89da3320b42816f4e ]
This function is used by ptrace and proc files like /proc/pid/cmdline and /proc/pid/environ.
Access_remote_vm never returns error codes, all errors are ignored and only size of successfully read data is returned. So, if current task was killed we'll simply return 0 (bytes read).
Mmap_sem could be locked for a long time or forever if something goes wrong. Using a killable lock permits cleanup of stuck tasks and simplifies investigation.
Link: http://lkml.kernel.org/r/156007494202.3335.16782303099589302087.stgit@buzz Signed-off-by: Konstantin Khlebnikov khlebnikov@yandex-team.ru Reviewed-by: Michal Koutný mkoutny@suse.com Acked-by: Oleg Nesterov oleg@redhat.com Acked-by: Michal Hocko mhocko@suse.com Cc: Alexey Dobriyan adobriyan@gmail.com Cc: Matthew Wilcox willy@infradead.org Cc: Cyrill Gorcunov gorcunov@gmail.com Cc: Kirill Tkhai ktkhai@virtuozzo.com Cc: Al Viro viro@zeniv.linux.org.uk Cc: Roman Gushchin guro@fb.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 --- mm/memory.c | 4 +++- mm/nommu.c | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/mm/memory.c b/mm/memory.c index ddf20bd0c317..9a4401d21e94 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -4349,7 +4349,9 @@ int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm, void *old_buf = buf; int write = gup_flags & FOLL_WRITE;
- down_read(&mm->mmap_sem); + if (down_read_killable(&mm->mmap_sem)) + return 0; + /* ignore errors, just check how much was successfully transferred */ while (len) { int bytes, ret, offset; diff --git a/mm/nommu.c b/mm/nommu.c index d8c02fbe03b5..b2823519f8cd 100644 --- a/mm/nommu.c +++ b/mm/nommu.c @@ -1792,7 +1792,8 @@ int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm, struct vm_area_struct *vma; int write = gup_flags & FOLL_WRITE;
- down_read(&mm->mmap_sem); + if (down_read_killable(&mm->mmap_sem)) + return 0;
/* the access must start within one of the target process's mappings */ vma = find_vma(mm, addr);
[ Upstream commit eb085574a7526c4375965c5fbf7e5b0c19cdd336 ]
When swapin is performed, after getting the swap entry information from the page table, system will swap in the swap entry, without any lock held to prevent the swap device from being swapoff. This may cause the race like below,
CPU 1 CPU 2 ----- ----- do_swap_page swapin_readahead __read_swap_cache_async swapoff swapcache_prepare p->swap_map = NULL __swap_duplicate p->swap_map[?] /* !!! NULL pointer access */
Because swapoff is usually done when system shutdown only, the race may not hit many people in practice. But it is still a race need to be fixed.
To fix the race, get_swap_device() is added to check whether the specified swap entry is valid in its swap device. If so, it will keep the swap entry valid via preventing the swap device from being swapoff, until put_swap_device() is called.
Because swapoff() is very rare code path, to make the normal path runs as fast as possible, rcu_read_lock/unlock() and synchronize_rcu() instead of reference count is used to implement get/put_swap_device(). >From get_swap_device() to put_swap_device(), RCU reader side is locked, so synchronize_rcu() in swapoff() will wait until put_swap_device() is called.
In addition to swap_map, cluster_info, etc. data structure in the struct swap_info_struct, the swap cache radix tree will be freed after swapoff, so this patch fixes the race between swap cache looking up and swapoff too.
Races between some other swap cache usages and swapoff are fixed too via calling synchronize_rcu() between clearing PageSwapCache() and freeing swap cache data structure.
Another possible method to fix this is to use preempt_off() + stop_machine() to prevent the swap device from being swapoff when its data structure is being accessed. The overhead in hot-path of both methods is similar. The advantages of RCU based method are,
1. stop_machine() may disturb the normal execution code path on other CPUs.
2. File cache uses RCU to protect its radix tree. If the similar mechanism is used for swap cache too, it is easier to share code between them.
3. RCU is used to protect swap cache in total_swapcache_pages() and exit_swap_address_space() already. The two mechanisms can be merged to simplify the logic.
Link: http://lkml.kernel.org/r/20190522015423.14418-1-ying.huang@intel.com Fixes: 235b62176712 ("mm/swap: add cluster lock") Signed-off-by: "Huang, Ying" ying.huang@intel.com Reviewed-by: Andrea Parri andrea.parri@amarulasolutions.com Not-nacked-by: Hugh Dickins hughd@google.com Cc: Andrea Arcangeli aarcange@redhat.com Cc: Paul E. McKenney paulmck@linux.vnet.ibm.com Cc: Daniel Jordan daniel.m.jordan@oracle.com Cc: Michal Hocko mhocko@suse.com Cc: Minchan Kim minchan@kernel.org Cc: Johannes Weiner hannes@cmpxchg.org Cc: Tim Chen tim.c.chen@linux.intel.com Cc: Mel Gorman mgorman@techsingularity.net Cc: Jérôme Glisse jglisse@redhat.com Cc: Yang Shi yang.shi@linux.alibaba.com Cc: David Rientjes rientjes@google.com Cc: Rik van Riel riel@redhat.com Cc: Jan Kara jack@suse.cz Cc: Dave Jiang dave.jiang@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 --- include/linux/swap.h | 13 +++- mm/memory.c | 2 +- mm/swap_state.c | 16 ++++- mm/swapfile.c | 154 ++++++++++++++++++++++++++++++++++--------- 4 files changed, 146 insertions(+), 39 deletions(-)
diff --git a/include/linux/swap.h b/include/linux/swap.h index 4bfb5c4ac108..6358a6185634 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -175,8 +175,9 @@ enum { SWP_PAGE_DISCARD = (1 << 10), /* freed swap page-cluster discards */ SWP_STABLE_WRITES = (1 << 11), /* no overwrite PG_writeback pages */ SWP_SYNCHRONOUS_IO = (1 << 12), /* synchronous IO is efficient */ + SWP_VALID = (1 << 13), /* swap is valid to be operated on? */ /* add others here before... */ - SWP_SCANNING = (1 << 13), /* refcount in scan_swap_map */ + SWP_SCANNING = (1 << 14), /* refcount in scan_swap_map */ };
#define SWAP_CLUSTER_MAX 32UL @@ -460,7 +461,7 @@ extern unsigned int count_swap_pages(int, int); extern sector_t map_swap_page(struct page *, struct block_device **); extern sector_t swapdev_block(int, pgoff_t); extern int page_swapcount(struct page *); -extern int __swap_count(struct swap_info_struct *si, swp_entry_t entry); +extern int __swap_count(swp_entry_t entry); extern int __swp_swapcount(swp_entry_t entry); extern int swp_swapcount(swp_entry_t entry); extern struct swap_info_struct *page_swap_info(struct page *); @@ -470,6 +471,12 @@ extern int try_to_free_swap(struct page *); struct backing_dev_info; extern int init_swap_address_space(unsigned int type, unsigned long nr_pages); extern void exit_swap_address_space(unsigned int type); +extern struct swap_info_struct *get_swap_device(swp_entry_t entry); + +static inline void put_swap_device(struct swap_info_struct *si) +{ + rcu_read_unlock(); +}
#else /* CONFIG_SWAP */
@@ -576,7 +583,7 @@ static inline int page_swapcount(struct page *page) return 0; }
-static inline int __swap_count(struct swap_info_struct *si, swp_entry_t entry) +static inline int __swap_count(swp_entry_t entry) { return 0; } diff --git a/mm/memory.c b/mm/memory.c index 9a4401d21e94..b0efc69b2634 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -2807,7 +2807,7 @@ vm_fault_t do_swap_page(struct vm_fault *vmf) struct swap_info_struct *si = swp_swap_info(entry);
if (si->flags & SWP_SYNCHRONOUS_IO && - __swap_count(si, entry) == 1) { + __swap_count(entry) == 1) { /* skip swapcache */ page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, vmf->address); diff --git a/mm/swap_state.c b/mm/swap_state.c index 85245fdec8d9..61453f1faf72 100644 --- a/mm/swap_state.c +++ b/mm/swap_state.c @@ -310,8 +310,13 @@ struct page *lookup_swap_cache(swp_entry_t entry, struct vm_area_struct *vma, unsigned long addr) { struct page *page; + struct swap_info_struct *si;
+ si = get_swap_device(entry); + if (!si) + return NULL; page = find_get_page(swap_address_space(entry), swp_offset(entry)); + put_swap_device(si);
INC_CACHE_INFO(find_total); if (page) { @@ -354,8 +359,8 @@ struct page *__read_swap_cache_async(swp_entry_t entry, gfp_t gfp_mask, struct vm_area_struct *vma, unsigned long addr, bool *new_page_allocated) { - struct page *found_page, *new_page = NULL; - struct address_space *swapper_space = swap_address_space(entry); + struct page *found_page = NULL, *new_page = NULL; + struct swap_info_struct *si; int err; *new_page_allocated = false;
@@ -365,7 +370,12 @@ struct page *__read_swap_cache_async(swp_entry_t entry, gfp_t gfp_mask, * called after lookup_swap_cache() failed, re-calling * that would confuse statistics. */ - found_page = find_get_page(swapper_space, swp_offset(entry)); + si = get_swap_device(entry); + if (!si) + break; + found_page = find_get_page(swap_address_space(entry), + swp_offset(entry)); + put_swap_device(si); if (found_page) break;
diff --git a/mm/swapfile.c b/mm/swapfile.c index 596ac98051c5..dbab16ddefa6 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -1079,12 +1079,11 @@ swp_entry_t get_swap_page_of_type(int type) static struct swap_info_struct *__swap_info_get(swp_entry_t entry) { struct swap_info_struct *p; - unsigned long offset, type; + unsigned long offset;
if (!entry.val) goto out; - type = swp_type(entry); - p = swap_type_to_swap_info(type); + p = swp_swap_info(entry); if (!p) goto bad_nofile; if (!(p->flags & SWP_USED)) @@ -1187,6 +1186,69 @@ static unsigned char __swap_entry_free_locked(struct swap_info_struct *p, return usage; }
+/* + * Check whether swap entry is valid in the swap device. If so, + * return pointer to swap_info_struct, and keep the swap entry valid + * via preventing the swap device from being swapoff, until + * put_swap_device() is called. Otherwise return NULL. + * + * The entirety of the RCU read critical section must come before the + * return from or after the call to synchronize_rcu() in + * enable_swap_info() or swapoff(). So if "si->flags & SWP_VALID" is + * true, the si->map, si->cluster_info, etc. must be valid in the + * critical section. + * + * Notice that swapoff or swapoff+swapon can still happen before the + * rcu_read_lock() in get_swap_device() or after the rcu_read_unlock() + * in put_swap_device() if there isn't any other way to prevent + * swapoff, such as page lock, page table lock, etc. The caller must + * be prepared for that. For example, the following situation is + * possible. + * + * CPU1 CPU2 + * do_swap_page() + * ... swapoff+swapon + * __read_swap_cache_async() + * swapcache_prepare() + * __swap_duplicate() + * // check swap_map + * // verify PTE not changed + * + * In __swap_duplicate(), the swap_map need to be checked before + * changing partly because the specified swap entry may be for another + * swap device which has been swapoff. And in do_swap_page(), after + * the page is read from the swap device, the PTE is verified not + * changed with the page table locked to check whether the swap device + * has been swapoff or swapoff+swapon. + */ +struct swap_info_struct *get_swap_device(swp_entry_t entry) +{ + struct swap_info_struct *si; + unsigned long offset; + + if (!entry.val) + goto out; + si = swp_swap_info(entry); + if (!si) + goto bad_nofile; + + rcu_read_lock(); + if (!(si->flags & SWP_VALID)) + goto unlock_out; + offset = swp_offset(entry); + if (offset >= si->max) + goto unlock_out; + + return si; +bad_nofile: + pr_err("%s: %s%08lx\n", __func__, Bad_file, entry.val); +out: + return NULL; +unlock_out: + rcu_read_unlock(); + return NULL; +} + static unsigned char __swap_entry_free(struct swap_info_struct *p, swp_entry_t entry, unsigned char usage) { @@ -1358,11 +1420,18 @@ int page_swapcount(struct page *page) return count; }
-int __swap_count(struct swap_info_struct *si, swp_entry_t entry) +int __swap_count(swp_entry_t entry) { + struct swap_info_struct *si; pgoff_t offset = swp_offset(entry); + int count = 0;
- return swap_count(si->swap_map[offset]); + si = get_swap_device(entry); + if (si) { + count = swap_count(si->swap_map[offset]); + put_swap_device(si); + } + return count; }
static int swap_swapcount(struct swap_info_struct *si, swp_entry_t entry) @@ -1387,9 +1456,11 @@ int __swp_swapcount(swp_entry_t entry) int count = 0; struct swap_info_struct *si;
- si = __swap_info_get(entry); - if (si) + si = get_swap_device(entry); + if (si) { count = swap_swapcount(si, entry); + put_swap_device(si); + } return count; }
@@ -2335,9 +2406,9 @@ static int swap_node(struct swap_info_struct *p) return bdev ? bdev->bd_disk->node_id : NUMA_NO_NODE; }
-static void _enable_swap_info(struct swap_info_struct *p, int prio, - unsigned char *swap_map, - struct swap_cluster_info *cluster_info) +static void setup_swap_info(struct swap_info_struct *p, int prio, + unsigned char *swap_map, + struct swap_cluster_info *cluster_info) { int i;
@@ -2362,7 +2433,11 @@ static void _enable_swap_info(struct swap_info_struct *p, int prio, } p->swap_map = swap_map; p->cluster_info = cluster_info; - p->flags |= SWP_WRITEOK; +} + +static void _enable_swap_info(struct swap_info_struct *p) +{ + p->flags |= SWP_WRITEOK | SWP_VALID; atomic_long_add(p->pages, &nr_swap_pages); total_swap_pages += p->pages;
@@ -2389,7 +2464,17 @@ static void enable_swap_info(struct swap_info_struct *p, int prio, frontswap_init(p->type, frontswap_map); spin_lock(&swap_lock); spin_lock(&p->lock); - _enable_swap_info(p, prio, swap_map, cluster_info); + setup_swap_info(p, prio, swap_map, cluster_info); + spin_unlock(&p->lock); + spin_unlock(&swap_lock); + /* + * Guarantee swap_map, cluster_info, etc. fields are valid + * between get/put_swap_device() if SWP_VALID bit is set + */ + synchronize_rcu(); + spin_lock(&swap_lock); + spin_lock(&p->lock); + _enable_swap_info(p); spin_unlock(&p->lock); spin_unlock(&swap_lock); } @@ -2398,7 +2483,8 @@ static void reinsert_swap_info(struct swap_info_struct *p) { spin_lock(&swap_lock); spin_lock(&p->lock); - _enable_swap_info(p, p->prio, p->swap_map, p->cluster_info); + setup_swap_info(p, p->prio, p->swap_map, p->cluster_info); + _enable_swap_info(p); spin_unlock(&p->lock); spin_unlock(&swap_lock); } @@ -2501,6 +2587,17 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
reenable_swap_slots_cache_unlock();
+ spin_lock(&swap_lock); + spin_lock(&p->lock); + p->flags &= ~SWP_VALID; /* mark swap device as invalid */ + spin_unlock(&p->lock); + spin_unlock(&swap_lock); + /* + * wait for swap operations protected by get/put_swap_device() + * to complete + */ + synchronize_rcu(); + flush_work(&p->discard_work);
destroy_swap_extents(p); @@ -3265,17 +3362,11 @@ static int __swap_duplicate(swp_entry_t entry, unsigned char usage) unsigned char has_cache; int err = -EINVAL;
- if (non_swap_entry(entry)) - goto out; - - p = swp_swap_info(entry); + p = get_swap_device(entry); if (!p) - goto bad_file; - - offset = swp_offset(entry); - if (unlikely(offset >= p->max)) goto out;
+ offset = swp_offset(entry); ci = lock_cluster_or_swap_info(p, offset);
count = p->swap_map[offset]; @@ -3321,11 +3412,9 @@ static int __swap_duplicate(swp_entry_t entry, unsigned char usage) unlock_out: unlock_cluster_or_swap_info(p, ci); out: + if (p) + put_swap_device(p); return err; - -bad_file: - pr_err("swap_dup: %s%08lx\n", Bad_file, entry.val); - goto out; }
/* @@ -3417,6 +3506,7 @@ int add_swap_count_continuation(swp_entry_t entry, gfp_t gfp_mask) struct page *list_page; pgoff_t offset; unsigned char count; + int ret = 0;
/* * When debugging, it's easier to use __GFP_ZERO here; but it's better @@ -3424,15 +3514,15 @@ int add_swap_count_continuation(swp_entry_t entry, gfp_t gfp_mask) */ page = alloc_page(gfp_mask | __GFP_HIGHMEM);
- si = swap_info_get(entry); + si = get_swap_device(entry); if (!si) { /* * An acceptable race has occurred since the failing - * __swap_duplicate(): the swap entry has been freed, - * perhaps even the whole swap_map cleared for swapoff. + * __swap_duplicate(): the swap device may be swapoff */ goto outer; } + spin_lock(&si->lock);
offset = swp_offset(entry);
@@ -3450,9 +3540,8 @@ int add_swap_count_continuation(swp_entry_t entry, gfp_t gfp_mask) }
if (!page) { - unlock_cluster(ci); - spin_unlock(&si->lock); - return -ENOMEM; + ret = -ENOMEM; + goto out; }
/* @@ -3504,10 +3593,11 @@ int add_swap_count_continuation(swp_entry_t entry, gfp_t gfp_mask) out: unlock_cluster(ci); spin_unlock(&si->lock); + put_swap_device(si); outer: if (page) __free_page(page); - return 0; + return ret; }
/*
[ Upstream commit 68037aa78208f34bda4e5cd76c357f718b838cbb ]
The usage is now hidden in an #ifdef, so we need to move the variable itself in there as well to avoid this warning:
kernel/locking/lockdep_proc.c:203:21: error: unused variable 'class' [-Werror,-Wunused-variable]
Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Cc: Andrew Morton akpm@linux-foundation.org Cc: Bart Van Assche bvanassche@acm.org Cc: Linus Torvalds torvalds@linux-foundation.org Cc: Paul E. McKenney paulmck@linux.vnet.ibm.com Cc: Peter Zijlstra peterz@infradead.org Cc: Qian Cai cai@lca.pw Cc: Thomas Gleixner tglx@linutronix.de Cc: Waiman Long longman@redhat.com Cc: Will Deacon will.deacon@arm.com Cc: Will Deacon will@kernel.org Cc: Yuyang Du duyuyang@gmail.com Cc: frederic@kernel.org Fixes: 68d41d8c94a3 ("locking/lockdep: Fix lock used or unused stats error") Link: https://lkml.kernel.org/r/20190715092809.736834-1-arnd@arndb.de Signed-off-by: Ingo Molnar mingo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/locking/lockdep_proc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/kernel/locking/lockdep_proc.c b/kernel/locking/lockdep_proc.c index 65b6a1600c8f..bda006f8a88b 100644 --- a/kernel/locking/lockdep_proc.c +++ b/kernel/locking/lockdep_proc.c @@ -200,7 +200,6 @@ static void lockdep_stats_debug_show(struct seq_file *m)
static int lockdep_stats_show(struct seq_file *m, void *v) { - struct lock_class *class; unsigned long nr_unused = 0, nr_uncategorized = 0, nr_irq_safe = 0, nr_irq_unsafe = 0, nr_softirq_safe = 0, nr_softirq_unsafe = 0, @@ -211,6 +210,8 @@ static int lockdep_stats_show(struct seq_file *m, void *v) sum_forward_deps = 0;
#ifdef CONFIG_PROVE_LOCKING + struct lock_class *class; + list_for_each_entry(class, &all_lock_classes, lock_entry) {
if (class->usage_mask == 0)
From: Mathias Nyman mathias.nyman@linux.intel.com
commit d39b5bad8658d6d94cb2d98a44a7e159db4f5030 upstream.
A second regression was found in the immediate data transfer (IDT) support which was added to 5.2 kernel
IDT is used to transfer small amounts of data (up to 8 bytes) in the field normally used for data dma address, thus avoiding dma mapping.
If the data was not already dma mapped, then IDT support assumed data was in urb->transfer_buffer, and did not take into accound that even small amounts of data (8 bytes) can be in a scatterlist instead.
This caused a NULL pointer dereference when sg_dma_len() was used with non-dma mapped data.
Solve this by not using IDT if scatter gather buffer list is used.
Fixes: 33e39350ebd2 ("usb: xhci: add Immediate Data Transfer support") Cc: stable@vger.kernel.org # v5.2 Reported-by: Maik Stohn maik.stohn@seal-one.com Tested-by: Maik Stohn maik.stohn@seal-one.com CC: Nicolas Saenz Julienne nsaenzjulienne@suse.de Signed-off-by: Mathias Nyman mathias.nyman@linux.intel.com Link: https://lore.kernel.org/r/1564044861-1445-1-git-send-email-mathias.nyman@lin... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/host/xhci.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -2170,7 +2170,8 @@ static inline bool xhci_urb_suitable_for if (!usb_endpoint_xfer_isoc(&urb->ep->desc) && usb_urb_dir_out(urb) && usb_endpoint_maxp(&urb->ep->desc) >= TRB_IDT_MAX_SIZE && urb->transfer_buffer_length <= TRB_IDT_MAX_SIZE && - !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) + !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP) && + !urb->num_sgs) return true;
return false;
From: Yoshihiro Shimoda yoshihiro.shimoda.uh@renesas.com
commit d74ffae8b8dd17eaa8b82fc163e6aa2076dc8fb1 upstream.
This patch fixes an issue that the following error happens on swiotlb environment:
xhci-hcd ee000000.usb: swiotlb buffer is full (sz: 524288 bytes), total 32768 (slots), used 1338 (slots)
On the kernel v5.1, block settings of a usb-storage with SuperSpeed were the following so that the block layer will allocate buffers up to 64 KiB, and then the issue didn't happen.
max_segment_size = 65536 max_hw_sectors_kb = 1024
After the commit 09324d32d2a0 ("block: force an unlimited segment size on queues with a virt boundary") is applied, the block settings are the following. So, the block layer will allocate buffers up to 1024 KiB, and then the issue happens:
max_segment_size = 4294967295 max_hw_sectors_kb = 1024
To fix the issue, the usb-storage driver checks the maximum size of a mapping for the device and then adjusts the max_hw_sectors_kb if required. After this patch is applied, the block settings will be the following, and then the issue doesn't happen.
max_segment_size = 4294967295 max_hw_sectors_kb = 256
Fixes: 09324d32d2a0 ("block: force an unlimited segment size on queues with a virt boundary") Cc: stable stable@vger.kernel.org Signed-off-by: Yoshihiro Shimoda yoshihiro.shimoda.uh@renesas.com Acked-by: Alan Stern stern@rowland.harvard.edu Reviewed-by: Christoph Hellwig hch@lst.de Link: https://lore.kernel.org/r/1563793105-20597-1-git-send-email-yoshihiro.shimod... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/storage/scsiglue.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
--- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c @@ -28,6 +28,8 @@ * status of a command. */
+#include <linux/blkdev.h> +#include <linux/dma-mapping.h> #include <linux/module.h> #include <linux/mutex.h>
@@ -99,6 +101,7 @@ static int slave_alloc (struct scsi_devi static int slave_configure(struct scsi_device *sdev) { struct us_data *us = host_to_us(sdev->host); + struct device *dev = us->pusb_dev->bus->sysdev;
/* * Many devices have trouble transferring more than 32KB at a time, @@ -129,6 +132,14 @@ static int slave_configure(struct scsi_d }
/* + * The max_hw_sectors should be up to maximum size of a mapping for + * the device. Otherwise, a DMA API might fail on swiotlb environment. + */ + blk_queue_max_hw_sectors(sdev->request_queue, + min_t(size_t, queue_max_hw_sectors(sdev->request_queue), + dma_max_mapping_size(dev) >> SECTOR_SHIFT)); + + /* * Some USB host controllers can't do DMA; they have to use PIO. * They indicate this by setting their dma_mask to NULL. For * such controllers we need to make sure the block layer sets
From: Phong Tran tranmanphong@gmail.com
commit f90bf1ece48a736097ea224430578fe586a9544c upstream.
syzboot reported that https://syzkaller.appspot.com/bug?extid=fd2bd7df88c606eea4ef
There is not consitency parameter in cluste_id_get/put calling. In case of getting the id with result is failure, the wusbhc->cluster_id will not be updated and this can not be used for wusb_cluster_id_put().
Tested report https://groups.google.com/d/msg/syzkaller-bugs/0znZopp3-9k/oxOrhLkLEgAJ
Reproduce and gdb got the details:
139 addr = wusb_cluster_id_get(); (gdb) n 140 if (addr == 0) (gdb) print addr $1 = 254 '\376' (gdb) n 142 result = __hwahc_set_cluster_id(hwahc, addr); (gdb) print result $2 = -71 (gdb) break wusb_cluster_id_put Breakpoint 3 at 0xffffffff836e3f20: file drivers/usb/wusbcore/wusbhc.c, line 384. (gdb) s Thread 2 hit Breakpoint 3, wusb_cluster_id_put (id=0 '\000') at drivers/usb/wusbcore/wusbhc.c:384 384 id = 0xff - id; (gdb) n 385 BUG_ON(id >= CLUSTER_IDS); (gdb) print id $3 = 255 '\377'
Reported-by: syzbot+fd2bd7df88c606eea4ef@syzkaller.appspotmail.com Signed-off-by: Phong Tran tranmanphong@gmail.com Cc: stable stable@vger.kernel.org Link: https://lore.kernel.org/r/20190724020601.15257-1-tranmanphong@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/host/hwa-hc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/usb/host/hwa-hc.c +++ b/drivers/usb/host/hwa-hc.c @@ -159,7 +159,7 @@ out: return result;
error_set_cluster_id: - wusb_cluster_id_put(wusbhc->cluster_id); + wusb_cluster_id_put(addr); error_cluster_id_get: goto out;
From: Ryan Kennedy ryan5544@gmail.com
commit f3dccdaade4118070a3a47bef6b18321431f9ac6 upstream.
The AMD PLL USB quirk is incorrectly enabled on newer Ryzen chipsets. The logic in usb_amd_find_chipset_info currently checks for unaffected chipsets rather than affected ones. This broke once a new chipset was added in e788787ef. It makes more sense to reverse the logic so it won't need to be updated as new chipsets are added. Note that the core of the workaround in usb_amd_quirk_pll does correctly check the chipset.
Signed-off-by: Ryan Kennedy ryan5544@gmail.com Fixes: e788787ef4f9 ("usb:xhci:Add quirk for Certain failing HP keyboard on reset after resume") Cc: stable stable@vger.kernel.org Acked-by: Alan Stern stern@rowland.harvard.edu Link: https://lore.kernel.org/r/20190704153529.9429-2-ryan5544@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/host/pci-quirks.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-)
--- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c @@ -205,7 +205,7 @@ int usb_amd_find_chipset_info(void) { unsigned long flags; struct amd_chipset_info info; - int ret; + int need_pll_quirk = 0;
spin_lock_irqsave(&amd_lock, flags);
@@ -219,21 +219,28 @@ int usb_amd_find_chipset_info(void) spin_unlock_irqrestore(&amd_lock, flags);
if (!amd_chipset_sb_type_init(&info)) { - ret = 0; goto commit; }
- /* Below chipset generations needn't enable AMD PLL quirk */ - if (info.sb_type.gen == AMD_CHIPSET_UNKNOWN || - info.sb_type.gen == AMD_CHIPSET_SB600 || - info.sb_type.gen == AMD_CHIPSET_YANGTZE || - (info.sb_type.gen == AMD_CHIPSET_SB700 && - info.sb_type.rev > 0x3b)) { + switch (info.sb_type.gen) { + case AMD_CHIPSET_SB700: + need_pll_quirk = info.sb_type.rev <= 0x3B; + break; + case AMD_CHIPSET_SB800: + case AMD_CHIPSET_HUDSON2: + case AMD_CHIPSET_BOLTON: + need_pll_quirk = 1; + break; + default: + need_pll_quirk = 0; + break; + } + + if (!need_pll_quirk) { if (info.smbus_dev) { pci_dev_put(info.smbus_dev); info.smbus_dev = NULL; } - ret = 0; goto commit; }
@@ -252,7 +259,7 @@ int usb_amd_find_chipset_info(void) } }
- ret = info.probe_result = 1; + need_pll_quirk = info.probe_result = 1; printk(KERN_DEBUG "QUIRK: Enable AMD PLL fix\n");
commit: @@ -263,7 +270,7 @@ commit:
/* Mark that we where here */ amd_chipset.probe_count++; - ret = amd_chipset.probe_result; + need_pll_quirk = amd_chipset.probe_result;
spin_unlock_irqrestore(&amd_lock, flags);
@@ -277,7 +284,7 @@ commit: spin_unlock_irqrestore(&amd_lock, flags); }
- return ret; + return need_pll_quirk; } EXPORT_SYMBOL_GPL(usb_amd_find_chipset_info);
From: Lucas Stach l.stach@pengutronix.de
commit bafe64e5f0edaa689e72e2f8dc236641da37fed4 upstream.
This reverts commit 3342ce35a1, as there is no need for this separate property and it breaks compatibility with existing devicetree files (arch/arm64/boot/dts/freescale/imx8mq.dtsi).
CC: stable@vger.kernel.org #5.2 Fixes: 3342ce35a183 ("usb: usb251xb: Add US lanes inversion dts-bindings") Signed-off-by: Lucas Stach l.stach@pengutronix.de Link: https://lore.kernel.org/r/20190719084407.28041-1-l.stach@pengutronix.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- Documentation/devicetree/bindings/usb/usb251xb.txt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
--- a/Documentation/devicetree/bindings/usb/usb251xb.txt +++ b/Documentation/devicetree/bindings/usb/usb251xb.txt @@ -64,10 +64,8 @@ Optional properties : - power-on-time-ms : Specifies the time it takes from the time the host initiates the power-on sequence to a port until the port has adequate power. The value is given in ms in a 0 - 510 range (default is 100ms). - - swap-dx-lanes : Specifies the downstream ports which will swap the - differential-pair (D+/D-), default is not-swapped. - - swap-us-lanes : Selects the upstream port differential-pair (D+/D-) - swapping (boolean, default is not-swapped) + - swap-dx-lanes : Specifies the ports which will swap the differential-pair + (D+/D-), default is not-swapped.
Examples: usb2512b@2c {
From: Lucas Stach l.stach@pengutronix.de
commit 79f6fafad4e2a874015cb67d735f9f87f1834367 upstream.
This property isn't needed and not yet used anywhere. The swap-dx-lanes property is perfectly fine for doing the swap on the upstream port lanes.
CC: stable@vger.kernel.org #5.2 Signed-off-by: Lucas Stach l.stach@pengutronix.de Link: https://lore.kernel.org/r/20190719084407.28041-2-l.stach@pengutronix.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/misc/usb251xb.c | 2 -- 1 file changed, 2 deletions(-)
--- a/drivers/usb/misc/usb251xb.c +++ b/drivers/usb/misc/usb251xb.c @@ -574,8 +574,6 @@ static int usb251xb_get_ofdata(struct us hub->port_swap = USB251XB_DEF_PORT_SWAP; usb251xb_get_ports_field(hub, "swap-dx-lanes", data->port_cnt, &hub->port_swap); - if (of_get_property(np, "swap-us-lanes", NULL)) - hub->port_swap |= BIT(0);
/* The following parameters are currently not exposed to devicetree, but * may be as soon as needed.
From: Lucas Stach l.stach@pengutronix.de
commit 4849ee6129702dcb05d36f9c7c61b4661fcd751f upstream.
This is a partial revert of 73d31def1aab "usb: usb251xb: Create a ports field collector method", which broke a existing devicetree (arch/arm64/boot/dts/freescale/imx8mq.dtsi).
There is no reason why the swap-dx-lanes property should not apply to the upstream port. The reason given in the breaking commit was that it's inconsitent with respect to other port properties, but in fact it is not. All other properties which only apply to the downstream ports explicitly reject port 0, so there is pretty strong precedence that the driver referred to the upstream port as port 0. So there is no inconsistency in this property at all, other than the swapping being also applicable to the upstream port.
CC: stable@vger.kernel.org #5.2 Signed-off-by: Lucas Stach l.stach@pengutronix.de Link: https://lore.kernel.org/r/20190719084407.28041-3-l.stach@pengutronix.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/usb/misc/usb251xb.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
--- a/drivers/usb/misc/usb251xb.c +++ b/drivers/usb/misc/usb251xb.c @@ -375,7 +375,8 @@ out_err:
#ifdef CONFIG_OF static void usb251xb_get_ports_field(struct usb251xb *hub, - const char *prop_name, u8 port_cnt, u8 *fld) + const char *prop_name, u8 port_cnt, + bool ds_only, u8 *fld) { struct device *dev = hub->dev; struct property *prop; @@ -383,7 +384,7 @@ static void usb251xb_get_ports_field(str u32 port;
of_property_for_each_u32(dev->of_node, prop_name, prop, p, port) { - if ((port >= 1) && (port <= port_cnt)) + if ((port >= ds_only ? 1 : 0) && (port <= port_cnt)) *fld |= BIT(port); else dev_warn(dev, "port %u doesn't exist\n", port); @@ -501,15 +502,15 @@ static int usb251xb_get_ofdata(struct us
hub->non_rem_dev = USB251XB_DEF_NON_REMOVABLE_DEVICES; usb251xb_get_ports_field(hub, "non-removable-ports", data->port_cnt, - &hub->non_rem_dev); + true, &hub->non_rem_dev);
hub->port_disable_sp = USB251XB_DEF_PORT_DISABLE_SELF; usb251xb_get_ports_field(hub, "sp-disabled-ports", data->port_cnt, - &hub->port_disable_sp); + true, &hub->port_disable_sp);
hub->port_disable_bp = USB251XB_DEF_PORT_DISABLE_BUS; usb251xb_get_ports_field(hub, "bp-disabled-ports", data->port_cnt, - &hub->port_disable_bp); + true, &hub->port_disable_bp);
hub->max_power_sp = USB251XB_DEF_MAX_POWER_SELF; if (!of_property_read_u32(np, "sp-max-total-current-microamp", @@ -573,7 +574,7 @@ static int usb251xb_get_ofdata(struct us */ hub->port_swap = USB251XB_DEF_PORT_SWAP; usb251xb_get_ports_field(hub, "swap-dx-lanes", data->port_cnt, - &hub->port_swap); + false, &hub->port_swap);
/* The following parameters are currently not exposed to devicetree, but * may be as soon as needed.
From: Wanpeng Li wanpengli@tencent.com
commit e751732486eb3f159089a64d1901992b1357e7cc upstream.
The idea before commit 240c35a37 (which has just been reverted) was that we have the following FPU states:
userspace (QEMU) guest --------------------------------------------------------------------------- processor vcpu->arch.guest_fpu
KVM_RUN: kvm_load_guest_fpu
vcpu->arch.user_fpu processor
preempt out
vcpu->arch.user_fpu current->thread.fpu
preempt in
vcpu->arch.user_fpu processor
back to userspace kvm_put_guest_fpu
processor vcpu->arch.guest_fpu ---------------------------------------------------------------------------
With the new lazy model we want to get the state back to the processor when schedule in from current->thread.fpu.
Reported-by: Thomas Lambertz mail@thomaslambertz.de Reported-by: anthony antdev66@gmail.com Tested-by: anthony antdev66@gmail.com Cc: Paolo Bonzini pbonzini@redhat.com Cc: Radim Krčmář rkrcmar@redhat.com Cc: Thomas Lambertz mail@thomaslambertz.de Cc: anthony antdev66@gmail.com Cc: stable@vger.kernel.org Fixes: 5f409e20b (x86/fpu: Defer FPU state load until return to userspace) Signed-off-by: Wanpeng Li wanpengli@tencent.com [Add a comment in front of the warning. - Paolo] Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/x86/kvm/x86.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
--- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3264,6 +3264,10 @@ void kvm_arch_vcpu_load(struct kvm_vcpu
kvm_x86_ops->vcpu_load(vcpu, cpu);
+ fpregs_assert_state_consistent(); + if (test_thread_flag(TIF_NEED_FPU_LOAD)) + switch_fpu_return(); + /* Apply any externally detected TSC adjustments (due to suspend) */ if (unlikely(vcpu->arch.tsc_offset_adjustment)) { adjust_tsc_offset_host(vcpu, vcpu->arch.tsc_offset_adjustment); @@ -7955,9 +7959,8 @@ static int vcpu_enter_guest(struct kvm_v wait_lapic_expire(vcpu); guest_enter_irqoff();
- fpregs_assert_state_consistent(); - if (test_thread_flag(TIF_NEED_FPU_LOAD)) - switch_fpu_return(); + /* The preempt notifier should have taken care of the FPU already. */ + WARN_ON_ONCE(test_thread_flag(TIF_NEED_FPU_LOAD));
if (unlikely(vcpu->arch.switch_db_regs)) { set_debugreg(0, 7);
From: Suraj Jitindar Singh sjitindarsingh@gmail.com
commit 63279eeb7f93abb1692573c26f1e038e1a87358b upstream.
The performance monitoring unit (PMU) registers are saved on guest exit when the guest has set the pmcregs_in_use flag in its lppaca, if it exists, or unconditionally if it doesn't. If a nested guest is being run then the hypervisor doesn't, and in most cases can't, know if the PMU registers are in use since it doesn't know the location of the lppaca for the nested guest, although it may have one for its immediate guest. This results in the values of these registers being lost across nested guest entry and exit in the case where the nested guest was making use of the performance monitoring facility while it's nested guest hypervisor wasn't.
Further more the hypervisor could interrupt a guest hypervisor between when it has loaded up the PMU registers and it calling H_ENTER_NESTED or between returning from the nested guest to the guest hypervisor and the guest hypervisor reading the PMU registers, in kvmhv_p9_guest_entry(). This means that it isn't sufficient to just save the PMU registers when entering or exiting a nested guest, but that it is necessary to always save the PMU registers whenever a guest is capable of running nested guests to ensure the register values aren't lost in the context switch.
Ensure the PMU register values are preserved by always saving their value into the vcpu struct when a guest is capable of running nested guests.
This should have minimal performance impact however any impact can be avoided by booting a guest with "-machine pseries,cap-nested-hv=false" on the qemu commandline.
Fixes: 95a6432ce903 ("KVM: PPC: Book3S HV: Streamlined guest entry/exit path on P9 for radix guests") Cc: stable@vger.kernel.org # v4.20+ Signed-off-by: Suraj Jitindar Singh sjitindarsingh@gmail.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20190703012022.15644-1-sjitindarsingh@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/powerpc/kvm/book3s_hv.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -3654,6 +3654,8 @@ int kvmhv_p9_guest_entry(struct kvm_vcpu vcpu->arch.vpa.dirty = 1; save_pmu = lp->pmcregs_in_use; } + /* Must save pmu if this guest is capable of running nested guests */ + save_pmu |= nesting_enabled(vcpu->kvm);
kvmhv_save_guest_pmu(vcpu, save_pmu);
From: Suraj Jitindar Singh sjitindarsingh@gmail.com
commit c8b4083db915dfe5a3b4a755ad2317e0509b43f1 upstream.
The Performance Stop Status and Control Register (PSSCR) is used to control the power saving facilities of the processor. This register has various fields, some of which can be modified only in hypervisor state, and others which can be modified in both hypervisor and privileged non-hypervisor state. The bits which can be modified in privileged non-hypervisor state are referred to as guest visible.
Currently the L0 hypervisor saves and restores both it's own host value as well as the guest value of the PSSCR when context switching between the hypervisor and guest. However a nested hypervisor running it's own nested guests (as indicated by kvmhv_on_pseries()) doesn't context switch the PSSCR register. That means if a nested (L2) guest modifies the PSSCR then the L1 guest hypervisor will run with that modified value, and if the L1 guest hypervisor modifies the PSSCR and then goes to run the nested (L2) guest again then the L2 PSSCR value will be lost.
Fix this by having the (L1) nested hypervisor save and restore both its host and the guest PSSCR value when entering and exiting a nested (L2) guest. Note that only the guest visible parts of the PSSCR are context switched since this is all the L1 nested hypervisor can access, this is fine however as these are the only fields the L0 hypervisor provides guest control of anyway and so all other fields are ignored.
This could also have been implemented by adding the PSSCR register to the hv_regs passed to the L0 hypervisor as input to the H_ENTER_NESTED hcall, however this would have meant updating the structure layout and thus required modifications to both the L0 and L1 kernels. Whereas the approach used doesn't require L0 kernel modifications while achieving the same result.
Fixes: 95a6432ce903 ("KVM: PPC: Book3S HV: Streamlined guest entry/exit path on P9 for radix guests") Cc: stable@vger.kernel.org # v4.20+ Signed-off-by: Suraj Jitindar Singh sjitindarsingh@gmail.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20190703012022.15644-3-sjitindarsingh@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/powerpc/kvm/book3s_hv.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
--- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -3569,9 +3569,18 @@ int kvmhv_p9_guest_entry(struct kvm_vcpu mtspr(SPRN_DEC, vcpu->arch.dec_expires - mftb());
if (kvmhv_on_pseries()) { + /* + * We need to save and restore the guest visible part of the + * psscr (i.e. using SPRN_PSSCR_PR) since the hypervisor + * doesn't do this for us. Note only required if pseries since + * this is done in kvmhv_load_hv_regs_and_go() below otherwise. + */ + unsigned long host_psscr; /* call our hypervisor to load up HV regs and go */ struct hv_guest_state hvregs;
+ host_psscr = mfspr(SPRN_PSSCR_PR); + mtspr(SPRN_PSSCR_PR, vcpu->arch.psscr); kvmhv_save_hv_regs(vcpu, &hvregs); hvregs.lpcr = lpcr; vcpu->arch.regs.msr = vcpu->arch.shregs.msr; @@ -3590,6 +3599,8 @@ int kvmhv_p9_guest_entry(struct kvm_vcpu vcpu->arch.shregs.msr = vcpu->arch.regs.msr; vcpu->arch.shregs.dar = mfspr(SPRN_DAR); vcpu->arch.shregs.dsisr = mfspr(SPRN_DSISR); + vcpu->arch.psscr = mfspr(SPRN_PSSCR_PR); + mtspr(SPRN_PSSCR_PR, host_psscr);
/* H_CEDE has to be handled now, not later */ if (trap == BOOK3S_INTERRUPT_SYSCALL && !vcpu->arch.nested &&
From: Cédric Le Goater clg@kaod.org
commit 9798f4ea71eaf8eaad7e688c5b298528089c7bf8 upstream.
The XIVE device structure is now allocated in kvmppc_xive_get_device() and kfree'd in kvmppc_core_destroy_vm(). In case of an OPAL error when allocating the XIVE VPs, the kfree() call in kvmppc_xive_*create() will result in a double free and corrupt the host memory.
Fixes: 5422e95103cf ("KVM: PPC: Book3S HV: XIVE: Replace the 'destroy' method by a 'release' method") Cc: stable@vger.kernel.org # v5.2+ Signed-off-by: Cédric Le Goater clg@kaod.org Tested-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/6ea6998b-a890-2511-01d1-747d7621eb19@kaod.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/powerpc/kvm/book3s_xive.c | 4 +--- arch/powerpc/kvm/book3s_xive_native.c | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-)
--- a/arch/powerpc/kvm/book3s_xive.c +++ b/arch/powerpc/kvm/book3s_xive.c @@ -1986,10 +1986,8 @@ static int kvmppc_xive_create(struct kvm
xive->single_escalation = xive_native_has_single_escalation();
- if (ret) { - kfree(xive); + if (ret) return ret; - }
return 0; } --- a/arch/powerpc/kvm/book3s_xive_native.c +++ b/arch/powerpc/kvm/book3s_xive_native.c @@ -1090,9 +1090,9 @@ static int kvmppc_xive_native_create(str xive->ops = &kvmppc_xive_native_ops;
if (ret) - kfree(xive); + return ret;
- return ret; + return 0; }
/*
From: Hans Verkuil hverkuil@xs4all.nl
commit 22be8233b34f4f468934c5fefcbe6151766fb8f2 upstream.
The V4L2_PIX_FMT_BGRA444 define clashed with the pre-existing V4L2_PIX_FMT_SGRBG12 which strangely enough used the same fourcc, even though that fourcc made no sense for a Bayer format. In any case, you can't have duplicates, so change the fourcc of V4L2_PIX_FMT_BGRA444.
Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Cc: stable@vger.kernel.org # for v5.2 and up Fixes: 6c84f9b1d2900 ("media: v4l: Add definitions for missing 16-bit RGB4444 formats") Reviewed-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Reviewed-by: Kieran Bingham kieran.bingham+renesas@ideasonboard.com Signed-off-by: Mauro Carvalho Chehab mchehab+samsung@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 9d9705ceda76..2427bc4d8eba 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -518,7 +518,13 @@ struct v4l2_pix_format { #define V4L2_PIX_FMT_RGBX444 v4l2_fourcc('R', 'X', '1', '2') /* 16 rrrrgggg bbbbxxxx */ #define V4L2_PIX_FMT_ABGR444 v4l2_fourcc('A', 'B', '1', '2') /* 16 aaaabbbb ggggrrrr */ #define V4L2_PIX_FMT_XBGR444 v4l2_fourcc('X', 'B', '1', '2') /* 16 xxxxbbbb ggggrrrr */ -#define V4L2_PIX_FMT_BGRA444 v4l2_fourcc('B', 'A', '1', '2') /* 16 bbbbgggg rrrraaaa */ + +/* + * Originally this had 'BA12' as fourcc, but this clashed with the older + * V4L2_PIX_FMT_SGRBG12 which inexplicably used that same fourcc. + * So use 'GA12' instead for V4L2_PIX_FMT_BGRA444. + */ +#define V4L2_PIX_FMT_BGRA444 v4l2_fourcc('G', 'A', '1', '2') /* 16 bbbbgggg rrrraaaa */ #define V4L2_PIX_FMT_BGRX444 v4l2_fourcc('B', 'X', '1', '2') /* 16 bbbbgggg rrrrxxxx */ #define V4L2_PIX_FMT_RGB555 v4l2_fourcc('R', 'G', 'B', 'O') /* 16 RGB-5-5-5 */ #define V4L2_PIX_FMT_ARGB555 v4l2_fourcc('A', 'R', '1', '5') /* 16 ARGB-1-5-5-5 */
From: Qu Wenruo wqu@suse.com
commit 42c16da6d684391db83788eb680accd84f6c2083 upstream.
As btrfs(5) specified:
Note If nodatacow or nodatasum are enabled, compression is disabled.
If NODATASUM or NODATACOW set, we should not compress the extent.
Normally NODATACOW is detected properly in run_delalloc_range() so compression won't happen for NODATACOW.
However for NODATASUM we don't have any check, and it can cause compressed extent without csum pretty easily, just by: mkfs.btrfs -f $dev mount $dev $mnt -o nodatasum touch $mnt/foobar mount -o remount,datasum,compress $mnt xfs_io -f -c "pwrite 0 128K" $mnt/foobar
And in fact, we have a bug report about corrupted compressed extent without proper data checksum so even RAID1 can't recover the corruption. (https://bugzilla.kernel.org/show_bug.cgi?id=199707)
Running compression without proper checksum could cause more damage when corruption happens, as compressed data could make the whole extent unreadable, so there is no need to allow compression for NODATACSUM.
The fix will refactor the inode compression check into two parts:
- inode_can_compress() As the hard requirement, checked at btrfs_run_delalloc_range(), so no compression will happen for NODATASUM inode at all.
- inode_need_compress() As the soft requirement, checked at btrfs_run_delalloc_range() and compress_file_range().
Reported-by: James Harvey jamespharvey20@gmail.com CC: stable@vger.kernel.org # 4.4+ Signed-off-by: Qu Wenruo wqu@suse.com Reviewed-by: David Sterba dsterba@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/btrfs/inode.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-)
--- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -394,10 +394,31 @@ static noinline int add_async_extent(str return 0; }
+/* + * Check if the inode has flags compatible with compression + */ +static inline bool inode_can_compress(struct inode *inode) +{ + if (BTRFS_I(inode)->flags & BTRFS_INODE_NODATACOW || + BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM) + return false; + return true; +} + +/* + * Check if the inode needs to be submitted to compression, based on mount + * options, defragmentation, properties or heuristics. + */ static inline int inode_need_compress(struct inode *inode, u64 start, u64 end) { struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
+ if (!inode_can_compress(inode)) { + WARN(IS_ENABLED(CONFIG_BTRFS_DEBUG), + KERN_ERR "BTRFS: unexpected compression for ino %llu\n", + btrfs_ino(BTRFS_I(inode))); + return 0; + } /* force compress */ if (btrfs_test_opt(fs_info, FORCE_COMPRESS)) return 1; @@ -1630,7 +1651,8 @@ int btrfs_run_delalloc_range(struct inod } else if (BTRFS_I(inode)->flags & BTRFS_INODE_PREALLOC && !force_cow) { ret = run_delalloc_nocow(inode, locked_page, start, end, page_started, 0, nr_written); - } else if (!inode_need_compress(inode, start, end)) { + } else if (!inode_can_compress(inode) || + !inode_need_compress(inode, start, end)) { ret = cow_file_range(inode, locked_page, start, end, end, page_started, nr_written, 1, NULL); } else {
From: Ondrej Mosnacek omosnace@redhat.com
commit acbc372e6109c803cbee4733769d02008381740f upstream.
We need to error out when trying to add an entry above SIDTAB_MAX in sidtab_reverse_lookup() to avoid overflow on the odd chance that this happens.
Cc: stable@vger.kernel.org Fixes: ee1a84fdfeed ("selinux: overhaul sidtab to fix bug and improve performance") Signed-off-by: Ondrej Mosnacek omosnace@redhat.com Reviewed-by: Kees Cook keescook@chromium.org Signed-off-by: Paul Moore paul@paul-moore.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- security/selinux/ss/sidtab.c | 5 +++++ 1 file changed, 5 insertions(+)
--- a/security/selinux/ss/sidtab.c +++ b/security/selinux/ss/sidtab.c @@ -286,6 +286,11 @@ static int sidtab_reverse_lookup(struct ++count; }
+ /* bail out if we already reached max entries */ + rc = -EOVERFLOW; + if (count >= SIDTAB_MAX) + goto out_unlock; + /* insert context into new entry */ rc = -ENOMEM; dst = sidtab_do_lookup(s, count, 1);
From: Hans de Goede hdegoede@redhat.com
commit d02f1aa39189e0619c3525d5cd03254e61bf606a upstream.
Some Lenovo 2-in-1s with a detachable keyboard have a portrait screen but advertise a landscape resolution and pitch, resulting in a messed up display if the kernel tries to show anything on the efifb (because of the wrong pitch).
Fix this by adding a new DMI match table for devices which need to have their width and height swapped.
At first it was tried to use the existing table for overriding some of the efifb parameters, but some of the affected devices have variants with different LCD resolutions which will not work with hardcoded override values.
Reference: https://bugzilla.redhat.com/show_bug.cgi?id=1730783 Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Thomas Gleixner tglx@linutronix.de Cc: stable@vger.kernel.org Link: https://lkml.kernel.org/r/20190721152418.11644-1-hdegoede@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/x86/kernel/sysfb_efi.c | 46 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+)
--- a/arch/x86/kernel/sysfb_efi.c +++ b/arch/x86/kernel/sysfb_efi.c @@ -230,9 +230,55 @@ static const struct dmi_system_id efifb_ {}, };
+/* + * Some devices have a portrait LCD but advertise a landscape resolution (and + * pitch). We simply swap width and height for these devices so that we can + * correctly deal with some of them coming with multiple resolutions. + */ +static const struct dmi_system_id efifb_dmi_swap_width_height[] __initconst = { + { + /* + * Lenovo MIIX310-10ICR, only some batches have the troublesome + * 800x1280 portrait screen. Luckily the portrait version has + * its own BIOS version, so we match on that. + */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "MIIX 310-10ICR"), + DMI_EXACT_MATCH(DMI_BIOS_VERSION, "1HCN44WW"), + }, + }, + { + /* Lenovo MIIX 320-10ICR with 800x1280 portrait screen */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, + "Lenovo MIIX 320-10ICR"), + }, + }, + { + /* Lenovo D330 with 800x1280 or 1200x1920 portrait screen */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, + "Lenovo ideapad D330-10IGM"), + }, + }, + {}, +}; + __init void sysfb_apply_efi_quirks(void) { if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI || !(screen_info.capabilities & VIDEO_CAPABILITY_SKIP_QUIRKS)) dmi_check_system(efifb_dmi_system_table); + + if (screen_info.orig_video_isVGA == VIDEO_TYPE_EFI && + dmi_check_system(efifb_dmi_swap_width_height)) { + u16 temp = screen_info.lfb_width; + + screen_info.lfb_width = screen_info.lfb_height; + screen_info.lfb_height = temp; + screen_info.lfb_linelength = 4 * screen_info.lfb_width; + } }
From: Zhenzhong Duan zhenzhong.duan@oracle.com
commit 517c3ba00916383af6411aec99442c307c23f684 upstream.
X86_HYPER_NATIVE isn't accurate for checking if running on native platform, e.g. CONFIG_HYPERVISOR_GUEST isn't set or "nopv" is enabled.
Checking the CPU feature bit X86_FEATURE_HYPERVISOR to determine if it's running on native platform is more accurate.
This still doesn't cover the platforms on which X86_FEATURE_HYPERVISOR is unsupported, e.g. VMware, but there is nothing which can be done about this scenario.
Fixes: 8a4b06d391b0 ("x86/speculation/mds: Add sysfs reporting for MDS") Signed-off-by: Zhenzhong Duan zhenzhong.duan@oracle.com Signed-off-by: Thomas Gleixner tglx@linutronix.de Cc: stable@vger.kernel.org Link: https://lkml.kernel.org/r/1564022349-17338-1-git-send-email-zhenzhong.duan@o... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/x86/kernel/cpu/bugs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c @@ -1226,7 +1226,7 @@ static ssize_t l1tf_show_state(char *buf
static ssize_t mds_show_state(char *buf) { - if (!hypervisor_is_type(X86_HYPER_NATIVE)) { + if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) { return sprintf(buf, "%s; SMT Host state unknown\n", mds_strings[mds_mitigation]); }
From: Eiichi Tsukata devel@etsukata.com
commit 2af7c85714d8cafadf925d55441458eae312cd6b upstream.
When arch_stack_walk_user() is called from atomic contexts, access_ok() can trigger the following warning if compiled with CONFIG_DEBUG_ATOMIC_SLEEP=y.
Reproducer:
// CONFIG_DEBUG_ATOMIC_SLEEP=y # cd /sys/kernel/debug/tracing # echo 1 > options/userstacktrace # echo 1 > events/irq/irq_handler_entry/enable
WARNING: CPU: 0 PID: 2649 at arch/x86/kernel/stacktrace.c:103 arch_stack_walk_user+0x6e/0xf6 CPU: 0 PID: 2649 Comm: bash Not tainted 5.3.0-rc1+ #99 RIP: 0010:arch_stack_walk_user+0x6e/0xf6 Call Trace: <IRQ> stack_trace_save_user+0x10a/0x16d trace_buffer_unlock_commit_regs+0x185/0x240 trace_event_buffer_commit+0xec/0x330 trace_event_raw_event_irq_handler_entry+0x159/0x1e0 __handle_irq_event_percpu+0x22d/0x440 handle_irq_event_percpu+0x70/0x100 handle_irq_event+0x5a/0x8b handle_edge_irq+0x12f/0x3f0 handle_irq+0x34/0x40 do_IRQ+0xa6/0x1f0 common_interrupt+0xf/0xf </IRQ>
Fix it by calling __range_not_ok() directly instead of access_ok() as copy_from_user_nmi() does. This is fine here because the actual copy is inside a pagefault disabled region.
Reported-by: Juri Lelli juri.lelli@gmail.com Signed-off-by: Eiichi Tsukata devel@etsukata.com Signed-off-by: Thomas Gleixner tglx@linutronix.de Link: https://lkml.kernel.org/r/20190722083216.16192-2-devel@etsukata.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/x86/kernel/stacktrace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/x86/kernel/stacktrace.c +++ b/arch/x86/kernel/stacktrace.c @@ -100,7 +100,7 @@ copy_stack_frame(const void __user *fp, { int ret;
- if (!access_ok(fp, sizeof(*frame))) + if (__range_not_ok(fp, sizeof(*frame), TASK_SIZE)) return 0;
ret = 1;
From: Martijn Coenen maco@android.com
commit a56587065094fd96eb4c2b5ad65571daad32156d upstream.
In case the target node requests a security context, the extra_buffers_size is increased with the size of the security context. But, that size is not available for use by regular scatter-gather buffers; make sure the ending of that buffer is marked correctly.
Acked-by: Todd Kjos tkjos@google.com Fixes: ec74136ded79 ("binder: create node flag to request sender's security context") Signed-off-by: Martijn Coenen maco@android.com Cc: stable@vger.kernel.org # 5.1+ Link: https://lore.kernel.org/r/20190709110923.220736-1-maco@android.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/android/binder.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -3239,7 +3239,8 @@ static void binder_transaction(struct bi buffer_offset = off_start_offset; off_end_offset = off_start_offset + tr->offsets_size; sg_buf_offset = ALIGN(off_end_offset, sizeof(void *)); - sg_buf_end_offset = sg_buf_offset + extra_buffers_size; + sg_buf_end_offset = sg_buf_offset + extra_buffers_size - + ALIGN(secctx_sz, sizeof(u64)); off_min = 0; for (buffer_offset = off_start_offset; buffer_offset < off_end_offset; buffer_offset += sizeof(binder_size_t)) {
From: Hridya Valsaraju hridya@google.com
commit 49ed96943a8e0c62cc5a9b0a6cfc88be87d1fcec upstream.
Currently, a transaction to context manager from its own process is prevented by checking if its binder_proc struct is the same as that of the sender. However, this would not catch cases where the process opens the binder device again and uses the new fd to send a transaction to the context manager.
Reported-by: syzbot+8b3c354d33c4ac78bfad@syzkaller.appspotmail.com Signed-off-by: Hridya Valsaraju hridya@google.com Acked-by: Todd Kjos tkjos@google.com Cc: stable stable@vger.kernel.org Link: https://lore.kernel.org/r/20190715191804.112933-1-hridya@google.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/android/binder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2988,7 +2988,7 @@ static void binder_transaction(struct bi else return_error = BR_DEAD_REPLY; mutex_unlock(&context->context_mgr_node_lock); - if (target_node && target_proc == proc) { + if (target_node && target_proc->pid == proc->pid) { binder_user_error("%d:%d got transaction to context manager from process owning it\n", proc->pid, thread->pid); return_error = BR_FAILED_REPLY;
From: YueHaibing yuehaibing@huawei.com
commit 3d139703d397f6281368047ba7ad1c8bf95aa8ab upstream.
If BITREVERSE is m and FPGA_MGR_ALTERA_PS_SPI is y, build fails:
drivers/fpga/altera-ps-spi.o: In function `altera_ps_write': altera-ps-spi.c:(.text+0x4ec): undefined reference to `byte_rev_table'
Select BITREVERSE to fix this.
Reported-by: Hulk Robot hulkci@huawei.com Fixes: fcfe18f885f6 ("fpga-manager: altera-ps-spi: use bitrev8x4") Signed-off-by: YueHaibing yuehaibing@huawei.com Cc: stable stable@vger.kernel.org Acked-by: Moritz Fischer mdf@kernel.org Link: https://lore.kernel.org/r/20190708071356.50928-1-yuehaibing@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/fpga/Kconfig | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/fpga/Kconfig +++ b/drivers/fpga/Kconfig @@ -40,6 +40,7 @@ config ALTERA_PR_IP_CORE_PLAT config FPGA_MGR_ALTERA_PS_SPI tristate "Altera FPGA Passive Serial over SPI" depends on SPI + select BITREVERSE help FPGA manager driver support for Altera Arria/Cyclone/Stratix using the passive serial interface over SPI.
From: Alexander Usyskin alexander.usyskin@intel.com
commit 1be8624a0cbef720e8da39a15971e01abffc865b upstream.
Add Mule Creek Canyon (PCH) MEI device ids for Elkhart Lake (EHL) Platform.
Signed-off-by: Alexander Usyskin alexander.usyskin@intel.com Signed-off-by: Tomas Winkler tomas.winkler@intel.com Cc: stable stable@vger.kernel.org Link: https://lore.kernel.org/r/20190712095814.20746-1-tomas.winkler@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/misc/mei/hw-me-regs.h | 3 +++ drivers/misc/mei/pci-me.c | 3 +++ 2 files changed, 6 insertions(+)
--- a/drivers/misc/mei/hw-me-regs.h +++ b/drivers/misc/mei/hw-me-regs.h @@ -81,6 +81,9 @@
#define MEI_DEV_ID_ICP_LP 0x34E0 /* Ice Lake Point LP */
+#define MEI_DEV_ID_MCC 0x4B70 /* Mule Creek Canyon (EHL) */ +#define MEI_DEV_ID_MCC_4 0x4B75 /* Mule Creek Canyon 4 (EHL) */ + /* * MEI HW Section */ --- a/drivers/misc/mei/pci-me.c +++ b/drivers/misc/mei/pci-me.c @@ -98,6 +98,9 @@ static const struct pci_device_id mei_me
{MEI_PCI_DEVICE(MEI_DEV_ID_ICP_LP, MEI_ME_PCH12_CFG)},
+ {MEI_PCI_DEVICE(MEI_DEV_ID_MCC, MEI_ME_PCH12_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_MCC_4, MEI_ME_PCH8_CFG)}, + /* required last entry */ {0, } };
From: Arseny Solokha asolokha@kb.kras.ru
commit 1b5621832f9bd9899370ea6928462cd02ebe7dc0 upstream.
misc/eeprom/{at24,at25,eeprom_93xx46} drivers all register their corresponding devices in the nvmem framework in compat mode which requires nvmem sysfs interface to be present. The latter, however, has been split out from nvmem under a separate Kconfig in commit ae0c2d725512 ("nvmem: core: add NVMEM_SYSFS Kconfig"). As a result, probing certain I2C-attached EEPROMs now fails with
at24: probe of 0-0050 failed with error -38
because of a stub implementation of nvmem_sysfs_setup_compat() in drivers/nvmem/nvmem.h. Update the nvmem dependency for these drivers so they could load again:
at24 0-0050: 32768 byte 24c256 EEPROM, writable, 64 bytes/write
Cc: Adrian Bunk bunk@kernel.org Cc: Bartosz Golaszewski brgl@bgdev.pl Cc: Srinivas Kandagatla srinivas.kandagatla@linaro.org Cc: stable@vger.kernel.org # v5.2+ Signed-off-by: Arseny Solokha asolokha@kb.kras.ru Link: https://lore.kernel.org/r/20190716111236.27803-1-asolokha@kb.kras.ru Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/misc/eeprom/Kconfig | 3 +++ 1 file changed, 3 insertions(+)
--- a/drivers/misc/eeprom/Kconfig +++ b/drivers/misc/eeprom/Kconfig @@ -5,6 +5,7 @@ config EEPROM_AT24 tristate "I2C EEPROMs / RAMs / ROMs from most vendors" depends on I2C && SYSFS select NVMEM + select NVMEM_SYSFS select REGMAP_I2C help Enable this driver to get read/write support to most I2C EEPROMs @@ -34,6 +35,7 @@ config EEPROM_AT25 tristate "SPI EEPROMs from most vendors" depends on SPI && SYSFS select NVMEM + select NVMEM_SYSFS help Enable this driver to get read/write support to most SPI EEPROMs, after you configure the board init code to know about each eeprom @@ -80,6 +82,7 @@ config EEPROM_93XX46 depends on SPI && SYSFS select REGMAP select NVMEM + select NVMEM_SYSFS help Driver for the microwire EEPROM chipsets 93xx46x. The driver supports both read and write commands and also the command to
From: Kefeng Wang wangkefeng.wang@huawei.com
commit 0c7d37f4d9b8446956e97b7c5e61173cdb7c8522 upstream.
The base value in do_div() called by hpet_time_div() is truncated from unsigned long to uint32_t, resulting in a divide-by-zero exception.
UBSAN: Undefined behaviour in ../drivers/char/hpet.c:572:2 division by zero CPU: 1 PID: 23682 Comm: syz-executor.3 Not tainted 4.4.184.x86_64+ #4 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014 0000000000000000 b573382df1853d00 ffff8800a3287b98 ffffffff81ad7561 ffff8800a3287c00 ffffffff838b35b0 ffffffff838b3860 ffff8800a3287c20 0000000000000000 ffff8800a3287bb0 ffffffff81b8f25e ffffffff838b35a0 Call Trace: [<ffffffff81ad7561>] __dump_stack lib/dump_stack.c:15 [inline] [<ffffffff81ad7561>] dump_stack+0xc1/0x120 lib/dump_stack.c:51 [<ffffffff81b8f25e>] ubsan_epilogue+0x12/0x8d lib/ubsan.c:166 [<ffffffff81b900cb>] __ubsan_handle_divrem_overflow+0x282/0x2c8 lib/ubsan.c:262 [<ffffffff823560dd>] hpet_time_div drivers/char/hpet.c:572 [inline] [<ffffffff823560dd>] hpet_ioctl_common drivers/char/hpet.c:663 [inline] [<ffffffff823560dd>] hpet_ioctl_common.cold+0xa8/0xad drivers/char/hpet.c:577 [<ffffffff81e63d56>] hpet_ioctl+0xc6/0x180 drivers/char/hpet.c:676 [<ffffffff81711590>] vfs_ioctl fs/ioctl.c:43 [inline] [<ffffffff81711590>] file_ioctl fs/ioctl.c:470 [inline] [<ffffffff81711590>] do_vfs_ioctl+0x6e0/0xf70 fs/ioctl.c:605 [<ffffffff81711eb4>] SYSC_ioctl fs/ioctl.c:622 [inline] [<ffffffff81711eb4>] SyS_ioctl+0x94/0xc0 fs/ioctl.c:613 [<ffffffff82846003>] tracesys_phase2+0x90/0x95
The main C reproducer autogenerated by syzkaller,
syscall(__NR_mmap, 0x20000000, 0x1000000, 3, 0x32, -1, 0); memcpy((void*)0x20000100, "/dev/hpet\000", 10); syscall(__NR_openat, 0xffffffffffffff9c, 0x20000100, 0, 0); syscall(__NR_ioctl, r[0], 0x40086806, 0x40000000000000);
Fix it by using div64_ul().
Signed-off-by: Kefeng Wang wangkefeng.wang@huawei.com Signed-off-by: Zhang HongJun zhanghongjun2@huawei.com Cc: stable stable@vger.kernel.org Reviewed-by: Arnd Bergmann arnd@arndb.de Link: https://lore.kernel.org/r/20190711132757.130092-1-wangkefeng.wang@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/char/hpet.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
--- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c @@ -567,8 +567,7 @@ static inline unsigned long hpet_time_di unsigned long long m;
m = hpets->hp_tick_freq + (dis >> 1); - do_div(m, dis); - return (unsigned long)m; + return div64_ul(m, dis); }
static int
From: Sébastien Szymanski sebastien.szymanski@armadeus.com
commit c479450f61c7f1f248c9a54aedacd2a6ca521ff8 upstream.
This patch adds support for the Armadeus ST0700 Adapt. It comes with a Santek ST0700I5Y-RBSLW 7.0" WVGA (800x480) TFT and an adapter board so that it can be connected on the TFT header of Armadeus Dev boards.
Cc: stable@vger.kernel.org # v4.19 Reviewed-by: Rob Herring robh@kernel.org Signed-off-by: Sébastien Szymanski sebastien.szymanski@armadeus.com Signed-off-by: Sam Ravnborg sam@ravnborg.org Link: https://patchwork.freedesktop.org/patch/msgid/20190507152713.27494-1-sebasti... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- Documentation/devicetree/bindings/display/panel/armadeus,st0700-adapt.txt | 9 +++ drivers/gpu/drm/panel/panel-simple.c | 29 ++++++++++ 2 files changed, 38 insertions(+)
--- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/armadeus,st0700-adapt.txt @@ -0,0 +1,9 @@ +Armadeus ST0700 Adapt. A Santek ST0700I5Y-RBSLW 7.0" WVGA (800x480) TFT with +an adapter board. + +Required properties: +- compatible: "armadeus,st0700-adapt" +- power-supply: see panel-common.txt + +Optional properties: +- backlight: see panel-common.txt --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -446,6 +446,32 @@ static const struct panel_desc ampire_am .bus_format = MEDIA_BUS_FMT_RGB666_1X18, };
+static const struct display_timing santek_st0700i5y_rbslw_f_timing = { + .pixelclock = { 26400000, 33300000, 46800000 }, + .hactive = { 800, 800, 800 }, + .hfront_porch = { 16, 210, 354 }, + .hback_porch = { 45, 36, 6 }, + .hsync_len = { 1, 10, 40 }, + .vactive = { 480, 480, 480 }, + .vfront_porch = { 7, 22, 147 }, + .vback_porch = { 22, 13, 3 }, + .vsync_len = { 1, 10, 20 }, + .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW | + DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_POSEDGE +}; + +static const struct panel_desc armadeus_st0700_adapt = { + .timings = &santek_st0700i5y_rbslw_f_timing, + .num_timings = 1, + .bpc = 6, + .size = { + .width = 154, + .height = 86, + }, + .bus_format = MEDIA_BUS_FMT_RGB666_1X18, + .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_POSEDGE, +}; + static const struct drm_display_mode auo_b101aw03_mode = { .clock = 51450, .hdisplay = 1024, @@ -2571,6 +2597,9 @@ static const struct of_device_id platfor .compatible = "arm,rtsm-display", .data = &arm_rtsm, }, { + .compatible = "armadeus,st0700-adapt", + .data = &armadeus_st0700_adapt, + }, { .compatible = "auo,b101aw03", .data = &auo_b101aw03, }, {
From: Ding Xiang dingxiang@cmss.chinamobile.com
commit 607975b30db41aad6edc846ed567191aa6b7d893 upstream.
put_device will call ac97_codec_release to free ac97_codec_device and other resources, so remove the kfree and other redundant code.
Fixes: 74426fbff66e ("ALSA: ac97: add an ac97 bus") Signed-off-by: Ding Xiang dingxiang@cmss.chinamobile.com Cc: stable@vger.kernel.org Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- sound/ac97/bus.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-)
--- a/sound/ac97/bus.c +++ b/sound/ac97/bus.c @@ -122,17 +122,12 @@ static int ac97_codec_add(struct ac97_co vendor_id);
ret = device_add(&codec->dev); - if (ret) - goto err_free_codec; + if (ret) { + put_device(&codec->dev); + return ret; + }
return 0; -err_free_codec: - of_node_put(codec->dev.of_node); - put_device(&codec->dev); - kfree(codec); - ac97_ctrl->codecs[idx] = NULL; - - return ret; }
unsigned int snd_ac97_bus_scan_one(struct ac97_controller *adrv,
From: Kai-Heng Feng kai.heng.feng@canonical.com
commit 70256b42caaf3e13c2932c2be7903a73fbe8bb8b upstream.
Commit 7b9584fa1c0b ("staging: line6: Move altsetting to properties") set a wrong altsetting for LINE6_PODHD500_1 during refactoring.
Set the correct altsetting number to fix the issue.
BugLink: https://bugs.launchpad.net/bugs/1790595 Fixes: 7b9584fa1c0b ("staging: line6: Move altsetting to properties") Signed-off-by: Kai-Heng Feng kai.heng.feng@canonical.com Cc: stable@vger.kernel.org Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- sound/usb/line6/podhd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/sound/usb/line6/podhd.c +++ b/sound/usb/line6/podhd.c @@ -413,7 +413,7 @@ static const struct line6_properties pod .name = "POD HD500", .capabilities = LINE6_CAP_PCM | LINE6_CAP_HWMON, - .altsetting = 1, + .altsetting = 0, .ep_ctrl_r = 0x81, .ep_ctrl_w = 0x01, .ep_audio_r = 0x86,
From: Takashi Iwai tiwai@suse.de
commit 0e279dcea0ec897af1c979ebee4ec92b461793f5 upstream.
The recent rewrite of PCM link lock management introduced the refcount in snd_pcm_group object, managed by the kernel refcount_t API. This caused unexpected kernel warnings when the kernel is built with CONFIG_REFCOUNT_FULL=y. As the warning line indicates, the problem is obviously that we start with refcount=0 and do refcount_inc() for adding each PCM link, while refcount_t API doesn't like refcount_inc() performed on zero.
For adapting the proper refcount_t usage, this patch changes the logic slightly: - The initial refcount is 1, assuming the single list entry - The refcount is incremented / decremented at each PCM link addition and deletion - ... which allows us concentrating only on the refcount as a release condition
Fixes: f57f3df03a8e ("ALSA: pcm: More fine-grained PCM link locking") BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=204221 Reported-and-tested-by: Duncan Overbruck kernel@duncano.de Cc: stable@vger.kernel.org Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- sound/core/pcm_native.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
--- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -77,7 +77,7 @@ void snd_pcm_group_init(struct snd_pcm_g spin_lock_init(&group->lock); mutex_init(&group->mutex); INIT_LIST_HEAD(&group->substreams); - refcount_set(&group->refs, 0); + refcount_set(&group->refs, 1); }
/* define group lock helpers */ @@ -1096,8 +1096,7 @@ static void snd_pcm_group_unref(struct s
if (!group) return; - do_free = refcount_dec_and_test(&group->refs) && - list_empty(&group->substreams); + do_free = refcount_dec_and_test(&group->refs); snd_pcm_group_unlock(group, substream->pcm->nonatomic); if (do_free) kfree(group); @@ -2020,6 +2019,7 @@ static int snd_pcm_link(struct snd_pcm_s snd_pcm_group_lock_irq(target_group, nonatomic); snd_pcm_stream_lock(substream1); snd_pcm_group_assign(substream1, target_group); + refcount_inc(&target_group->refs); snd_pcm_stream_unlock(substream1); snd_pcm_group_unlock_irq(target_group, nonatomic); _end: @@ -2056,13 +2056,14 @@ static int snd_pcm_unlink(struct snd_pcm snd_pcm_group_lock_irq(group, nonatomic);
relink_to_local(substream); + refcount_dec(&group->refs);
/* detach the last stream, too */ if (list_is_singular(&group->substreams)) { relink_to_local(list_first_entry(&group->substreams, struct snd_pcm_substream, link_list)); - do_free = !refcount_read(&group->refs); + do_free = refcount_dec_and_test(&group->refs); }
snd_pcm_group_unlock_irq(group, nonatomic);
From: Takashi Iwai tiwai@suse.de
commit 2756d9143aa517b97961e85412882b8ce31371a6 upstream.
It turned out that the recent Intel HD-audio controller chips show a significant stall during the system PM resume intermittently. It doesn't happen so often and usually it may read back successfully after one or more seconds, but in some rare worst cases the driver went into fallback mode.
After trial-and-error, we found out that the communication stall seems covered by issuing the sync after each verb write, as already done for AMD and other chipsets. So this patch enables the write-sync flag for the recent Intel chips, Skylake and onward, as a workaround.
Also, since Broxton and co have the very same driver flags as Skylake, refer to the Skylake driver flags instead of defining the same contents again for simplification.
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=201901 Reported-and-tested-by: Todd Brandt todd.e.brandt@linux.intel.com Cc: stable@vger.kernel.org Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- sound/pci/hda/hda_intel.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
--- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -313,11 +313,10 @@ enum {
#define AZX_DCAPS_INTEL_SKYLAKE \ (AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_PM_RUNTIME |\ + AZX_DCAPS_SYNC_WRITE |\ AZX_DCAPS_SEPARATE_STREAM_TAG | AZX_DCAPS_I915_COMPONENT)
-#define AZX_DCAPS_INTEL_BROXTON \ - (AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_PM_RUNTIME |\ - AZX_DCAPS_SEPARATE_STREAM_TAG | AZX_DCAPS_I915_COMPONENT) +#define AZX_DCAPS_INTEL_BROXTON AZX_DCAPS_INTEL_SKYLAKE
/* quirks for ATI SB / AMD Hudson */ #define AZX_DCAPS_PRESET_ATI_SB \
From: Hui Wang hui.wang@canonical.com
commit 3f8809499bf02ef7874254c5e23fc764a47a21a0 upstream.
This conexant codec isn't in the supported codec list yet, the hda generic driver can drive this codec well, but on a Lenovo machine with mute/mic-mute leds, we need to apply CXT_FIXUP_THINKPAD_ACPI to make the leds work. After adding this codec to the list, the driver patch_conexant.c will apply THINKPAD_ACPI to this machine.
Cc: stable@vger.kernel.org Signed-off-by: Hui Wang hui.wang@canonical.com Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- sound/pci/hda/patch_conexant.c | 1 + 1 file changed, 1 insertion(+)
--- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -1083,6 +1083,7 @@ static int patch_conexant_auto(struct hd */
static const struct hda_device_id snd_hda_id_conexant[] = { + HDA_CODEC_ENTRY(0x14f11f86, "CX8070", patch_conexant_auto), HDA_CODEC_ENTRY(0x14f12008, "CX8200", patch_conexant_auto), HDA_CODEC_ENTRY(0x14f15045, "CX20549 (Venice)", patch_conexant_auto), HDA_CODEC_ENTRY(0x14f15047, "CX20551 (Waikiki)", patch_conexant_auto),
From: Shawn Anastasio shawn@anastas.io
commit b4fc36e60f25cf22bf8b7b015a701015740c3743 upstream.
The refactor of powerpc DMA functions in commit 6666cc17d780 ("powerpc/dma: remove dma_nommu_mmap_coherent") incorrectly changes the way DMA mappings are handled on powerpc. Since this change, all mapped pages are marked as cache-inhibited through the default implementation of arch_dma_mmap_pgprot. This differs from the previous behavior of only marking pages in noncoherent mappings as cache-inhibited and has resulted in sporadic system crashes in certain hardware configurations and workloads (see Bugzilla).
This commit restores the previous correct behavior by providing an implementation of arch_dma_mmap_pgprot that only marks pages in noncoherent mappings as cache-inhibited. As this behavior should be universal for all powerpc platforms a new file, dma-generic.c, was created to store it.
Fixes: 6666cc17d780 ("powerpc/dma: remove dma_nommu_mmap_coherent") # NOTE: fixes commit 6666cc17d780 released in v5.1. # Consider a stable tag: # Cc: stable@vger.kernel.org # v5.1+ # NOTE: fixes commit 6666cc17d780 released in v5.1. # Consider a stable tag: # Cc: stable@vger.kernel.org # v5.1+ Cc: stable@vger.kernel.org # v5.1+ Signed-off-by: Shawn Anastasio shawn@anastas.io Reviewed-by: Alexey Kardashevskiy aik@ozlabs.ru Reviewed-by: Christoph Hellwig hch@lst.de Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20190717235437.12908-1-shawn@anastas.io Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/powerpc/Kconfig | 1 + arch/powerpc/kernel/Makefile | 3 ++- arch/powerpc/kernel/dma-common.c | 17 +++++++++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-)
--- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -121,6 +121,7 @@ config PPC select ARCH_32BIT_OFF_T if PPC32 select ARCH_HAS_DEBUG_VIRTUAL select ARCH_HAS_DEVMEM_IS_ALLOWED + select ARCH_HAS_DMA_MMAP_PGPROT select ARCH_HAS_ELF_RANDOMIZE select ARCH_HAS_FORTIFY_SOURCE select ARCH_HAS_GCOV_PROFILE_ALL --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -49,7 +49,8 @@ obj-y := cputable.o ptrace.o syscalls signal.o sysfs.o cacheinfo.o time.o \ prom.o traps.o setup-common.o \ udbg.o misc.o io.o misc_$(BITS).o \ - of_platform.o prom_parse.o + of_platform.o prom_parse.o \ + dma-common.o obj-$(CONFIG_PPC64) += setup_64.o sys_ppc32.o \ signal_64.o ptrace32.o \ paca.o nvram_64.o firmware.o --- /dev/null +++ b/arch/powerpc/kernel/dma-common.c @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Contains common dma routines for all powerpc platforms. + * + * Copyright (C) 2019 Shawn Anastasio. + */ + +#include <linux/mm.h> +#include <linux/dma-noncoherent.h> + +pgprot_t arch_dma_mmap_pgprot(struct device *dev, pgprot_t prot, + unsigned long attrs) +{ + if (!dev_is_dma_coherent(dev)) + return pgprot_noncached(prot); + return prot; +}
From: Gautham R. Shenoy ego@linux.vnet.ibm.com
commit 4d202c8c8ed3822327285747db1765967110b274 upstream.
xive_find_target_in_mask() has the following for(;;) loop which has a bug when @first == cpumask_first(@mask) and condition 1 fails to hold for every CPU in @mask. In this case we loop forever in the for-loop.
first = cpu; for (;;) { if (cpu_online(cpu) && xive_try_pick_target(cpu)) // condition 1 return cpu; cpu = cpumask_next(cpu, mask); if (cpu == first) // condition 2 break;
if (cpu >= nr_cpu_ids) // condition 3 cpu = cpumask_first(mask); }
This is because, when @first == cpumask_first(@mask), we never hit the condition 2 (cpu == first) since prior to this check, we would have executed "cpu = cpumask_next(cpu, mask)" which will set the value of @cpu to a value greater than @first or to nr_cpus_ids. When this is coupled with the fact that condition 1 is not met, we will never exit this loop.
This was discovered by the hard-lockup detector while running LTP test concurrently with SMT switch tests.
watchdog: CPU 12 detected hard LOCKUP on other CPUs 68 watchdog: CPU 12 TB:85587019220796, last SMP heartbeat TB:85578827223399 (15999ms ago) watchdog: CPU 68 Hard LOCKUP watchdog: CPU 68 TB:85587019361273, last heartbeat TB:85576815065016 (19930ms ago) CPU: 68 PID: 45050 Comm: hxediag Kdump: loaded Not tainted 4.18.0-100.el8.ppc64le #1 NIP: c0000000006f5578 LR: c000000000cba9ec CTR: 0000000000000000 REGS: c000201fff3c7d80 TRAP: 0100 Not tainted (4.18.0-100.el8.ppc64le) MSR: 9000000002883033 <SF,HV,VEC,VSX,FP,ME,IR,DR,RI,LE> CR: 24028424 XER: 00000000 CFAR: c0000000006f558c IRQMASK: 1 GPR00: c0000000000afc58 c000201c01c43400 c0000000015ce500 c000201cae26ec18 GPR04: 0000000000000800 0000000000000540 0000000000000800 00000000000000f8 GPR08: 0000000000000020 00000000000000a8 0000000080000000 c00800001a1beed8 GPR12: c0000000000b1410 c000201fff7f4c00 0000000000000000 0000000000000000 GPR16: 0000000000000000 0000000000000000 0000000000000540 0000000000000001 GPR20: 0000000000000048 0000000010110000 c00800001a1e3780 c000201cae26ed18 GPR24: 0000000000000000 c000201cae26ed8c 0000000000000001 c000000001116bc0 GPR28: c000000001601ee8 c000000001602494 c000201cae26ec18 000000000000001f NIP [c0000000006f5578] find_next_bit+0x38/0x90 LR [c000000000cba9ec] cpumask_next+0x2c/0x50 Call Trace: [c000201c01c43400] [c000201cae26ec18] 0xc000201cae26ec18 (unreliable) [c000201c01c43420] [c0000000000afc58] xive_find_target_in_mask+0x1b8/0x240 [c000201c01c43470] [c0000000000b0228] xive_pick_irq_target.isra.3+0x168/0x1f0 [c000201c01c435c0] [c0000000000b1470] xive_irq_startup+0x60/0x260 [c000201c01c43640] [c0000000001d8328] __irq_startup+0x58/0xf0 [c000201c01c43670] [c0000000001d844c] irq_startup+0x8c/0x1a0 [c000201c01c436b0] [c0000000001d57b0] __setup_irq+0x9f0/0xa90 [c000201c01c43760] [c0000000001d5aa0] request_threaded_irq+0x140/0x220 [c000201c01c437d0] [c00800001a17b3d4] bnx2x_nic_load+0x188c/0x3040 [bnx2x] [c000201c01c43950] [c00800001a187c44] bnx2x_self_test+0x1fc/0x1f70 [bnx2x] [c000201c01c43a90] [c000000000adc748] dev_ethtool+0x11d8/0x2cb0 [c000201c01c43b60] [c000000000b0b61c] dev_ioctl+0x5ac/0xa50 [c000201c01c43bf0] [c000000000a8d4ec] sock_do_ioctl+0xbc/0x1b0 [c000201c01c43c60] [c000000000a8dfb8] sock_ioctl+0x258/0x4f0 [c000201c01c43d20] [c0000000004c9704] do_vfs_ioctl+0xd4/0xa70 [c000201c01c43de0] [c0000000004ca274] sys_ioctl+0xc4/0x160 [c000201c01c43e30] [c00000000000b388] system_call+0x5c/0x70 Instruction dump: 78aad182 54a806be 3920ffff 78a50664 794a1f24 7d294036 7d43502a 7d295039 4182001c 48000034 78a9d182 79291f24 <7d23482a> 2fa90000 409e0020 38a50040
To fix this, move the check for condition 2 after the check for condition 3, so that we are able to break out of the loop soon after iterating through all the CPUs in the @mask in the problem case. Use do..while() to achieve this.
Fixes: 243e25112d06 ("powerpc/xive: Native exploitation of the XIVE interrupt controller") Cc: stable@vger.kernel.org # v4.12+ Reported-by: Indira P. Joga indira.priya@in.ibm.com Signed-off-by: Gautham R. Shenoy ego@linux.vnet.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/1563359724-13931-1-git-send-email-ego@linux.vnet.i... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/powerpc/sysdev/xive/common.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
--- a/arch/powerpc/sysdev/xive/common.c +++ b/arch/powerpc/sysdev/xive/common.c @@ -479,7 +479,7 @@ static int xive_find_target_in_mask(cons * Now go through the entire mask until we find a valid * target. */ - for (;;) { + do { /* * We re-check online as the fallback case passes us * an untested affinity mask @@ -487,12 +487,11 @@ static int xive_find_target_in_mask(cons if (cpu_online(cpu) && xive_try_pick_target(cpu)) return cpu; cpu = cpumask_next(cpu, mask); - if (cpu == first) - break; /* Wrap around */ if (cpu >= nr_cpu_ids) cpu = cpumask_first(mask); - } + } while (cpu != first); + return -1; }
From: Suraj Jitindar Singh sjitindarsingh@gmail.com
commit da0ef93310e67ae6902efded60b6724dab27a5d1 upstream.
The virtual real mode addressing (VRMA) mechanism is used when a partition is using HPT (Hash Page Table) translation and performs real mode accesses (MSR[IR|DR] = 0) in non-hypervisor mode. In this mode effective address bits 0:23 are treated as zero (i.e. the access is aliased to 0) and the access is performed using an implicit 1TB SLB entry.
The size of the RMA (Real Memory Area) is communicated to the guest as the size of the first memory region in the device tree. And because of the mechanism described above can be expected to not exceed 1TB. In the event that the host erroneously represents the RMA as being larger than 1TB, guest accesses in real mode to memory addresses above 1TB will be aliased down to below 1TB. This means that a memory access performed in real mode may differ to one performed in virtual mode for the same memory address, which would likely have unintended consequences.
To avoid this outcome have the guest explicitly limit the size of the RMA to the current maximum, which is 1TB. This means that even if the first memory block is larger than 1TB, only the first 1TB should be accessed in real mode.
Fixes: c610d65c0ad0 ("powerpc/pseries: lift RTAS limit for hash") Cc: stable@vger.kernel.org # v4.16+ Signed-off-by: Suraj Jitindar Singh sjitindarsingh@gmail.com Tested-by: Satheesh Rajendran sathnaga@linux.vnet.ibm.com Reviewed-by: David Gibson david@gibson.dropbear.id.au Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20190710052018.14628-1-sjitindarsingh@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/powerpc/mm/book3s64/hash_utils.c | 9 +++++++++ 1 file changed, 9 insertions(+)
--- a/arch/powerpc/mm/book3s64/hash_utils.c +++ b/arch/powerpc/mm/book3s64/hash_utils.c @@ -1901,11 +1901,20 @@ void hash__setup_initial_memory_limit(ph * * For guests on platforms before POWER9, we clamp the it limit to 1G * to avoid some funky things such as RTAS bugs etc... + * + * On POWER9 we limit to 1TB in case the host erroneously told us that + * the RMA was >1TB. Effective address bits 0:23 are treated as zero + * (meaning the access is aliased to zero i.e. addr = addr % 1TB) + * for virtual real mode addressing and so it doesn't make sense to + * have an area larger than 1TB as it can't be addressed. */ if (!early_cpu_has_feature(CPU_FTR_HVMODE)) { ppc64_rma_size = first_memblock_size; if (!early_cpu_has_feature(CPU_FTR_ARCH_300)) ppc64_rma_size = min_t(u64, ppc64_rma_size, 0x40000000); + else + ppc64_rma_size = min_t(u64, ppc64_rma_size, + 1UL << SID_SHIFT_1T);
/* Finally limit subsequent allocations */ memblock_set_current_limit(ppc64_rma_size);
From: Michael Neuling mikey@neuling.org
commit f16d80b75a096c52354c6e0a574993f3b0dfbdfe upstream.
On systems like P9 powernv where we have no TM (or P8 booted with ppc_tm=off), userspace can construct a signal context which still has the MSR TS bits set. The kernel tries to restore this context which results in the following crash:
Unexpected TM Bad Thing exception at c0000000000022fc (msr 0x8000000102a03031) tm_scratch=800000020280f033 Oops: Unrecoverable exception, sig: 6 [#1] LE PAGE_SIZE=64K MMU=Hash SMP NR_CPUS=2048 NUMA pSeries Modules linked in: CPU: 0 PID: 1636 Comm: sigfuz Not tainted 5.2.0-11043-g0a8ad0ffa4 #69 NIP: c0000000000022fc LR: 00007fffb2d67e48 CTR: 0000000000000000 REGS: c00000003fffbd70 TRAP: 0700 Not tainted (5.2.0-11045-g7142b497d8) MSR: 8000000102a03031 <SF,VEC,VSX,FP,ME,IR,DR,LE,TM[E]> CR: 42004242 XER: 00000000 CFAR: c0000000000022e0 IRQMASK: 0 GPR00: 0000000000000072 00007fffb2b6e560 00007fffb2d87f00 0000000000000669 GPR04: 00007fffb2b6e728 0000000000000000 0000000000000000 00007fffb2b6f2a8 GPR08: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 GPR12: 0000000000000000 00007fffb2b76900 0000000000000000 0000000000000000 GPR16: 00007fffb2370000 00007fffb2d84390 00007fffea3a15ac 000001000a250420 GPR20: 00007fffb2b6f260 0000000010001770 0000000000000000 0000000000000000 GPR24: 00007fffb2d843a0 00007fffea3a14a0 0000000000010000 0000000000800000 GPR28: 00007fffea3a14d8 00000000003d0f00 0000000000000000 00007fffb2b6e728 NIP [c0000000000022fc] rfi_flush_fallback+0x7c/0x80 LR [00007fffb2d67e48] 0x7fffb2d67e48 Call Trace: Instruction dump: e96a0220 e96a02a8 e96a0330 e96a03b8 394a0400 4200ffdc 7d2903a6 e92d0c00 e94d0c08 e96d0c10 e82d0c18 7db242a6 <4c000024> 7db243a6 7db142a6 f82d0c18
The problem is the signal code assumes TM is enabled when CONFIG_PPC_TRANSACTIONAL_MEM is enabled. This may not be the case as with P9 powernv or if `ppc_tm=off` is used on P8.
This means any local user can crash the system.
Fix the problem by returning a bad stack frame to the user if they try to set the MSR TS bits with sigreturn() on systems where TM is not supported.
Found with sigfuz kernel selftest on P9.
This fixes CVE-2019-13648.
Fixes: 2b0a576d15e0 ("powerpc: Add new transactional memory state to the signal context") Cc: stable@vger.kernel.org # v3.9 Reported-by: Praveen Pandey Praveen.Pandey@in.ibm.com Signed-off-by: Michael Neuling mikey@neuling.org Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20190719050502.405-1-mikey@neuling.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/powerpc/kernel/signal_32.c | 3 +++ arch/powerpc/kernel/signal_64.c | 5 +++++ 2 files changed, 8 insertions(+)
--- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -1198,6 +1198,9 @@ SYSCALL_DEFINE0(rt_sigreturn) goto bad;
if (MSR_TM_ACTIVE(msr_hi<<32)) { + /* Trying to start TM on non TM system */ + if (!cpu_has_feature(CPU_FTR_TM)) + goto bad; /* We only recheckpoint on return if we're * transaction. */ --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -771,6 +771,11 @@ SYSCALL_DEFINE0(rt_sigreturn) if (MSR_TM_ACTIVE(msr)) { /* We recheckpoint on return. */ struct ucontext __user *uc_transact; + + /* Trying to start TM on non TM system */ + if (!cpu_has_feature(CPU_FTR_TM)) + goto badframe; + if (__get_user(uc_transact, &uc->uc_link)) goto badframe; if (restore_tm_sigcontexts(current, &uc->uc_mcontext,
From: Suraj Jitindar Singh sjitindarsingh@gmail.com
commit 28d2a6e6684d9851905f379816d8a4d03587ed94 upstream.
The ability to run nested guests under KVM means that a guest can also act as a hypervisor for it's own nested guest. Currently ppc_set_pmu_inuse() assumes that either FW_FEATURE_LPAR is set, indicating a guest environment, and so sets the pmcregs_in_use flag in the lppaca, or that it isn't set, indicating a hypervisor environment, and so sets the pmcregs_in_use flag in the paca.
The pmcregs_in_use flag in the lppaca is used to communicate this information to a hypervisor and so must be set in a guest environment. The pmcregs_in_use flag in the paca is used by KVM code to determine whether the host state of the performance monitoring unit (PMU) must be saved and restored when running a guest.
Thus when a guest also acts as a hypervisor it must set this bit in both places since it needs to ensure both that the real hypervisor saves it's PMU registers when it runs (requires pmcregs_in_use flag in lppaca), and that it saves it's own PMU registers when running a nested guest (requires pmcregs_in_use flag in paca).
Modify ppc_set_pmu_inuse() so that the pmcregs_in_use bit is set in both the lppaca and the paca when a guest (LPAR) is running with the capability of running it's own guests (CONFIG_KVM_BOOK3S_HV_POSSIBLE).
Fixes: 95a6432ce903 ("KVM: PPC: Book3S HV: Streamlined guest entry/exit path on P9 for radix guests") Cc: stable@vger.kernel.org # v4.20+ Signed-off-by: Suraj Jitindar Singh sjitindarsingh@gmail.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20190703012022.15644-2-sjitindarsingh@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- arch/powerpc/include/asm/pmc.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
--- a/arch/powerpc/include/asm/pmc.h +++ b/arch/powerpc/include/asm/pmc.h @@ -27,11 +27,10 @@ static inline void ppc_set_pmu_inuse(int #ifdef CONFIG_PPC_PSERIES get_lppaca()->pmcregs_in_use = inuse; #endif - } else { + } #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE - get_paca()->pmcregs_in_use = inuse; + get_paca()->pmcregs_in_use = inuse; #endif - } #endif }
From: Zhengyuan Liu liuzhengyuan@kylinos.cn
commit dbd0f6d6c2a11eb9c31ca9cd454f95bb5713e92e upstream.
sq->cached_sq_head and cq->cached_cq_tail are both unsigned int. If cached_sq_head overflows before cached_cq_tail, then we may miss a barrier req. As cached_cq_tail always follows cached_sq_head, the NQ should be enough.
Cc: stable@vger.kernel.org Fixes: de0617e46717 ("io_uring: add support for marking commands as draining") Signed-off-by: Zhengyuan Liu liuzhengyuan@kylinos.cn Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/io_uring.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -425,7 +425,7 @@ static inline bool io_sequence_defer(str if ((req->flags & (REQ_F_IO_DRAIN|REQ_F_IO_DRAINED)) != REQ_F_IO_DRAIN) return false;
- return req->sequence > ctx->cached_cq_tail + ctx->sq_ring->dropped; + return req->sequence != ctx->cached_cq_tail + ctx->sq_ring->dropped; }
static struct io_kiocb *io_get_deferred_req(struct io_ring_ctx *ctx)
From: Dmitry Safonov dima@arista.com
commit effa467870c7612012885df4e246bdb8ffd8e44c upstream.
Intel VT-d driver was reworked to use common deferred flushing implementation. Previously there was one global per-cpu flush queue, afterwards - one per domain.
Before deferring a flush, the queue should be allocated and initialized.
Currently only domains with IOMMU_DOMAIN_DMA type initialize their flush queue. It's probably worth to init it for static or unmanaged domains too, but it may be arguable - I'm leaving it to iommu folks.
Prevent queuing an iova flush if the domain doesn't have a queue. The defensive check seems to be worth to keep even if queue would be initialized for all kinds of domains. And is easy backportable.
On 4.19.43 stable kernel it has a user-visible effect: previously for devices in si domain there were crashes, on sata devices:
BUG: spinlock bad magic on CPU#6, swapper/0/1 lock: 0xffff88844f582008, .magic: 00000000, .owner: <none>/-1, .owner_cpu: 0 CPU: 6 PID: 1 Comm: swapper/0 Not tainted 4.19.43 #1 Call Trace: <IRQ> dump_stack+0x61/0x7e spin_bug+0x9d/0xa3 do_raw_spin_lock+0x22/0x8e _raw_spin_lock_irqsave+0x32/0x3a queue_iova+0x45/0x115 intel_unmap+0x107/0x113 intel_unmap_sg+0x6b/0x76 __ata_qc_complete+0x7f/0x103 ata_qc_complete+0x9b/0x26a ata_qc_complete_multiple+0xd0/0xe3 ahci_handle_port_interrupt+0x3ee/0x48a ahci_handle_port_intr+0x73/0xa9 ahci_single_level_irq_intr+0x40/0x60 __handle_irq_event_percpu+0x7f/0x19a handle_irq_event_percpu+0x32/0x72 handle_irq_event+0x38/0x56 handle_edge_irq+0x102/0x121 handle_irq+0x147/0x15c do_IRQ+0x66/0xf2 common_interrupt+0xf/0xf RIP: 0010:__do_softirq+0x8c/0x2df
The same for usb devices that use ehci-pci: BUG: spinlock bad magic on CPU#0, swapper/0/1 lock: 0xffff88844f402008, .magic: 00000000, .owner: <none>/-1, .owner_cpu: 0 CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.19.43 #4 Call Trace: <IRQ> dump_stack+0x61/0x7e spin_bug+0x9d/0xa3 do_raw_spin_lock+0x22/0x8e _raw_spin_lock_irqsave+0x32/0x3a queue_iova+0x77/0x145 intel_unmap+0x107/0x113 intel_unmap_page+0xe/0x10 usb_hcd_unmap_urb_setup_for_dma+0x53/0x9d usb_hcd_unmap_urb_for_dma+0x17/0x100 unmap_urb_for_dma+0x22/0x24 __usb_hcd_giveback_urb+0x51/0xc3 usb_giveback_urb_bh+0x97/0xde tasklet_action_common.isra.4+0x5f/0xa1 tasklet_action+0x2d/0x30 __do_softirq+0x138/0x2df irq_exit+0x7d/0x8b smp_apic_timer_interrupt+0x10f/0x151 apic_timer_interrupt+0xf/0x20 </IRQ> RIP: 0010:_raw_spin_unlock_irqrestore+0x17/0x39
Cc: David Woodhouse dwmw2@infradead.org Cc: Joerg Roedel joro@8bytes.org Cc: Lu Baolu baolu.lu@linux.intel.com Cc: iommu@lists.linux-foundation.org Cc: stable@vger.kernel.org # 4.14+ Fixes: 13cf01744608 ("iommu/vt-d: Make use of iova deferred flushing") Signed-off-by: Dmitry Safonov dima@arista.com Reviewed-by: Lu Baolu baolu.lu@linux.intel.com Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/iommu/intel-iommu.c | 3 ++- drivers/iommu/iova.c | 18 ++++++++++++++---- include/linux/iova.h | 6 ++++++ 3 files changed, 22 insertions(+), 5 deletions(-)
--- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -3752,7 +3752,8 @@ static void intel_unmap(struct device *d
freelist = domain_unmap(domain, start_pfn, last_pfn);
- if (intel_iommu_strict || (pdev && pdev->untrusted)) { + if (intel_iommu_strict || (pdev && pdev->untrusted) || + !has_iova_flush_queue(&domain->iovad)) { iommu_flush_iotlb_psi(iommu, domain, start_pfn, nrpages, !freelist, 0); /* free iova */ --- a/drivers/iommu/iova.c +++ b/drivers/iommu/iova.c @@ -54,9 +54,14 @@ init_iova_domain(struct iova_domain *iov } EXPORT_SYMBOL_GPL(init_iova_domain);
+bool has_iova_flush_queue(struct iova_domain *iovad) +{ + return !!iovad->fq; +} + static void free_iova_flush_queue(struct iova_domain *iovad) { - if (!iovad->fq) + if (!has_iova_flush_queue(iovad)) return;
if (timer_pending(&iovad->fq_timer)) @@ -74,13 +79,14 @@ static void free_iova_flush_queue(struct int init_iova_flush_queue(struct iova_domain *iovad, iova_flush_cb flush_cb, iova_entry_dtor entry_dtor) { + struct iova_fq __percpu *queue; int cpu;
atomic64_set(&iovad->fq_flush_start_cnt, 0); atomic64_set(&iovad->fq_flush_finish_cnt, 0);
- iovad->fq = alloc_percpu(struct iova_fq); - if (!iovad->fq) + queue = alloc_percpu(struct iova_fq); + if (!queue) return -ENOMEM;
iovad->flush_cb = flush_cb; @@ -89,13 +95,17 @@ int init_iova_flush_queue(struct iova_do for_each_possible_cpu(cpu) { struct iova_fq *fq;
- fq = per_cpu_ptr(iovad->fq, cpu); + fq = per_cpu_ptr(queue, cpu); fq->head = 0; fq->tail = 0;
spin_lock_init(&fq->lock); }
+ smp_wmb(); + + iovad->fq = queue; + timer_setup(&iovad->fq_timer, fq_flush_timeout, 0); atomic_set(&iovad->fq_timer_on, 0);
--- a/include/linux/iova.h +++ b/include/linux/iova.h @@ -155,6 +155,7 @@ struct iova *reserve_iova(struct iova_do void copy_reserved_iova(struct iova_domain *from, struct iova_domain *to); void init_iova_domain(struct iova_domain *iovad, unsigned long granule, unsigned long start_pfn); +bool has_iova_flush_queue(struct iova_domain *iovad); int init_iova_flush_queue(struct iova_domain *iovad, iova_flush_cb flush_cb, iova_entry_dtor entry_dtor); struct iova *find_iova(struct iova_domain *iovad, unsigned long pfn); @@ -235,6 +236,11 @@ static inline void init_iova_domain(stru { }
+bool has_iova_flush_queue(struct iova_domain *iovad) +{ + return false; +} + static inline int init_iova_flush_queue(struct iova_domain *iovad, iova_flush_cb flush_cb, iova_entry_dtor entry_dtor)
From: Chris Wilson chris@chris-wilson.co.uk
commit 9eed17d37c77171cf5ffb95c4257f87df3cd4c8f upstream.
Since the cached32_node is allowed to be advanced above dma_32bit_pfn (to provide a shortcut into the limited range), we need to be careful to remove the to be freed node if it is the cached32_node.
[ 48.477773] BUG: KASAN: use-after-free in __cached_rbnode_delete_update+0x68/0x110 [ 48.477812] Read of size 8 at addr ffff88870fc19020 by task kworker/u8:1/37 [ 48.477843] [ 48.477879] CPU: 1 PID: 37 Comm: kworker/u8:1 Tainted: G U 5.2.0+ #735 [ 48.477915] Hardware name: Intel Corporation NUC7i5BNK/NUC7i5BNB, BIOS BNKBL357.86A.0052.2017.0918.1346 09/18/2017 [ 48.478047] Workqueue: i915 __i915_gem_free_work [i915] [ 48.478075] Call Trace: [ 48.478111] dump_stack+0x5b/0x90 [ 48.478137] print_address_description+0x67/0x237 [ 48.478178] ? __cached_rbnode_delete_update+0x68/0x110 [ 48.478212] __kasan_report.cold.3+0x1c/0x38 [ 48.478240] ? __cached_rbnode_delete_update+0x68/0x110 [ 48.478280] ? __cached_rbnode_delete_update+0x68/0x110 [ 48.478308] __cached_rbnode_delete_update+0x68/0x110 [ 48.478344] private_free_iova+0x2b/0x60 [ 48.478378] iova_magazine_free_pfns+0x46/0xa0 [ 48.478403] free_iova_fast+0x277/0x340 [ 48.478443] fq_ring_free+0x15a/0x1a0 [ 48.478473] queue_iova+0x19c/0x1f0 [ 48.478597] cleanup_page_dma.isra.64+0x62/0xb0 [i915] [ 48.478712] __gen8_ppgtt_cleanup+0x63/0x80 [i915] [ 48.478826] __gen8_ppgtt_cleanup+0x42/0x80 [i915] [ 48.478940] __gen8_ppgtt_clear+0x433/0x4b0 [i915] [ 48.479053] __gen8_ppgtt_clear+0x462/0x4b0 [i915] [ 48.479081] ? __sg_free_table+0x9e/0xf0 [ 48.479116] ? kfree+0x7f/0x150 [ 48.479234] i915_vma_unbind+0x1e2/0x240 [i915] [ 48.479352] i915_vma_destroy+0x3a/0x280 [i915] [ 48.479465] __i915_gem_free_objects+0xf0/0x2d0 [i915] [ 48.479579] __i915_gem_free_work+0x41/0xa0 [i915] [ 48.479607] process_one_work+0x495/0x710 [ 48.479642] worker_thread+0x4c7/0x6f0 [ 48.479687] ? process_one_work+0x710/0x710 [ 48.479724] kthread+0x1b2/0x1d0 [ 48.479774] ? kthread_create_worker_on_cpu+0xa0/0xa0 [ 48.479820] ret_from_fork+0x1f/0x30 [ 48.479864] [ 48.479907] Allocated by task 631: [ 48.479944] save_stack+0x19/0x80 [ 48.479994] __kasan_kmalloc.constprop.6+0xc1/0xd0 [ 48.480038] kmem_cache_alloc+0x91/0xf0 [ 48.480082] alloc_iova+0x2b/0x1e0 [ 48.480125] alloc_iova_fast+0x58/0x376 [ 48.480166] intel_alloc_iova+0x90/0xc0 [ 48.480214] intel_map_sg+0xde/0x1f0 [ 48.480343] i915_gem_gtt_prepare_pages+0xb8/0x170 [i915] [ 48.480465] huge_get_pages+0x232/0x2b0 [i915] [ 48.480590] ____i915_gem_object_get_pages+0x40/0xb0 [i915] [ 48.480712] __i915_gem_object_get_pages+0x90/0xa0 [i915] [ 48.480834] i915_gem_object_prepare_write+0x2d6/0x330 [i915] [ 48.480955] create_test_object.isra.54+0x1a9/0x3e0 [i915] [ 48.481075] igt_shared_ctx_exec+0x365/0x3c0 [i915] [ 48.481210] __i915_subtests.cold.4+0x30/0x92 [i915] [ 48.481341] __run_selftests.cold.3+0xa9/0x119 [i915] [ 48.481466] i915_live_selftests+0x3c/0x70 [i915] [ 48.481583] i915_pci_probe+0xe7/0x220 [i915] [ 48.481620] pci_device_probe+0xe0/0x180 [ 48.481665] really_probe+0x163/0x4e0 [ 48.481710] device_driver_attach+0x85/0x90 [ 48.481750] __driver_attach+0xa5/0x180 [ 48.481796] bus_for_each_dev+0xda/0x130 [ 48.481831] bus_add_driver+0x205/0x2e0 [ 48.481882] driver_register+0xca/0x140 [ 48.481927] do_one_initcall+0x6c/0x1af [ 48.481970] do_init_module+0x106/0x350 [ 48.482010] load_module+0x3d2c/0x3ea0 [ 48.482058] __do_sys_finit_module+0x110/0x180 [ 48.482102] do_syscall_64+0x62/0x1f0 [ 48.482147] entry_SYSCALL_64_after_hwframe+0x44/0xa9 [ 48.482190] [ 48.482224] Freed by task 37: [ 48.482273] save_stack+0x19/0x80 [ 48.482318] __kasan_slab_free+0x12e/0x180 [ 48.482363] kmem_cache_free+0x70/0x140 [ 48.482406] __free_iova+0x1d/0x30 [ 48.482445] fq_ring_free+0x15a/0x1a0 [ 48.482490] queue_iova+0x19c/0x1f0 [ 48.482624] cleanup_page_dma.isra.64+0x62/0xb0 [i915] [ 48.482749] __gen8_ppgtt_cleanup+0x63/0x80 [i915] [ 48.482873] __gen8_ppgtt_cleanup+0x42/0x80 [i915] [ 48.482999] __gen8_ppgtt_clear+0x433/0x4b0 [i915] [ 48.483123] __gen8_ppgtt_clear+0x462/0x4b0 [i915] [ 48.483250] i915_vma_unbind+0x1e2/0x240 [i915] [ 48.483378] i915_vma_destroy+0x3a/0x280 [i915] [ 48.483500] __i915_gem_free_objects+0xf0/0x2d0 [i915] [ 48.483622] __i915_gem_free_work+0x41/0xa0 [i915] [ 48.483659] process_one_work+0x495/0x710 [ 48.483704] worker_thread+0x4c7/0x6f0 [ 48.483748] kthread+0x1b2/0x1d0 [ 48.483787] ret_from_fork+0x1f/0x30 [ 48.483831] [ 48.483868] The buggy address belongs to the object at ffff88870fc19000 [ 48.483868] which belongs to the cache iommu_iova of size 40 [ 48.483920] The buggy address is located 32 bytes inside of [ 48.483920] 40-byte region [ffff88870fc19000, ffff88870fc19028) [ 48.483964] The buggy address belongs to the page: [ 48.484006] page:ffffea001c3f0600 refcount:1 mapcount:0 mapping:ffff8888181a91c0 index:0x0 compound_mapcount: 0 [ 48.484045] flags: 0x8000000000010200(slab|head) [ 48.484096] raw: 8000000000010200 ffffea001c421a08 ffffea001c447e88 ffff8888181a91c0 [ 48.484141] raw: 0000000000000000 0000000000120012 00000001ffffffff 0000000000000000 [ 48.484188] page dumped because: kasan: bad access detected [ 48.484230] [ 48.484265] Memory state around the buggy address: [ 48.484314] ffff88870fc18f00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 48.484361] ffff88870fc18f80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 48.484406] >ffff88870fc19000: fb fb fb fb fb fc fc fc fc fc fc fc fc fc fc fc [ 48.484451] ^ [ 48.484494] ffff88870fc19080: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 48.484530] ffff88870fc19100: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=108602 Fixes: e60aa7b53845 ("iommu/iova: Extend rbtree node caching") Signed-off-by: Chris Wilson chris@chris-wilson.co.uk Cc: Robin Murphy robin.murphy@arm.com Cc: Joerg Roedel jroedel@suse.de Cc: Joerg Roedel joro@8bytes.org Cc: stable@vger.kernel.org # v4.15+ Reviewed-by: Robin Murphy robin.murphy@arm.com Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/iommu/iova.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
--- a/drivers/iommu/iova.c +++ b/drivers/iommu/iova.c @@ -137,8 +137,9 @@ __cached_rbnode_delete_update(struct iov struct iova *cached_iova;
cached_iova = rb_entry(iovad->cached32_node, struct iova, node); - if (free->pfn_hi < iovad->dma_32bit_pfn && - free->pfn_lo >= cached_iova->pfn_lo) { + if (free == cached_iova || + (free->pfn_hi < iovad->dma_32bit_pfn && + free->pfn_lo >= cached_iova->pfn_lo)) { iovad->cached32_node = rb_next(&free->node); iovad->max32_alloc_size = iovad->dma_32bit_pfn; }
From: Joerg Roedel jroedel@suse.de
commit 201c1db90cd643282185a00770f12f95da330eca upstream.
The stub function for !CONFIG_IOMMU_IOVA needs to be 'static inline'.
Fixes: effa467870c76 ('iommu/vt-d: Don't queue_iova() if there is no flush queue') Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- include/linux/iova.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/include/linux/iova.h +++ b/include/linux/iova.h @@ -236,7 +236,7 @@ static inline void init_iova_domain(stru { }
-bool has_iova_flush_queue(struct iova_domain *iovad) +static inline bool has_iova_flush_queue(struct iova_domain *iovad) { return false; }
From: Dan Williams dan.j.williams@intel.com
commit 00289cd87676e14913d2d8492d1ce05c4baafdae upstream.
The libnvdimm subsystem arranges for devices to be destroyed as a result of a sysfs operation. Since device_unregister() cannot be called from an actively running sysfs attribute of the same device libnvdimm arranges for device_unregister() to be performed in an out-of-line async context.
The driver core maintains a 'dead' state for coordinating its own racing async registration / de-registration requests. Rather than add local 'dead' state tracking infrastructure to libnvdimm device objects, export the existing state tracking via a new kill_device() helper.
The kill_device() helper simply marks the device as dead, i.e. that it is on its way to device_del(), or returns that the device was already dead. This can be used in advance of calling device_unregister() for subsystems like libnvdimm that might need to handle multiple user threads racing to delete a device.
This refactoring does not change any behavior, but it is a pre-requisite for follow-on fixes and therefore marked for -stable.
Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: "Rafael J. Wysocki" rafael@kernel.org Fixes: 4d88a97aa9e8 ("libnvdimm, nvdimm: dimm driver and base libnvdimm device-driver...") Cc: stable@vger.kernel.org Tested-by: Jane Chu jane.chu@oracle.com Reviewed-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Link: https://lore.kernel.org/r/156341207332.292348.14959761496009347574.stgit@dwi... Signed-off-by: Dan Williams dan.j.williams@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/base/core.c | 27 +++++++++++++++++++-------- include/linux/device.h | 1 + 2 files changed, 20 insertions(+), 8 deletions(-)
--- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -2211,6 +2211,24 @@ void put_device(struct device *dev) } EXPORT_SYMBOL_GPL(put_device);
+bool kill_device(struct device *dev) +{ + /* + * Require the device lock and set the "dead" flag to guarantee that + * the update behavior is consistent with the other bitfields near + * it and that we cannot have an asynchronous probe routine trying + * to run while we are tearing out the bus/class/sysfs from + * underneath the device. + */ + lockdep_assert_held(&dev->mutex); + + if (dev->p->dead) + return false; + dev->p->dead = true; + return true; +} +EXPORT_SYMBOL_GPL(kill_device); + /** * device_del - delete device from system. * @dev: device. @@ -2230,15 +2248,8 @@ void device_del(struct device *dev) struct kobject *glue_dir = NULL; struct class_interface *class_intf;
- /* - * Hold the device lock and set the "dead" flag to guarantee that - * the update behavior is consistent with the other bitfields near - * it and that we cannot have an asynchronous probe routine trying - * to run while we are tearing out the bus/class/sysfs from - * underneath the device. - */ device_lock(dev); - dev->p->dead = true; + kill_device(dev); device_unlock(dev);
/* Notify clients of device removal. This call must come --- a/include/linux/device.h +++ b/include/linux/device.h @@ -1375,6 +1375,7 @@ extern int (*platform_notify_remove)(str */ extern struct device *get_device(struct device *dev); extern void put_device(struct device *dev); +extern bool kill_device(struct device *dev);
#ifdef CONFIG_DEVTMPFS extern int devtmpfs_create_node(struct device *dev);
From: Dan Williams dan.j.williams@intel.com
commit 8aac0e2338916e273ccbd438a2b7a1e8c61749f5 upstream.
A multithreaded namespace creation/destruction stress test currently fails with signatures like the following:
sysfs group 'power' not found for kobject 'dax1.1' RIP: 0010:sysfs_remove_group+0x76/0x80 Call Trace: device_del+0x73/0x370 device_unregister+0x16/0x50 nd_async_device_unregister+0x1e/0x30 [libnvdimm] async_run_entry_fn+0x39/0x160 process_one_work+0x23c/0x5e0 worker_thread+0x3c/0x390
BUG: kernel NULL pointer dereference, address: 0000000000000020 RIP: 0010:klist_put+0x1b/0x6c Call Trace: klist_del+0xe/0x10 device_del+0x8a/0x2c9 ? __switch_to_asm+0x34/0x70 ? __switch_to_asm+0x40/0x70 device_unregister+0x44/0x4f nd_async_device_unregister+0x22/0x2d [libnvdimm] async_run_entry_fn+0x47/0x15a process_one_work+0x1a2/0x2eb worker_thread+0x1b8/0x26e
Use the kill_device() helper to atomically resolve the race of multiple threads issuing kill, device_unregister(), requests.
Reported-by: Jane Chu jane.chu@oracle.com Reported-by: Erwin Tsaur erwin.tsaur@oracle.com Fixes: 4d88a97aa9e8 ("libnvdimm, nvdimm: dimm driver and base libnvdimm device-driver...") Cc: stable@vger.kernel.org Link: https://github.com/pmem/ndctl/issues/96 Tested-by: Tested-by: Jane Chu jane.chu@oracle.com Link: https://lore.kernel.org/r/156341207846.292348.10435719262819764054.stgit@dwi... Signed-off-by: Dan Williams dan.j.williams@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/nvdimm/bus.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+)
--- a/drivers/nvdimm/bus.c +++ b/drivers/nvdimm/bus.c @@ -547,13 +547,38 @@ EXPORT_SYMBOL(nd_device_register);
void nd_device_unregister(struct device *dev, enum nd_async_mode mode) { + bool killed; + switch (mode) { case ND_ASYNC: + /* + * In the async case this is being triggered with the + * device lock held and the unregistration work needs to + * be moved out of line iff this is thread has won the + * race to schedule the deletion. + */ + if (!kill_device(dev)) + return; + get_device(dev); async_schedule_domain(nd_async_device_unregister, dev, &nd_async_domain); break; case ND_SYNC: + /* + * In the sync case the device is being unregistered due + * to a state change of the parent. Claim the kill state + * to synchronize against other unregistration requests, + * or otherwise let the async path handle it if the + * unregistration was already queued. + */ + device_lock(dev); + killed = kill_device(dev); + device_unlock(dev); + + if (!killed) + return; + nd_synchronize(); device_unregister(dev); break;
From: Dan Williams dan.j.williams@intel.com
commit 700cd033a82d466ad8f9615f9985525e45f8960a upstream.
Namespace activation expects to be able to reference region badblocks. The following warning sometimes triggers when asynchronous namespace activation races in front of the completion of namespace probing. Move all possible namespace probing after region badblocks initialization.
Otherwise, lockdep sometimes catches the uninitialized state of the badblocks seqlock with stack trace signatures like:
INFO: trying to register non-static key. pmem2: detected capacity change from 0 to 136365211648 the code is fine but needs lockdep annotation. turning off the locking correctness validator. CPU: 9 PID: 358 Comm: kworker/u80:5 Tainted: G OE 5.2.0-rc4+ #3382 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 0.0.0 02/06/2015 Workqueue: events_unbound async_run_entry_fn Call Trace: dump_stack+0x85/0xc0 pmem1.12: detected capacity change from 0 to 8589934592 register_lock_class+0x56a/0x570 ? check_object+0x140/0x270 __lock_acquire+0x80/0x1710 ? __mutex_lock+0x39d/0x910 lock_acquire+0x9e/0x180 ? nd_pfn_validate+0x28f/0x440 [libnvdimm] badblocks_check+0x93/0x1f0 ? nd_pfn_validate+0x28f/0x440 [libnvdimm] nd_pfn_validate+0x28f/0x440 [libnvdimm] ? lockdep_hardirqs_on+0xf0/0x180 nd_dax_probe+0x9a/0x120 [libnvdimm] nd_pmem_probe+0x6d/0x180 [nd_pmem] nvdimm_bus_probe+0x90/0x2c0 [libnvdimm]
Fixes: 48af2f7e52f4 ("libnvdimm, pfn: during init, clear errors...") Cc: stable@vger.kernel.org Cc: Vishal Verma vishal.l.verma@intel.com Reviewed-by: Vishal Verma vishal.l.verma@intel.com Link: https://lore.kernel.org/r/156341208365.292348.1547528796026249120.stgit@dwil... Signed-off-by: Dan Williams dan.j.williams@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/nvdimm/region.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-)
--- a/drivers/nvdimm/region.c +++ b/drivers/nvdimm/region.c @@ -34,17 +34,6 @@ static int nd_region_probe(struct device if (rc) return rc;
- rc = nd_region_register_namespaces(nd_region, &err); - if (rc < 0) - return rc; - - ndrd = dev_get_drvdata(dev); - ndrd->ns_active = rc; - ndrd->ns_count = rc + err; - - if (rc && err && rc == err) - return -ENODEV; - if (is_nd_pmem(&nd_region->dev)) { struct resource ndr_res;
@@ -60,6 +49,17 @@ static int nd_region_probe(struct device nvdimm_badblocks_populate(nd_region, &nd_region->bb, &ndr_res); }
+ rc = nd_region_register_namespaces(nd_region, &err); + if (rc < 0) + return rc; + + ndrd = dev_get_drvdata(dev); + ndrd->ns_active = rc; + ndrd->ns_count = rc + err; + + if (rc && err && rc == err) + return -ENODEV; + nd_region->btt_seed = nd_btt_create(nd_region); nd_region->pfn_seed = nd_pfn_create(nd_region); nd_region->dax_seed = nd_dax_create(nd_region);
From: Dan Williams dan.j.williams@intel.com
commit b70d31d054ee3a6fc1034b9d7fc0ae1e481aa018 upstream.
In preparation for fixing a deadlock between wait_for_bus_probe_idle() and the nvdimm_bus_list_mutex arrange for __nd_ioctl() without nvdimm_bus_list_mutex held. This also unifies the 'dimm' and 'bus' level ioctls into a common nd_ioctl() preamble implementation.
Marked for -stable as it is a pre-requisite for a follow-on fix.
Cc: stable@vger.kernel.org Fixes: bf9bccc14c05 ("libnvdimm: pmem label sets and namespace instantiation") Cc: Vishal Verma vishal.l.verma@intel.com Tested-by: Jane Chu jane.chu@oracle.com Link: https://lore.kernel.org/r/156341209518.292348.7183897251740665198.stgit@dwil... Signed-off-by: Dan Williams dan.j.williams@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- drivers/nvdimm/bus.c | 94 ++++++++++++++++++++++++++++------------------- drivers/nvdimm/nd-core.h | 3 + 2 files changed, 59 insertions(+), 38 deletions(-)
--- a/drivers/nvdimm/bus.c +++ b/drivers/nvdimm/bus.c @@ -73,7 +73,7 @@ static void nvdimm_bus_probe_end(struct { nvdimm_bus_lock(&nvdimm_bus->dev); if (--nvdimm_bus->probe_active == 0) - wake_up(&nvdimm_bus->probe_wait); + wake_up(&nvdimm_bus->wait); nvdimm_bus_unlock(&nvdimm_bus->dev); }
@@ -341,7 +341,7 @@ struct nvdimm_bus *nvdimm_bus_register(s return NULL; INIT_LIST_HEAD(&nvdimm_bus->list); INIT_LIST_HEAD(&nvdimm_bus->mapping_list); - init_waitqueue_head(&nvdimm_bus->probe_wait); + init_waitqueue_head(&nvdimm_bus->wait); nvdimm_bus->id = ida_simple_get(&nd_ida, 0, 0, GFP_KERNEL); if (nvdimm_bus->id < 0) { kfree(nvdimm_bus); @@ -426,6 +426,9 @@ static int nd_bus_remove(struct device * list_del_init(&nvdimm_bus->list); mutex_unlock(&nvdimm_bus_list_mutex);
+ wait_event(nvdimm_bus->wait, + atomic_read(&nvdimm_bus->ioctl_active) == 0); + nd_synchronize(); device_for_each_child(&nvdimm_bus->dev, NULL, child_unregister);
@@ -885,7 +888,7 @@ void wait_nvdimm_bus_probe_idle(struct d if (nvdimm_bus->probe_active == 0) break; nvdimm_bus_unlock(&nvdimm_bus->dev); - wait_event(nvdimm_bus->probe_wait, + wait_event(nvdimm_bus->wait, nvdimm_bus->probe_active == 0); nvdimm_bus_lock(&nvdimm_bus->dev); } while (true); @@ -1115,24 +1118,10 @@ static int __nd_ioctl(struct nvdimm_bus return rc; }
-static long nd_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - long id = (long) file->private_data; - int rc = -ENXIO, ro; - struct nvdimm_bus *nvdimm_bus; - - ro = ((file->f_flags & O_ACCMODE) == O_RDONLY); - mutex_lock(&nvdimm_bus_list_mutex); - list_for_each_entry(nvdimm_bus, &nvdimm_bus_list, list) { - if (nvdimm_bus->id == id) { - rc = __nd_ioctl(nvdimm_bus, NULL, ro, cmd, arg); - break; - } - } - mutex_unlock(&nvdimm_bus_list_mutex); - - return rc; -} +enum nd_ioctl_mode { + BUS_IOCTL, + DIMM_IOCTL, +};
static int match_dimm(struct device *dev, void *data) { @@ -1147,31 +1136,62 @@ static int match_dimm(struct device *dev return 0; }
-static long nvdimm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +static long nd_ioctl(struct file *file, unsigned int cmd, unsigned long arg, + enum nd_ioctl_mode mode) + { - int rc = -ENXIO, ro; - struct nvdimm_bus *nvdimm_bus; + struct nvdimm_bus *nvdimm_bus, *found = NULL; + long id = (long) file->private_data; + struct nvdimm *nvdimm = NULL; + int rc, ro;
ro = ((file->f_flags & O_ACCMODE) == O_RDONLY); mutex_lock(&nvdimm_bus_list_mutex); list_for_each_entry(nvdimm_bus, &nvdimm_bus_list, list) { - struct device *dev = device_find_child(&nvdimm_bus->dev, - file->private_data, match_dimm); - struct nvdimm *nvdimm; + if (mode == DIMM_IOCTL) { + struct device *dev;
- if (!dev) - continue; + dev = device_find_child(&nvdimm_bus->dev, + file->private_data, match_dimm); + if (!dev) + continue; + nvdimm = to_nvdimm(dev); + found = nvdimm_bus; + } else if (nvdimm_bus->id == id) { + found = nvdimm_bus; + }
- nvdimm = to_nvdimm(dev); - rc = __nd_ioctl(nvdimm_bus, nvdimm, ro, cmd, arg); - put_device(dev); - break; + if (found) { + atomic_inc(&nvdimm_bus->ioctl_active); + break; + } } mutex_unlock(&nvdimm_bus_list_mutex);
+ if (!found) + return -ENXIO; + + nvdimm_bus = found; + rc = __nd_ioctl(nvdimm_bus, nvdimm, ro, cmd, arg); + + if (nvdimm) + put_device(&nvdimm->dev); + if (atomic_dec_and_test(&nvdimm_bus->ioctl_active)) + wake_up(&nvdimm_bus->wait); + return rc; }
+static long bus_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + return nd_ioctl(file, cmd, arg, BUS_IOCTL); +} + +static long dimm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + return nd_ioctl(file, cmd, arg, DIMM_IOCTL); +} + static int nd_open(struct inode *inode, struct file *file) { long minor = iminor(inode); @@ -1183,16 +1203,16 @@ static int nd_open(struct inode *inode, static const struct file_operations nvdimm_bus_fops = { .owner = THIS_MODULE, .open = nd_open, - .unlocked_ioctl = nd_ioctl, - .compat_ioctl = nd_ioctl, + .unlocked_ioctl = bus_ioctl, + .compat_ioctl = bus_ioctl, .llseek = noop_llseek, };
static const struct file_operations nvdimm_fops = { .owner = THIS_MODULE, .open = nd_open, - .unlocked_ioctl = nvdimm_ioctl, - .compat_ioctl = nvdimm_ioctl, + .unlocked_ioctl = dimm_ioctl, + .compat_ioctl = dimm_ioctl, .llseek = noop_llseek, };
--- a/drivers/nvdimm/nd-core.h +++ b/drivers/nvdimm/nd-core.h @@ -17,10 +17,11 @@ extern struct workqueue_struct *nvdimm_w
struct nvdimm_bus { struct nvdimm_bus_descriptor *nd_desc; - wait_queue_head_t probe_wait; + wait_queue_head_t wait; struct list_head list; struct device dev; int id, probe_active; + atomic_t ioctl_active; struct list_head mapping_list; struct mutex reconfig_mutex; struct badrange badrange;
From: Arnd Bergmann arnd@arndb.de
commit 173e6ee21e2b3f477f07548a79c43b8d9cfbb37d upstream.
The combination of KASAN_STACK and GCC_PLUGIN_STRUCTLEAK_BYREF leads to much larger kernel stack usage, as seen from the warnings about functions that now exceed the 2048 byte limit:
drivers/media/i2c/tvp5150.c:253:1: error: the frame size of 3936 bytes is larger than 2048 bytes drivers/media/tuners/r820t.c:1327:1: error: the frame size of 2816 bytes is larger than 2048 bytes drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c:16552:1: error: the frame size of 3144 bytes is larger than 2048 bytes [-Werror=frame-larger-than=] fs/ocfs2/aops.c:1892:1: error: the frame size of 2088 bytes is larger than 2048 bytes fs/ocfs2/dlm/dlmrecovery.c:737:1: error: the frame size of 2088 bytes is larger than 2048 bytes fs/ocfs2/namei.c:1677:1: error: the frame size of 2584 bytes is larger than 2048 bytes fs/ocfs2/super.c:1186:1: error: the frame size of 2640 bytes is larger than 2048 bytes fs/ocfs2/xattr.c:3678:1: error: the frame size of 2176 bytes is larger than 2048 bytes net/bluetooth/l2cap_core.c:7056:1: error: the frame size of 2144 bytes is larger than 2048 bytes [-Werror=frame-larger-than=] net/bluetooth/l2cap_core.c: In function 'l2cap_recv_frame': net/bridge/br_netlink.c:1505:1: error: the frame size of 2448 bytes is larger than 2048 bytes net/ieee802154/nl802154.c:548:1: error: the frame size of 2232 bytes is larger than 2048 bytes net/wireless/nl80211.c:1726:1: error: the frame size of 2224 bytes is larger than 2048 bytes net/wireless/nl80211.c:2357:1: error: the frame size of 4584 bytes is larger than 2048 bytes net/wireless/nl80211.c:5108:1: error: the frame size of 2760 bytes is larger than 2048 bytes net/wireless/nl80211.c:6472:1: error: the frame size of 2112 bytes is larger than 2048 bytes
The structleak plugin was previously disabled for CONFIG_COMPILE_TEST, but meant we missed some bugs, so this time we should address them.
The frame size warnings are distracting, and risking a kernel stack overflow is generally not beneficial to performance, so it may be best to disallow that particular combination. This can be done by turning off either one. I picked the dependency in GCC_PLUGIN_STRUCTLEAK_BYREF and GCC_PLUGIN_STRUCTLEAK_BYREF_ALL, as this option is designed to make uninitialized stack usage less harmful when enabled on its own, but it also prevents KASAN from detecting those cases in which it was in fact needed.
KASAN_STACK is currently implied by KASAN on gcc, but could be made a user selectable option if we want to allow combining (non-stack) KASAN with GCC_PLUGIN_STRUCTLEAK_BYREF.
Note that it would be possible to specifically address the files that print the warning, but presumably the overall stack usage is still significantly higher than in other configurations, so this would not address the full problem.
I could not test this with CONFIG_INIT_STACK_ALL, which may or may not suffer from a similar problem.
Fixes: 81a56f6dcd20 ("gcc-plugins: structleak: Generalize to all variable types") Signed-off-by: Arnd Bergmann arnd@arndb.de Link: https://lore.kernel.org/r/20190722114134.3123901-1-arnd@arndb.de Signed-off-by: Kees Cook keescook@chromium.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- security/Kconfig.hardening | 7 +++++++ 1 file changed, 7 insertions(+)
--- a/security/Kconfig.hardening +++ b/security/Kconfig.hardening @@ -61,6 +61,7 @@ choice config GCC_PLUGIN_STRUCTLEAK_BYREF bool "zero-init structs passed by reference (strong)" depends on GCC_PLUGINS + depends on !(KASAN && KASAN_STACK=1) select GCC_PLUGIN_STRUCTLEAK help Zero-initialize any structures on the stack that may @@ -70,9 +71,15 @@ choice exposures, like CVE-2017-1000410: https://git.kernel.org/linus/06e7e776ca4d3654
+ As a side-effect, this keeps a lot of variables on the + stack that can otherwise be optimized out, so combining + this with CONFIG_KASAN_STACK can lead to a stack overflow + and is disallowed. + config GCC_PLUGIN_STRUCTLEAK_BYREF_ALL bool "zero-init anything passed by reference (very strong)" depends on GCC_PLUGINS + depends on !(KASAN && KASAN_STACK=1) select GCC_PLUGIN_STRUCTLEAK help Zero-initialize any stack variables that may be passed
From: Chris Wilson chris@chris-wilson.co.uk
commit 44d89409a12eb8333735958509d7d591b461d13d upstream.
The idea behind keeping the saturation mask local to a context backfired spectacularly. The premise with the local mask was that we would be more proactive in attempting to use semaphores after each time the context idled, and that all new contexts would attempt to use semaphores ignoring the current state of the system. This turns out to be horribly optimistic. If the system state is still oversaturated and the existing workloads have all stopped using semaphores, the new workloads would attempt to use semaphores and be deprioritised behind real work. The new contexts would not switch off using semaphores until their initial batch of low priority work had completed. Given sufficient backload load of equal user priority, this would completely starve the new work of any GPU time.
To compensate, remove the local tracking in favour of keeping it as global state on the engine -- once the system is saturated and semaphores are disabled, everyone stops attempting to use semaphores until the system is idle again. One of the reason for preferring local context tracking was that it worked with virtual engines, so for switching to global state we could either do a complete check of all the virtual siblings or simply disable semaphores for those requests. This takes the simpler approach of disabling semaphores on virtual engines.
The downside is that the decision that the engine is saturated is a local measure -- we are only checking whether or not this context was scheduled in a timely fashion, it may be legitimately delayed due to user priorities. We still have the same dilemma though, that we do not want to employ the semaphore poll unless it will be used.
v2: Explain why we need to assume the worst wrt virtual engines.
Fixes: ca6e56f654e7 ("drm/i915: Disable semaphore busywaits on saturated systems") Signed-off-by: Chris Wilson chris@chris-wilson.co.uk Cc: Tvrtko Ursulin tvrtko.ursulin@intel.com Cc: Dmitry Rogozhkin dmitry.v.rogozhkin@intel.com Cc: Dmitry Ermilov dmitry.ermilov@intel.com Reviewed-by: Tvrtko Ursulin tvrtko.ursulin@intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20190618074153.16055-8-chris@c... Signed-off-by: Joonas Lahtinen joonas.lahtinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/i915/i915_request.c | 4 ++-- drivers/gpu/drm/i915/intel_context.c | 1 - drivers/gpu/drm/i915/intel_context_types.h | 2 -- drivers/gpu/drm/i915/intel_engine_cs.c | 1 + drivers/gpu/drm/i915/intel_engine_types.h | 2 ++ 5 files changed, 5 insertions(+), 5 deletions(-)
--- a/drivers/gpu/drm/i915/i915_request.c +++ b/drivers/gpu/drm/i915/i915_request.c @@ -443,7 +443,7 @@ void __i915_request_submit(struct i915_r */ if (request->sched.semaphores && i915_sw_fence_signaled(&request->semaphore)) - request->hw_context->saturated |= request->sched.semaphores; + engine->saturated |= request->sched.semaphores;
/* We may be recursing from the signal callback of another i915 fence */ spin_lock_nested(&request->lock, SINGLE_DEPTH_NESTING); @@ -829,7 +829,7 @@ already_busywaiting(struct i915_request * * See the are-we-too-late? check in __i915_request_submit(). */ - return rq->sched.semaphores | rq->hw_context->saturated; + return rq->sched.semaphores | rq->engine->saturated; }
static int --- a/drivers/gpu/drm/i915/intel_context.c +++ b/drivers/gpu/drm/i915/intel_context.c @@ -230,7 +230,6 @@ intel_context_init(struct intel_context ce->gem_context = ctx; ce->engine = engine; ce->ops = engine->cops; - ce->saturated = 0;
INIT_LIST_HEAD(&ce->signal_link); INIT_LIST_HEAD(&ce->signals); --- a/drivers/gpu/drm/i915/intel_context_types.h +++ b/drivers/gpu/drm/i915/intel_context_types.h @@ -59,8 +59,6 @@ struct intel_context { atomic_t pin_count; struct mutex pin_mutex; /* guards pinning and associated on-gpuing */
- intel_engine_mask_t saturated; /* submitting semaphores too late? */ - /** * active_tracker: Active tracker for the external rq activity * on this intel_context object. --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c @@ -1200,6 +1200,7 @@ void intel_engines_park(struct drm_i915_
i915_gem_batch_pool_fini(&engine->batch_pool); engine->execlists.no_priolist = false; + engine->saturated = 0; }
i915->gt.active_engines = 0; --- a/drivers/gpu/drm/i915/intel_engine_types.h +++ b/drivers/gpu/drm/i915/intel_engine_types.h @@ -285,6 +285,8 @@ struct intel_engine_cs { struct intel_context *kernel_context; /* pinned */ struct intel_context *preempt_context; /* pinned; optional */
+ intel_engine_mask_t saturated; /* submitting semaphores too late? */ + struct drm_i915_gem_object *default_state; void *pinned_default_state;
From: Linus Torvalds torvalds@linux-foundation.org
commit d7852fbd0f0423937fa287a598bfde188bb68c22 upstream.
It turns out that 'access()' (and 'faccessat()') can cause a lot of RCU work because it installs a temporary credential that gets allocated and freed for each system call.
The allocation and freeing overhead is mostly benign, but because credentials can be accessed under the RCU read lock, the freeing involves a RCU grace period.
Which is not a huge deal normally, but if you have a lot of access() calls, this causes a fair amount of seconday damage: instead of having a nice alloc/free patterns that hits in hot per-CPU slab caches, you have all those delayed free's, and on big machines with hundreds of cores, the RCU overhead can end up being enormous.
But it turns out that all of this is entirely unnecessary. Exactly because access() only installs the credential as the thread-local subjective credential, the temporary cred pointer doesn't actually need to be RCU free'd at all. Once we're done using it, we can just free it synchronously and avoid all the RCU overhead.
So add a 'non_rcu' flag to 'struct cred', which can be set by users that know they only use it in non-RCU context (there are other potential users for this). We can make it a union with the rcu freeing list head that we need for the RCU case, so this doesn't need any extra storage.
Note that this also makes 'get_current_cred()' clear the new non_rcu flag, in case we have filesystems that take a long-term reference to the cred and then expect the RCU delayed freeing afterwards. It's not entirely clear that this is required, but it makes for clear semantics: the subjective cred remains non-RCU as long as you only access it synchronously using the thread-local accessors, but you _can_ use it as a generic cred if you want to.
It is possible that we should just remove the whole RCU markings for ->cred entirely. Only ->real_cred is really supposed to be accessed through RCU, and the long-term cred copies that nfs uses might want to explicitly re-enable RCU freeing if required, rather than have get_current_cred() do it implicitly.
But this is a "minimal semantic changes" change for the immediate problem.
Acked-by: Peter Zijlstra (Intel) peterz@infradead.org Acked-by: Eric Dumazet edumazet@google.com Acked-by: Paul E. McKenney paulmck@linux.ibm.com Cc: Oleg Nesterov oleg@redhat.com Cc: Jan Glauber jglauber@marvell.com Cc: Jiri Kosina jikos@kernel.org Cc: Jayachandran Chandrasekharan Nair jnair@marvell.com Cc: Greg KH greg@kroah.com Cc: Kees Cook keescook@chromium.org Cc: David Howells dhowells@redhat.com Cc: Miklos Szeredi miklos@szeredi.hu Cc: Al Viro viro@zeniv.linux.org.uk Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/open.c | 19 +++++++++++++++++++ include/linux/cred.h | 8 +++++++- kernel/cred.c | 21 +++++++++++++++++++-- 3 files changed, 45 insertions(+), 3 deletions(-)
--- a/fs/open.c +++ b/fs/open.c @@ -374,6 +374,25 @@ long do_faccessat(int dfd, const char __ override_cred->cap_permitted; }
+ /* + * The new set of credentials can *only* be used in + * task-synchronous circumstances, and does not need + * RCU freeing, unless somebody then takes a separate + * reference to it. + * + * NOTE! This is _only_ true because this credential + * is used purely for override_creds() that installs + * it as the subjective cred. Other threads will be + * accessing ->real_cred, not the subjective cred. + * + * If somebody _does_ make a copy of this (using the + * 'get_current_cred()' function), that will clear the + * non_rcu field, because now that other user may be + * expecting RCU freeing. But normal thread-synchronous + * cred accesses will keep things non-RCY. + */ + override_cred->non_rcu = 1; + old_cred = override_creds(override_cred); retry: res = user_path_at(dfd, filename, lookup_flags, &path); --- a/include/linux/cred.h +++ b/include/linux/cred.h @@ -145,7 +145,11 @@ struct cred { struct user_struct *user; /* real user ID subscription */ struct user_namespace *user_ns; /* user_ns the caps and keyrings are relative to. */ struct group_info *group_info; /* supplementary groups for euid/fsgid */ - struct rcu_head rcu; /* RCU deletion hook */ + /* RCU deletion */ + union { + int non_rcu; /* Can we skip RCU deletion? */ + struct rcu_head rcu; /* RCU deletion hook */ + }; } __randomize_layout;
extern void __put_cred(struct cred *); @@ -246,6 +250,7 @@ static inline const struct cred *get_cre if (!cred) return cred; validate_creds(cred); + nonconst_cred->non_rcu = 0; return get_new_cred(nonconst_cred); }
@@ -257,6 +262,7 @@ static inline const struct cred *get_cre if (!atomic_inc_not_zero(&nonconst_cred->usage)) return NULL; validate_creds(cred); + nonconst_cred->non_rcu = 0; return cred; }
--- a/kernel/cred.c +++ b/kernel/cred.c @@ -144,7 +144,10 @@ void __put_cred(struct cred *cred) BUG_ON(cred == current->cred); BUG_ON(cred == current->real_cred);
- call_rcu(&cred->rcu, put_cred_rcu); + if (cred->non_rcu) + put_cred_rcu(&cred->rcu); + else + call_rcu(&cred->rcu, put_cred_rcu); } EXPORT_SYMBOL(__put_cred);
@@ -256,6 +259,7 @@ struct cred *prepare_creds(void) old = task->cred; memcpy(new, old, sizeof(struct cred));
+ new->non_rcu = 0; atomic_set(&new->usage, 1); set_cred_subscribers(new, 0); get_group_info(new->group_info); @@ -535,7 +539,19 @@ const struct cred *override_creds(const
validate_creds(old); validate_creds(new); - get_cred(new); + + /* + * NOTE! This uses 'get_new_cred()' rather than 'get_cred()'. + * + * That means that we do not clear the 'non_rcu' flag, since + * we are only installing the cred into the thread-synchronous + * '->cred' pointer, not the '->real_cred' pointer that is + * visible to other threads under RCU. + * + * Also note that we did validate_creds() manually, not depending + * on the validation in 'get_cred()'. + */ + get_new_cred((struct cred *)new); alter_cred_subscribers(new, 1); rcu_assign_pointer(current->cred, new); alter_cred_subscribers(old, -1); @@ -672,6 +688,7 @@ struct cred *prepare_kernel_cred(struct validate_creds(old);
*new = *old; + new->non_rcu = 0; atomic_set(&new->usage, 1); set_cred_subscribers(new, 0); get_uid(new->user);
From: Zhengyuan Liu liuzhengyuan@kylinos.cn
commit c0e48f9dea9129aa11bec3ed13803bcc26e96e49 upstream.
There is a hang issue while using fio to do some basic test. The issue can be easily reproduced using the below script:
while true do fio --ioengine=io_uring -rw=write -bs=4k -numjobs=1 \ -size=1G -iodepth=64 -name=uring --filename=/dev/zero done
After several minutes (or more), fio would block at io_uring_enter->io_cqring_wait in order to waiting for previously committed sqes to be completed and can't return to user anymore until we send a SIGTERM to fio. After receiving SIGTERM, fio hangs at io_ring_ctx_wait_and_kill with a backtrace like this:
[54133.243816] Call Trace: [54133.243842] __schedule+0x3a0/0x790 [54133.243868] schedule+0x38/0xa0 [54133.243880] schedule_timeout+0x218/0x3b0 [54133.243891] ? sched_clock+0x9/0x10 [54133.243903] ? wait_for_completion+0xa3/0x130 [54133.243916] ? _raw_spin_unlock_irq+0x2c/0x40 [54133.243930] ? trace_hardirqs_on+0x3f/0xe0 [54133.243951] wait_for_completion+0xab/0x130 [54133.243962] ? wake_up_q+0x70/0x70 [54133.243984] io_ring_ctx_wait_and_kill+0xa0/0x1d0 [54133.243998] io_uring_release+0x20/0x30 [54133.244008] __fput+0xcf/0x270 [54133.244029] ____fput+0xe/0x10 [54133.244040] task_work_run+0x7f/0xa0 [54133.244056] do_exit+0x305/0xc40 [54133.244067] ? get_signal+0x13b/0xbd0 [54133.244088] do_group_exit+0x50/0xd0 [54133.244103] get_signal+0x18d/0xbd0 [54133.244112] ? _raw_spin_unlock_irqrestore+0x36/0x60 [54133.244142] do_signal+0x34/0x720 [54133.244171] ? exit_to_usermode_loop+0x7e/0x130 [54133.244190] exit_to_usermode_loop+0xc0/0x130 [54133.244209] do_syscall_64+0x16b/0x1d0 [54133.244221] entry_SYSCALL_64_after_hwframe+0x49/0xbe
The reason is that we had added a req to ctx->pending_async at the very end, but it didn't get a chance to be processed. How could this happen?
fio#cpu0 wq#cpu1
io_add_to_prev_work io_sq_wq_submit_work
atomic_read() <<< 1
atomic_dec_return() << 1->0 list_empty(); <<< true;
list_add_tail() atomic_read() << 0 or 1?
As atomic_ops.rst states, atomic_read does not guarantee that the runtime modification by any other thread is visible yet, so we must take care of that with a proper implicit or explicit memory barrier.
This issue was detected with the help of Jackie's liuyun01@kylinos.cn
Fixes: 31b515106428 ("io_uring: allow workqueue item to handle multiple buffered requests") Signed-off-by: Zhengyuan Liu liuzhengyuan@kylinos.cn Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/io_uring.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -1769,6 +1769,10 @@ static bool io_add_to_prev_work(struct a ret = true; spin_lock(&list->lock); list_add_tail(&req->list, &list->list); + /* + * Ensure we see a simultaneous modification from io_sq_wq_submit_work() + */ + smp_mb(); if (!atomic_read(&list->cnt)) { list_del_init(&req->list); ret = false;
From: Jens Axboe axboe@kernel.dk
commit 36703247d5f52a679df9da51192b6950fe81689f upstream.
Daniel reports that when testing an http server that uses io_uring to poll for incoming connections, sometimes it hard crashes. This is due to an uninitialized list member for the io_uring request. Normally this doesn't trigger and none of the test cases caught it.
Reported-by: Daniel Kozak kozzi11@gmail.com Tested-by: Daniel Kozak kozzi11@gmail.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/io_uring.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -1489,6 +1489,8 @@ static int io_poll_add(struct io_kiocb * INIT_LIST_HEAD(&poll->wait.entry); init_waitqueue_func_entry(&poll->wait, io_poll_wake);
+ INIT_LIST_HEAD(&req->list); + mask = vfs_poll(poll->file, &ipt.pt) & poll->events;
spin_lock_irq(&ctx->completion_lock);
From: Zhengyuan Liu liuzhengyuan@kylinos.cn
commit f7b76ac9d17e16e44feebb6d2749fec92bfd6dd4 upstream.
We could queue a work for each req in defer and link list without increasing async_list->cnt, so we shouldn't decrease it while exiting from workqueue as well if we didn't process the req in async list.
Thanks to Jens Axboe axboe@kernel.dk for his guidance.
Fixes: 31b515106428 ("io_uring: allow workqueue item to handle multiple buffered requests") Signed-off-by: Zhengyuan Liu liuzhengyuan@kylinos.cn Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/io_uring.c | 8 ++++++++ 1 file changed, 8 insertions(+)
--- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -331,6 +331,9 @@ struct io_kiocb { #define REQ_F_SEQ_PREV 8 /* sequential with previous */ #define REQ_F_IO_DRAIN 16 /* drain existing IO first */ #define REQ_F_IO_DRAINED 32 /* drain done */ +#define REQ_F_LINK 64 /* linked sqes */ +#define REQ_F_LINK_DONE 128 /* linked sqes done */ +#define REQ_F_FAIL_LINK 256 /* fail rest of links */ u64 user_data; u32 error; /* iopoll result from callback */ u32 sequence; @@ -1698,6 +1701,10 @@ restart: /* async context always use a copy of the sqe */ kfree(sqe);
+ /* req from defer and link list needn't decrease async cnt */ + if (req->flags & (REQ_F_IO_DRAINED | REQ_F_LINK_DONE)) + goto out; + if (!async_list) break; if (!list_empty(&req_list)) { @@ -1745,6 +1752,7 @@ restart: } }
+out: if (cur_mm) { set_fs(old_fs); unuse_mm(cur_mm);
From: Jens Axboe axboe@kernel.dk
commit bd11b3a391e3df6fa958facbe4b3f9f4cca9bd49 upstream.
Hrvoje reports that when a large fixed buffer is registered and IO is being done to the latter pages of said buffer, the IO submission time is much worse:
reading to the start of the buffer: 11238 ns reading to the end of the buffer: 1039879 ns
In fact, it's worse by two orders of magnitude. The reason for that is how io_uring figures out how to setup the iov_iter. We point the iter at the first bvec, and then use iov_iter_advance() to fast-forward to the offset within that buffer we need.
However, that is abysmally slow, as it entails iterating the bvecs that we setup as part of buffer registration. There's really no need to use this generic helper, as we know it's a BVEC type iterator, and we also know that each bvec is PAGE_SIZE in size, apart from possibly the first and last. Hence we can just use a shift on the offset to find the right index, and then adjust the iov_iter appropriately. After this fix, the timings are:
reading to the start of the buffer: 10135 ns reading to the end of the buffer: 1377 ns
Or about an 755x improvement for the tail page.
Reported-by: Hrvoje Zeba zeba.hrvoje@gmail.com Tested-by: Hrvoje Zeba zeba.hrvoje@gmail.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- fs/io_uring.c | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-)
--- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -1001,8 +1001,43 @@ static int io_import_fixed(struct io_rin */ offset = buf_addr - imu->ubuf; iov_iter_bvec(iter, rw, imu->bvec, imu->nr_bvecs, offset + len); - if (offset) - iov_iter_advance(iter, offset); + + if (offset) { + /* + * Don't use iov_iter_advance() here, as it's really slow for + * using the latter parts of a big fixed buffer - it iterates + * over each segment manually. We can cheat a bit here, because + * we know that: + * + * 1) it's a BVEC iter, we set it up + * 2) all bvecs are PAGE_SIZE in size, except potentially the + * first and last bvec + * + * So just find our index, and adjust the iterator afterwards. + * If the offset is within the first bvec (or the whole first + * bvec, just use iov_iter_advance(). This makes it easier + * since we can just skip the first segment, which may not + * be PAGE_SIZE aligned. + */ + const struct bio_vec *bvec = imu->bvec; + + if (offset <= bvec->bv_len) { + iov_iter_advance(iter, offset); + } else { + unsigned long seg_skip; + + /* skip first vec */ + offset -= bvec->bv_len; + seg_skip = 1 + (offset >> PAGE_SHIFT); + + iter->bvec = bvec + seg_skip; + iter->nr_segs -= seg_skip; + iter->count -= (seg_skip << PAGE_SHIFT); + iter->iov_offset = offset & ~PAGE_MASK; + if (iter->iov_offset) + iter->count -= iter->iov_offset; + } + }
/* don't drop a reference to these pages */ iter->type |= ITER_BVEC_FLAG_NO_REF;
stable-rc/linux-5.2.y boot: 122 boots: 0 failed, 75 passed with 45 offline, 2 untried/unknown (v5.2.4-216-g0c4d120e771a)
Full Boot Summary: https://kernelci.org/boot/all/job/stable-rc/branch/linux-5.2.y/kernel/v5.2.4... Full Build Summary: https://kernelci.org/build/stable-rc/branch/linux-5.2.y/kernel/v5.2.4-216-g0...
Tree: stable-rc Branch: linux-5.2.y Git Describe: v5.2.4-216-g0c4d120e771a Git Commit: 0c4d120e771a048ef7ae9a4130169b1cf03c36da Git URL: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git Tested: 72 unique boards, 27 SoC families, 17 builds out of 209
Offline Platforms:
riscv:
defconfig: gcc-8 sifive_fu540: 1 offline lab
arm64:
defconfig: gcc-8 meson-axg-s400: 1 offline lab meson-g12a-u200: 1 offline lab meson-g12a-x96-max: 1 offline lab meson-gxbb-odroidc2: 1 offline lab meson-gxl-s905d-p230: 1 offline lab meson-gxl-s905x-libretech-cc: 1 offline lab meson-gxl-s905x-nexbox-a95x: 1 offline lab meson-gxl-s905x-p212: 1 offline lab meson-gxm-nexbox-a1: 1 offline lab rk3399-firefly: 1 offline lab sun50i-a64-pine64-plus: 1 offline lab
mips:
pistachio_defconfig: gcc-8 pistachio_marduk: 1 offline lab
arm:
exynos_defconfig: gcc-8 exynos5250-arndale: 1 offline lab exynos5420-arndale-octa: 1 offline lab exynos5800-peach-pi: 1 offline lab
multi_v7_defconfig: gcc-8 bcm72521-bcm97252sffe: 1 offline lab bcm7445-bcm97445c: 1 offline lab exynos5250-arndale: 1 offline lab exynos5420-arndale-octa: 1 offline lab exynos5800-peach-pi: 1 offline lab imx6dl-wandboard_dual: 1 offline lab imx6dl-wandboard_solo: 1 offline lab imx6q-wandboard: 1 offline lab imx7s-warp: 1 offline lab meson8b-odroidc1: 1 offline lab omap3-beagle: 1 offline lab omap4-panda: 1 offline lab qcom-apq8064-ifc6410: 1 offline lab stih410-b2120: 1 offline lab sun4i-a10-cubieboard: 1 offline lab sun7i-a20-bananapi: 1 offline lab vf610-colibri-eval-v3: 1 offline lab
omap2plus_defconfig: gcc-8 omap3-beagle: 1 offline lab omap4-panda: 1 offline lab
qcom_defconfig: gcc-8 qcom-apq8064-ifc6410: 1 offline lab
davinci_all_defconfig: gcc-8 da850-evm: 1 offline lab dm365evm,legacy: 1 offline lab
imx_v6_v7_defconfig: gcc-8 imx6dl-wandboard_dual: 1 offline lab imx6dl-wandboard_solo: 1 offline lab imx6q-wandboard: 1 offline lab imx7s-warp: 1 offline lab vf610-colibri-eval-v3: 1 offline lab
sunxi_defconfig: gcc-8 sun4i-a10-cubieboard: 1 offline lab sun7i-a20-bananapi: 1 offline lab
--- For more info write to info@kernelci.org
On Tue, 30 Jul 2019 at 01:16, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 5.2.5 release. There are 215 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed 31 Jul 2019 07:05:01 PM UTC. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.2.5-rc1.g... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.2.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: 5.2.5-rc1 git repo: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git git branch: linux-5.2.y git commit: 0c4d120e771a048ef7ae9a4130169b1cf03c36da git describe: v5.2.4-216-g0c4d120e771a Test details: https://qa-reports.linaro.org/lkft/linux-stable-rc-5.2-oe/build/v5.2.4-216-g...
No regressions (compared to build v5.2.4)
No fixes (compared to build v5.2.4)
Ran 22523 total tests in the following environments and test suites.
Environments -------------- - dragonboard-410c - hi6220-hikey - i386 - juno-r2 - qemu_arm - qemu_arm64 - qemu_i386 - qemu_x86_64 - x15 - x86
Test Suites ----------- * build * install-android-platform-tools-r2600 * kselftest * libgpiod * libhugetlbfs * ltp-cap_bounds-tests * ltp-commands-tests * ltp-containers-tests * ltp-cpuhotplug-tests * ltp-cve-tests * ltp-dio-tests * ltp-fcntl-locktests-tests * ltp-filecaps-tests * ltp-fs_bind-tests * ltp-fs_perms_simple-tests * ltp-fsx-tests * ltp-hugetlb-tests * ltp-io-tests * ltp-ipc-tests * ltp-math-tests * ltp-mm-tests * ltp-nptl-tests * ltp-pty-tests * ltp-sched-tests * ltp-securebits-tests * ltp-syscalls-tests * ltp-timers-tests * network-basic-tests * perf * spectre-meltdown-checker-test * v4l2-compliance * ltp-fs-tests * ltp-open-posix-tests * kvm-unit-tests * kselftest-vsyscall-mode-native * kselftest-vsyscall-mode-none
On Tue, Jul 30, 2019 at 02:48:15PM +0530, Naresh Kamboju wrote:
On Tue, 30 Jul 2019 at 01:16, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 5.2.5 release. There are 215 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed 31 Jul 2019 07:05:01 PM UTC. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.2.5-rc1.g... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.2.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 7/29/19 1:19 PM, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.2.5 release. There are 215 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed 31 Jul 2019 07:05:01 PM UTC. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.2.5-rc1.g... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.2.y and the diffstat can be found below.
thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
thanks, -- Shuah
On Tue, Jul 30, 2019 at 08:01:42AM -0600, shuah wrote:
On 7/29/19 1:19 PM, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.2.5 release. There are 215 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed 31 Jul 2019 07:05:01 PM UTC. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.2.5-rc1.g... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.2.y and the diffstat can be found below.
thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
Thanks for testing all of these and letting me know.
greg k-h
On Mon, Jul 29, 2019 at 09:19:56PM +0200, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.2.5 release. There are 215 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed 31 Jul 2019 07:05:01 PM UTC. Anything received after that time might be too late.
Build results: total: 159 pass: 159 fail: 0 Qemu test results: total: 364 pass: 364 fail: 0
Guenter
On Tue, Jul 30, 2019 at 11:43:05AM -0700, Guenter Roeck wrote:
On Mon, Jul 29, 2019 at 09:19:56PM +0200, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.2.5 release. There are 215 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed 31 Jul 2019 07:05:01 PM UTC. Anything received after that time might be too late.
Build results: total: 159 pass: 159 fail: 0 Qemu test results: total: 364 pass: 364 fail: 0
Thanks for testing all of these and letting me know.
greg k-h
On Mon, Jul 29, 2019 at 09:19:56PM +0200, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.2.5 release. There are 215 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed 31 Jul 2019 07:05:01 PM UTC. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.2.5-rc1.g... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.2.y and the diffstat can be found below.
thanks,
greg k-h
Compiled and booted with no regressions on my system.
Cheers, Kelsey
On 29/07/2019 20:19, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.2.5 release. There are 215 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed 31 Jul 2019 07:05:01 PM UTC. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.2.5-rc1.g... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.2.y and the diffstat can be found below.
thanks,
greg k-h
All tests passing for Tegra ...
Test results for stable-v5.2: 12 builds: 12 pass, 0 fail 22 boots: 22 pass, 0 fail 38 tests: 38 pass, 0 fail
Linux version: 5.2.5-rc1-g0c4d120e771a Boards tested: tegra124-jetson-tk1, tegra186-p2771-0000, tegra194-p2972-0000, tegra20-ventana, tegra210-p2371-2180, tegra30-cardhu-a04
Cheers Jon
On Wed, Jul 31, 2019 at 10:36:58AM +0100, Jon Hunter wrote:
On 29/07/2019 20:19, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.2.5 release. There are 215 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed 31 Jul 2019 07:05:01 PM UTC. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.2.5-rc1.g... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.2.y and the diffstat can be found below.
thanks,
greg k-h
All tests passing for Tegra ...
Test results for stable-v5.2: 12 builds: 12 pass, 0 fail 22 boots: 22 pass, 0 fail 38 tests: 38 pass, 0 fail
Linux version: 5.2.5-rc1-g0c4d120e771a Boards tested: tegra124-jetson-tk1, tegra186-p2771-0000, tegra194-p2972-0000, tegra20-ventana, tegra210-p2371-2180, tegra30-cardhu-a04
Thanks for testing all of these and letting me know.
greg k-h
linux-stable-mirror@lists.linaro.org