4.19.78-stable review
Subsystems (8)
Greg Kroah-Hartman
maintainercover 4.19.78-stable review
This is the start of the stable review cycle for the 4.19.78 release. There are 106 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 Tue 08 Oct 2019 05:07:10 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/v4.x/stable-review/patch-4.19.78-rc1.gz
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.19.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 4.19.78-rc1
Bharath Vedartham <[email protected]>
9p/cache.c: Fix memory leak in v9fs_cache_session_get_cookie
Tetsuo Handa <[email protected]>
kexec: bail out upon SIGKILL when allocating memory.
Andrey Konovalov <[email protected]>
NFC: fix attrs checks in netlink interface
Eric Biggers <[email protected]>
smack: use GFP_NOFS while holding inode_smack::smk_lock
Jann Horn <[email protected]>
Smack: Don't ignore other bprm->unsafe flags if LSM_UNSAFE_PTRACE is set
Pierre-Louis Bossart <[email protected]>
soundwire: fix regmap dependencies and align with other serial links
Pierre-Louis Bossart <[email protected]>
soundwire: Kconfig: fix help format
Eric Dumazet <[email protected]>
sch_cbq: validate TCA_CBQ_WRROPT to avoid crash
Tuong Lien <[email protected]>
tipc: fix unlimited bundling of small messages
Dongli Zhang <[email protected]>
xen-netfront: do not use ~0U as error return value for xennet_fill_frags()
Dotan Barak <[email protected]>
net/rds: Fix error handling in rds_ib_add_one()
Josh Hunt <[email protected]>
udp: only do GSO if # of segs > 1
Linus Walleij <[email protected]>
net: dsa: rtl8366: Check VLAN ID and not ports
Dexuan Cui <[email protected]>
vsock: Fix a lockdep warning in __vsock_release()
Josh Hunt <[email protected]>
udp: fix gso_segs calculations
Eric Dumazet <[email protected]>
sch_dsmark: fix potential NULL deref in dsmark_init()
David Howells <[email protected]>
rxrpc: Fix rxrpc_recvmsg tracepoint
Reinhard Speyerer <[email protected]>
qmi_wwan: add support for Cinterion CLS8 devices
Eric Dumazet <[email protected]>
nfc: fix memory leak in llcp_sock_bind()
Martin KaFai Lau <[email protected]>
net: Unpublish sk from sk_reuseport_cb before call_rcu
Navid Emamdoost <[email protected]>
net: qlogic: Fix memory leak in ql_alloc_large_buffers
Paolo Abeni <[email protected]>
net: ipv4: avoid mixed n_redirects and rate_tokens usage
David Ahern <[email protected]>
ipv6: Handle missing host route in __ipv6_ifa_notify
Eric Dumazet <[email protected]>
ipv6: drop incoming packets having a v4mapped source address
Johan Hovold <[email protected]>
hso: fix NULL-deref on tty open
Haishuang Yan <[email protected]>
erspan: remove the incorrect mtu limit for erspan
Vishal Kulkarni <[email protected]>
cxgb4:Fix out-of-bounds MSI-X info array access
Daniel Borkmann <[email protected]>
bpf: fix use after free in prog symbol exposure
Damien Le Moal <[email protected]>
block: mq-deadline: Fix queue restart handling
Alexandre Ghiti <[email protected]>
arm: use STACK_TOP when computing mmap base address
Alexandre Ghiti <[email protected]>
arm: properly account for stack randomization and stack guard gap
Alexandre Ghiti <[email protected]>
mips: properly account for stack randomization and stack guard gap
Alexandre Ghiti <[email protected]>
arm64: consider stack randomization for mmap base only when necessary
Nicolas Boichat <[email protected]>
kmemleak: increase DEBUG_KMEMLEAK_EARLY_LOG_SIZE default to 16K
Changwei Ge <[email protected]>
ocfs2: wait for recovering done after direct unlock request
Greg Thelen <[email protected]>
kbuild: clean compressed initramfs image
Yunfeng Ye <[email protected]>
crypto: hisilicon - Fix double free in sec_free_hw_sgl()
David Howells <[email protected]>
hypfs: Fix error number left in struct pointer member
Jens Axboe <[email protected]>
pktcdvd: remove warning on attempting to register non-passthrough dev
OGAWA Hirofumi <[email protected]>
fat: work around race with userspace's read via blockdev while mounting
Mike Rapoport <[email protected]>
ARM: 8903/1: ensure that usable memory in bank 0 starts from a PMD-aligned address
Jia-Ju Bai <[email protected]>
security: smack: Fix possible null-pointer dereferences in smack_socket_sock_rcv_skb()
Thierry Reding <[email protected]>
PCI: exynos: Propagate errors for optional PHYs
Thierry Reding <[email protected]>
PCI: imx6: Propagate errors for optional regulators
Thierry Reding <[email protected]>
PCI: histb: Propagate errors for optional regulators
Thierry Reding <[email protected]>
PCI: rockchip: Propagate errors for optional regulators
Joao Moreno <[email protected]>
HID: apple: Fix stuck function keys when using FN
Biwen Li <[email protected]>
rtc: pcf85363/pcf85263: fix regmap error in set_time
Anson Huang <[email protected]>
rtc: snvs: fix possible race condition
Nick Desaulniers <[email protected]>
ARM: 8875/1: Kconfig: default to AEABI w/ Clang
Pierre-Louis Bossart <[email protected]>
soundwire: intel: fix channel number reported by hardware
Will Deacon <[email protected]>
ARM: 8898/1: mm: Don't treat faults reported from cache maintenance as writes
Miroslav Benes <[email protected]>
livepatch: Nullify obj->mod in klp_module_coming()'s error path
Jason Gerecke <[email protected]>
HID: wacom: Fix several minor compiler warnings
Nishka Dasgupta <[email protected]>
PCI: tegra: Fix OF node reference leak
Kai-Heng Feng <[email protected]>
mfd: intel-lpss: Remove D3cold delay
Hans de Goede <[email protected]>
i2c-cht-wc: Fix lockdep warning
Nathan Chancellor <[email protected]>
MIPS: tlbex: Explicitly cast _PAGE_NO_EXEC to a boolean
Zhou Yanjie <[email protected]>
MIPS: Ingenic: Disable broken BTB lookup optimization.
zhangyi (F) <[email protected]>
ext4: fix potential use after free after remounting with noblock_validity
Chris Wilson <[email protected]>
dma-buf/sw_sync: Synchronize signal vs syncpt free
Bart Van Assche <[email protected]>
scsi: core: Reduce memory required for SCSI logging
Chunyan Zhang <[email protected]>
clk: sprd: add missing kfree
Jorge Ramirez-Ortiz <[email protected]>
mbox: qcom: add APCS child device for QCS404
Ganesh Goudar <[email protected]>
powerpc: dump kernel log before carrying out fadump or kdump
Eugen Hristev <[email protected]>
clk: at91: select parent if main oscillator or bypass is enabled
Arnd Bergmann <[email protected]>
arm64: fix unreachable code issue with cmpxchg
Otto Meier <[email protected]>
pinctrl: meson-gxbb: Fix wrong pinning definition for uart_c
Nathan Lynch <[email protected]>
powerpc/pseries: correctly track irq state in default idle
Stephen Boyd <[email protected]>
clk: qcom: gcc-sdm845: Use floor ops for sdcc clks
Deepa Dinamani <[email protected]>
pstore: fs superblock limits
Nicholas Piggin <[email protected]>
powerpc/64s/exception: machine check use correct cfar for late handler
Jean Delvare <[email protected]>
drm/amdgpu/si: fix ASIC tests
Charlene Liu <[email protected]>
drm/amd/display: support spdif
Geert Uytterhoeven <[email protected]>
clk: renesas: cpg-mssr: Set GENPD_FLAG_ALWAYS_ON for clock domain
Geert Uytterhoeven <[email protected]>
clk: renesas: mstp: Set GENPD_FLAG_ALWAYS_ON for clock domain
Daniel Drake <[email protected]>
pinctrl: amd: disable spurious-firing GPIO IRQs
Mark Menzynski <[email protected]>
drm/nouveau/volt: Fix for some cards having 0 maximum voltage
hexin <[email protected]>
vfio_pci: Restore original state on release
Sam Bobroff <[email protected]>
powerpc/eeh: Clear stale EEH_DEV_NO_HANDLER flag
Sowjanya Komatineni <[email protected]>
pinctrl: tegra: Fix write barrier placement in pmx_writel
Nathan Lynch <[email protected]>
powerpc/pseries/mobility: use cond_resched when updating device tree
Christophe Leroy <[email protected]>
powerpc/futex: Fix warning: 'oldval' may be used uninitialized in this function
Nathan Lynch <[email protected]>
powerpc/rtas: use device model APIs and serialization during LPM
Cédric Le Goater <[email protected]>
powerpc/xmon: Check for HV mode when dumping XIVE info from OPAL
Stephen Boyd <[email protected]>
clk: zx296718: Don't reference clk_init_data after registration
Stephen Boyd <[email protected]>
clk: sprd: Don't reference clk_init_data after registration
Stephen Boyd <[email protected]>
clk: sirf: Don't reference clk_init_data after registration
Stephen Boyd <[email protected]>
clk: actions: Don't reference clk_init_data after registration
Alexey Kardashevskiy <[email protected]>
powerpc/powernv/ioda2: Allocate TCE table levels on demand for default DMA window
Lewis Huang <[email protected]>
drm/amd/display: reprogram VM config when system resume
Anthony Koo <[email protected]>
drm/amd/display: fix issue where 252-255 values are clipped
Icenowy Zheng <[email protected]>
clk: sunxi-ng: v3s: add missing clock slices for MMC2 module clocks
Nathan Huckleberry <[email protected]>
clk: qoriq: Fix -Wunused-const-variable
Corey Minyard <[email protected]>
ipmi_si: Only schedule continuously in the thread in maintenance mode
Nathan Chancellor <[email protected]>
PCI: rpaphp: Avoid a sometimes-uninitialized warning
Jia-Ju Bai <[email protected]>
gpu: drm: radeon: Fix a possible null-pointer dereference in radeon_connector_set_property()
KyleMahlkuch <[email protected]>
drm/radeon: Fix EEH during kexec
Sean Paul <[email protected]>
drm/rockchip: Check for fast link training before enabling psr
Navid Emamdoost <[email protected]>
drm/panel: check failure cases in the probe func
Ahmad Fatoum <[email protected]>
drm/stm: attach gem fence to atomic state
Marko Kohtala <[email protected]>
video: ssd1307fb: Start page range at page_offset
Lucas Stach <[email protected]>
drm/panel: simple: fix AUO g185han01 horizontal blanking
Andrey Smirnov <[email protected]>
drm/bridge: tc358767: Increase AUX transfer length limit
Vadim Sukhomlinov <[email protected]>
tpm: Fix TPM 1.2 Shutdown sequence to prevent future TPM operations
Jarkko Sakkinen <[email protected]>
tpm: use tpm_try_get_ops() in tpm-sysfs.c.
-------------
Diffstat:
Makefile | 4 +- arch/arm/Kconfig | 5 +- arch/arm/mm/fault.c | 4 +- arch/arm/mm/fault.h | 1 + arch/arm/mm/mmap.c | 16 +- arch/arm/mm/mmu.c | 16 ++ arch/arm64/include/asm/cmpxchg.h | 6 +- arch/arm64/mm/mmap.c | 6 +- arch/mips/include/asm/mipsregs.h | 4 + arch/mips/kernel/cpu-probe.c | 7 + arch/mips/mm/mmap.c | 14 +- arch/mips/mm/tlbex.c | 2 +- arch/powerpc/include/asm/futex.h | 3 +- arch/powerpc/kernel/eeh_driver.c | 11 +- arch/powerpc/kernel/exceptions-64s.S | 4 + arch/powerpc/kernel/rtas.c | 11 +- arch/powerpc/kernel/traps.c | 1 + arch/powerpc/platforms/powernv/pci-ioda-tce.c | 20 +-- arch/powerpc/platforms/powernv/pci.h | 2 +- arch/powerpc/platforms/pseries/mobility.c | 9 + arch/powerpc/platforms/pseries/setup.c | 3 + arch/powerpc/xmon/xmon.c | 15 +- arch/s390/hypfs/inode.c | 9 +- block/mq-deadline.c | 23 +-- drivers/base/regmap/Kconfig | 2 +- drivers/block/pktcdvd.c | 1 - drivers/char/ipmi/ipmi_si_intf.c | 24 ++- drivers/char/tpm/tpm-chip.c | 5 +- drivers/char/tpm/tpm-sysfs.c | 134 +++++++++------ drivers/clk/actions/owl-common.c | 5 +- drivers/clk/at91/clk-main.c | 10 +- drivers/clk/clk-qoriq.c | 2 +- drivers/clk/qcom/gcc-sdm845.c | 4 +- drivers/clk/renesas/clk-mstp.c | 3 +- drivers/clk/renesas/renesas-cpg-mssr.c | 3 +- drivers/clk/sirf/clk-common.c | 12 +- drivers/clk/sprd/common.c | 5 +- drivers/clk/sprd/pll.c | 2 + drivers/clk/sunxi-ng/ccu-sun8i-v3s.c | 3 + drivers/clk/zte/clk-zx296718.c | 109 ++++++------ drivers/crypto/hisilicon/sec/sec_algs.c | 13 +- drivers/dma-buf/sw_sync.c | 16 +- drivers/gpu/drm/amd/amdgpu/si.c | 6 +- drivers/gpu/drm/amd/display/dc/core/dc.c | 8 + drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 17 +- drivers/gpu/drm/amd/display/dc/dce/dce_audio.c | 4 +- .../gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c | 3 +- drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 9 +- drivers/gpu/drm/bridge/tc358767.c | 2 +- drivers/gpu/drm/nouveau/nvkm/subdev/bios/volt.c | 2 + .../gpu/drm/panel/panel-raspberrypi-touchscreen.c | 13 ++ drivers/gpu/drm/panel/panel-simple.c | 6 +- drivers/gpu/drm/radeon/radeon_connectors.c | 2 +- drivers/gpu/drm/radeon/radeon_drv.c | 8 + drivers/gpu/drm/stm/ltdc.c | 2 + drivers/hid/hid-apple.c | 49 +++--- drivers/hid/wacom_sys.c | 7 +- drivers/hid/wacom_wac.c | 4 +- drivers/i2c/busses/i2c-cht-wc.c | 46 +++++ drivers/mailbox/qcom-apcs-ipc-mailbox.c | 8 +- drivers/mfd/intel-lpss-pci.c | 2 + drivers/net/dsa/rtl8366.c | 11 +- drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c | 9 +- drivers/net/ethernet/qlogic/qla3xxx.c | 1 + drivers/net/usb/hso.c | 12 +- drivers/net/usb/qmi_wwan.c | 1 + drivers/net/xen-netfront.c | 17 +- drivers/pci/controller/dwc/pci-exynos.c | 2 +- drivers/pci/controller/dwc/pci-imx6.c | 4 +- drivers/pci/controller/dwc/pcie-histb.c | 4 +- drivers/pci/controller/pci-tegra.c | 22 ++- drivers/pci/controller/pcie-rockchip-host.c | 16 +- drivers/pci/hotplug/rpaphp_core.c | 18 +- drivers/pinctrl/meson/pinctrl-meson-gxbb.c | 12 +- drivers/pinctrl/pinctrl-amd.c | 12 +- drivers/pinctrl/tegra/pinctrl-tegra.c | 4 +- drivers/rtc/rtc-pcf85363.c | 7 +- drivers/rtc/rtc-snvs.c | 11 +- drivers/scsi/scsi_logging.c | 48 +----- drivers/soundwire/Kconfig | 9 +- drivers/soundwire/Makefile | 2 +- drivers/soundwire/intel.c | 10 ++ drivers/vfio/pci/vfio_pci.c | 17 +- drivers/video/fbdev/ssd1307fb.c | 2 +- fs/9p/cache.c | 2 + fs/ext4/block_validity.c | 189 +++++++++++++++------ fs/ext4/ext4.h | 10 +- fs/fat/dir.c | 13 +- fs/fat/fatent.c | 3 + fs/ocfs2/dlm/dlmunlock.c | 23 ++- fs/pstore/ram.c | 2 + include/scsi/scsi_dbg.h | 2 - include/trace/events/rxrpc.h | 2 +- kernel/bpf/syscall.c | 28 +-- kernel/kexec_core.c | 2 + kernel/livepatch/core.c | 1 + lib/Kconfig.debug | 2 +- net/core/sock.c | 11 +- net/ipv4/ip_gre.c | 1 + net/ipv4/route.c | 5 +- net/ipv4/udp.c | 11 +- net/ipv6/addrconf.c | 17 +- net/ipv6/ip6_input.c | 10 ++ net/ipv6/udp.c | 9 +- net/nfc/llcp_sock.c | 7 +- net/nfc/netlink.c | 6 +- net/rds/ib.c | 6 +- net/sched/sch_cbq.c | 40 +++-- net/sched/sch_dsmark.c | 2 + net/tipc/link.c | 29 ++-- net/tipc/msg.c | 5 +- net/vmw_vsock/af_vsock.c | 16 +- net/vmw_vsock/hyperv_transport.c | 2 +- net/vmw_vsock/virtio_transport_common.c | 2 +- security/smack/smack_access.c | 6 +- security/smack/smack_lsm.c | 7 +- tools/testing/selftests/net/udpgso.c | 16 +- usr/Makefile | 3 + 118 files changed, 965 insertions(+), 523 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/106 tpm: use tpm_try_get_ops() in tpm-sysfs.c.
From: Jarkko Sakkinen <[email protected]>
commit 2677ca98ae377517930c183248221f69f771c921 upstream
Use tpm_try_get_ops() in tpm-sysfs.c so that we can consider moving other decorations (locking, localities, power management for example) inside it. This direction can be of course taken only after other call sites for tpm_transmit() have been treated in the same way.
--- drivers/char/tpm/tpm-sysfs.c | 134 ++++++++++++++++++++++------------- 1 file changed, 83 insertions(+), 51 deletions(-)
drivers/char/tpm/tpm-sysfs.c +83 -51
@@ -39,7 +39,6 @@ static ssize_t pubek_show(struct device *dev, struct device_attribute *attr, {struct tpm_buf tpm_buf;struct tpm_readpubek_out *out; -ssize_t rc;int i;char *str = buf;struct tpm_chip *chip =to_tpm_chip (dev);
@@ -47,19 +46,18 @@ static ssize_t pubek_show(struct device *dev, struct device_attribute *attr,memset (&anti_replay,0 ,sizeof (anti_replay)); - rc =tpm_buf_init (&tpm_buf,TPM_TAG_RQU_COMMAND ,TPM_ORD_READPUBEK ); -if (rc) -return rc; +if (tpm_try_get_ops (chip)) +return 0 ; + +if (tpm_buf_init (&tpm_buf,TPM_TAG_RQU_COMMAND ,TPM_ORD_READPUBEK )) + goto out_ops;tpm_buf_append (&tpm_buf, anti_replay,sizeof (anti_replay)); - rc =tpm_transmit_cmd (chip,NULL , tpm_buf.data,PAGE_SIZE , +if (tpm_transmit_cmd (chip,NULL , tpm_buf.data,PAGE_SIZE ,READ_PUBEK_RESULT_MIN_BODY_SIZE ,0 , -"attempting to read the PUBEK" ); -if (rc) { -tpm_buf_destroy (&tpm_buf); -return 0 ; - } +"attempting to read the PUBEK" )) + goto out_buf; out = (struct tpm_readpubek_out *)&tpm_buf.data[10 ]; str +=
@@ -90,9 +88,11 @@ static ssize_t pubek_show(struct device *dev, struct device_attribute *attr, str +=sprintf (str,"\n" ); } - rc = str - buf; +out_buf:tpm_buf_destroy (&tpm_buf); -return rc; +out_ops: +tpm_put_ops (chip); +return str - buf; }static DEVICE_ATTR_RO (pubek);
@@ -106,12 +106,16 @@ static ssize_t pcrs_show(struct device *dev, struct device_attribute *attr,char *str = buf;struct tpm_chip *chip =to_tpm_chip (dev); - rc =tpm_getcap (chip,TPM_CAP_PROP_PCR , &cap, -"attempting to determine the number of PCRS" , -sizeof (cap.num_pcrs)); -if (rc) +if (tpm_try_get_ops (chip))return 0 ; +if (tpm_getcap (chip,TPM_CAP_PROP_PCR , &cap, +"attempting to determine the number of PCRS" , +sizeof (cap.num_pcrs))) { +tpm_put_ops (chip); +return 0 ; + } + num_pcrs =be32_to_cpu (cap.num_pcrs);for (i =0 ; i < num_pcrs; i++) { rc =tpm_pcr_read_dev (chip, i, digest);
@@ -122,6 +126,7 @@ static ssize_t pcrs_show(struct device *dev, struct device_attribute *attr, str +=sprintf (str,"%02X " , digest[j]); str +=sprintf (str,"\n" ); } +tpm_put_ops (chip);return str - buf; }static DEVICE_ATTR_RO (pcrs);
@@ -129,16 +134,21 @@ static DEVICE_ATTR_RO(pcrs);static ssize_t enabled_show (struct device *dev,struct device_attribute *attr,char *buf) { +struct tpm_chip *chip =to_tpm_chip (dev); +ssize_t rc =0 ;cap_t cap; -ssize_t rc; - rc =tpm_getcap (to_tpm_chip (dev),TPM_CAP_FLAG_PERM , &cap, -"attempting to determine the permanent enabled state" , -sizeof (cap.perm_flags)); -if (rc) +if (tpm_try_get_ops (chip))return 0 ; +if (tpm_getcap (chip,TPM_CAP_FLAG_PERM , &cap, +"attempting to determine the permanent enabled state" , +sizeof (cap.perm_flags))) + goto out_ops; + rc =sprintf (buf,"%d\n" , !cap.perm_flags.disable); +out_ops: +tpm_put_ops (chip);return rc; }static DEVICE_ATTR_RO (enabled);
@@ -146,16 +156,21 @@ static DEVICE_ATTR_RO(enabled);static ssize_t active_show (struct device *dev,struct device_attribute *attr,char *buf) { +struct tpm_chip *chip =to_tpm_chip (dev); +ssize_t rc =0 ;cap_t cap; -ssize_t rc; - rc =tpm_getcap (to_tpm_chip (dev),TPM_CAP_FLAG_PERM , &cap, -"attempting to determine the permanent active state" , -sizeof (cap.perm_flags)); -if (rc) +if (tpm_try_get_ops (chip))return 0 ; +if (tpm_getcap (chip,TPM_CAP_FLAG_PERM , &cap, +"attempting to determine the permanent active state" , +sizeof (cap.perm_flags))) + goto out_ops; + rc =sprintf (buf,"%d\n" , !cap.perm_flags.deactivated); +out_ops: +tpm_put_ops (chip);return rc; }static DEVICE_ATTR_RO (active);
@@ -163,16 +178,21 @@ static DEVICE_ATTR_RO(active);static ssize_t owned_show (struct device *dev,struct device_attribute *attr,char *buf) { +struct tpm_chip *chip =to_tpm_chip (dev); +ssize_t rc =0 ;cap_t cap; -ssize_t rc; - rc =tpm_getcap (to_tpm_chip (dev),TPM_CAP_PROP_OWNER , &cap, -"attempting to determine the owner state" , -sizeof (cap.owned)); -if (rc) +if (tpm_try_get_ops (chip))return 0 ; +if (tpm_getcap (to_tpm_chip (dev),TPM_CAP_PROP_OWNER , &cap, +"attempting to determine the owner state" , +sizeof (cap.owned))) + goto out_ops; + rc =sprintf (buf,"%d\n" , cap.owned); +out_ops: +tpm_put_ops (chip);return rc; }static DEVICE_ATTR_RO (owned);
@@ -180,16 +200,21 @@ static DEVICE_ATTR_RO(owned);static ssize_t temp_deactivated_show (struct device *dev,struct device_attribute *attr,char *buf) { +struct tpm_chip *chip =to_tpm_chip (dev); +ssize_t rc =0 ;cap_t cap; -ssize_t rc; - rc =tpm_getcap (to_tpm_chip (dev),TPM_CAP_FLAG_VOL , &cap, -"attempting to determine the temporary state" , -sizeof (cap.stclear_flags)); -if (rc) +if (tpm_try_get_ops (chip))return 0 ; +if (tpm_getcap (to_tpm_chip (dev),TPM_CAP_FLAG_VOL , &cap, +"attempting to determine the temporary state" , +sizeof (cap.stclear_flags))) + goto out_ops; + rc =sprintf (buf,"%d\n" , cap.stclear_flags.deactivated); +out_ops: +tpm_put_ops (chip);return rc; }static DEVICE_ATTR_RO (temp_deactivated);
@@ -198,15 +223,18 @@ static ssize_t caps_show(struct device *dev, struct device_attribute *attr, char *buf) {struct tpm_chip *chip =to_tpm_chip (dev); -cap_t cap; -ssize_t rc; +ssize_t rc =0 ;char *str = buf; +cap_t cap; - rc =tpm_getcap (chip,TPM_CAP_PROP_MANUFACTURER , &cap, -"attempting to determine the manufacturer" , -sizeof (cap.manufacturer_id)); -if (rc) +if (tpm_try_get_ops (chip))return 0 ; + +if (tpm_getcap (chip,TPM_CAP_PROP_MANUFACTURER , &cap, +"attempting to determine the manufacturer" , +sizeof (cap.manufacturer_id))) + goto out_ops; + str +=sprintf (str,"Manufacturer: 0x%x\n" ,be32_to_cpu (cap.manufacturer_id));
@@ -223,20 +251,22 @@ static ssize_t caps_show(struct device *dev, struct device_attribute *attr, cap.tpm_version_1_2.revMinor); }else {/* Otherwise just use TPM_STRUCT_VER */ - rc =tpm_getcap (chip,TPM_CAP_VERSION_1_1 , &cap, -"attempting to determine the 1.1 version" , -sizeof (cap.tpm_version)); -if (rc) -return 0 ; +if (tpm_getcap (chip,TPM_CAP_VERSION_1_1 , &cap, +"attempting to determine the 1.1 version" , +sizeof (cap.tpm_version))) + goto out_ops; + str +=sprintf (str,"TCG version: %d.%d\nFirmware version: %d.%d\n" , cap.tpm_version.Major, cap.tpm_version.Minor, cap.tpm_version.revMajor, cap.tpm_version.revMinor); - } - -return str - buf; +} + rc = str - buf; +out_ops: +tpm_put_ops (chip); +return rc; }static DEVICE_ATTR_RO (caps);
@@ -244,10 +274,12 @@ static ssize_t cancel_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) {struct tpm_chip *chip =to_tpm_chip (dev); -if (chip ==NULL ) + +if (tpm_try_get_ops (chip))return 0 ; chip->ops->cancel (chip); +tpm_put_ops (chip);return count; }static DEVICE_ATTR_WO (cancel);
Signature · 1 line
2.20.1
Re: [PATCH 4.19 001/106] tpm: use tpm_try_get_ops() in tpm-sysfs.c.
Quoted 8 lines · Greg Kroah-Hartman
From: Jarkko Sakkinen <[email protected]>
commit
2677ca98ae377517930c183248221f69f771c921upstreamUse
tpm_try_get_ops()intpm-sysfs.cso that we can consider moving other decorations (locking, localities, power management for example) inside it. This direction can be of course taken only after other call sites fortpm_transmit()have been treated in the same way.
This changes locking completely:
Quoted 4 lines
drivers/char/tpm/tpm-sysfs.c +0
-0@@ -244,10 +274,12 @@ static ssize_t cancel_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) {struct tpm_chip *chip =to_tpm_chip (dev);
drivers/char/tpm/tpm-sysfs.c static ssize_t cancel_store(struct device *dev, struct device_attribute *attr, · line 285
Quoted 10 lines
drivers/char/tpm/tpm-sysfs.c +3
-1-if (chip ==NULL ) + +if (tpm_try_get_ops (chip))return 0 ; chip->ops->cancel (chip); +tpm_put_ops (chip);return count; }static DEVICE_ATTR_WO (cancel);
For example this did not have any locking, and is now protected by
get_device(&chip->dev);
down_read(&chip->ops_sem);. Is that intended? Is this known to fix any bugs?
Best regards,
Pavel
Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
Re: [PATCH 4.19 001/106] tpm: use tpm_try_get_ops() in tpm-sysfs.c.
Quoted 7 lines · Pavel Machek
For example this did not have any locking, and is now protected by
get_device(&chip->dev); down_read(&chip->ops_sem);. Is that intended? Is this known to fix any bugs?
It is, sysfs code can otherwise race when ops is set NULL in class shutdown.
/Jarkko
Greg Kroah-Hartman
maintainerPATCH 2/106 tpm: Fix TPM 1.2 Shutdown sequence to prevent future TPM operations
In reply to Greg Kroah-HartmanFrom: Vadim Sukhomlinov <[email protected]>
commit db4d8cb9c9f2af71c4d087817160d866ed572cc9 upstream
TPM 2.0 Shutdown involve sending TPM2_Shutdown to TPM chip and disabling future TPM operations. TPM 1.2 behavior was different, future TPM operations weren't disabled, causing rare issues. This patch ensures that future TPM operations are disabled.
--- drivers/char/tpm/tpm-chip.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/char/tpm/tpm-chip.c +3 -2
@@ -187,12 +187,13 @@ static int tpm_class_shutdown(struct device *dev) { struct tpm_chip *chip = container_of(dev, struct tpm_chip, dev); +down_write (&chip->ops_sem);if (chip->flags &TPM_CHIP_FLAG_TPM2 ) { -down_write (&chip->ops_sem);tpm2_shutdown (chip,TPM2_SU_CLEAR ); chip->ops =NULL ; -up_write (&chip->ops_sem); } + chip->ops =NULL ; +up_write (&chip->ops_sem);return 0 ; }
Signature · 1 line
2.20.1
Re: [PATCH 4.19 002/106] tpm: Fix TPM 1.2 Shutdown sequence to prevent future TPM operations
Hi!
Quoted 8 lines
From: Vadim Sukhomlinov <[email protected]>
commit
db4d8cb9c9f2af71c4d087817160d866ed572cc9upstreamTPM 2.0 Shutdown involve sending
TPM2_Shutdownto TPM chip and disabling future TPM operations. TPM 1.2 behavior was different, future TPM operations weren't disabled, causing rare issues. This patch ensures that future TPM operations are disabled.
...
Quoted 8 lines
drivers/char/tpm/tpm-chip.c +1
-0@@ -187,12 +187,13 @@ static int tpm_class_shutdown(struct device *dev) { struct tpm_chip *chip = container_of(dev, struct tpm_chip, dev); +down_write (&chip->ops_sem);if (chip->flags &TPM_CHIP_FLAG_TPM2 ) {
drivers/char/tpm/tpm-chip.c static int tpm_class_shutdown(struct device *dev) · line 199
Quoted 10 lines
drivers/char/tpm/tpm-chip.c +2
-2-down_write (&chip->ops_sem);tpm2_shutdown (chip,TPM2_SU_CLEAR ); chip->ops =NULL ; -up_write (&chip->ops_sem); } + chip->ops =NULL ; +up_write (&chip->ops_sem);return 0 ; }
Still can be improved -- chip->ops = NULL; is done twice, copy inside the if {} is redundant...
Best regards,
Pavel
Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
Re: [PATCH 4.19 002/106] tpm: Fix TPM 1.2 Shutdown sequence to prevent future TPM operations
Quoted 16 lines
Quoted 16 lines
drivers/char/tpm/tpm-chip.c +3
-2@@ -187,12 +187,13 @@ static int tpm_class_shutdown(struct device *dev) { struct tpm_chip *chip = container_of(dev, struct tpm_chip, dev); +down_write (&chip->ops_sem);if (chip->flags &TPM_CHIP_FLAG_TPM2 ) { -down_write (&chip->ops_sem);tpm2_shutdown (chip,TPM2_SU_CLEAR ); chip->ops =NULL ; -up_write (&chip->ops_sem); } + chip->ops =NULL ; +up_write (&chip->ops_sem);
Quoted 5 lines
drivers/char/tpm/tpm-chip.c static int tpm_class_shutdown(struct device *dev) · line 199
Quoted 2 lines
drivers/char/tpm/tpm-chip.c +0
-0return 0 ; }Still can be improved --
chip->ops= NULL; is done twice, copy inside the if {} is redundant...
Thanks. I can update this.
/Jarkko
Greg Kroah-Hartman
maintainerPATCH 3/106 drm/bridge: tc358767: Increase AUX transfer length limit
In reply to Greg Kroah-HartmanFrom: Andrey Smirnov <[email protected]>
[ Upstream commit e0655feaec62d5139b6b13a7b1bbb1ab8f1c2d83 ]
According to the datasheet tc358767 can transfer up to 16 bytes via its AUX channel, so the artificial limit of 8 appears to be too low. However only up to 15-bytes seem to be actually supported and trying to use 16-byte transfers results in transfers failing sporadically (with bogus status in case of I2C transfers), so limit it to 15.
--- drivers/gpu/drm/bridge/tc358767.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/bridge/tc358767.c +1 -1
@@ -302,7 +302,7 @@ static ssize_t tc_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) {struct tc_data *tc =aux_to_tc (aux); -size_t size =min_t (size_t,8 , msg->size); +size_t size =min_t (size_t,DP_AUX_MAX_PAYLOAD_BYTES -1 , msg->size);u8 request = msg->request & ~DP_AUX_I2C_MOT ;u8 *buf = msg->buffer;u32 tmp =0 ;
Signature · 8 lines
2.20.1 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
Greg Kroah-Hartman
maintainerPATCH 4/106 drm/panel: simple: fix AUO g185han01 horizontal blanking
In reply to Greg Kroah-HartmanFrom: Lucas Stach <[email protected]>
[ Upstream commit f8c6bfc612b56f02e1b8fae699dff12738aaf889 ]
The horizontal blanking periods are too short, as the values are specified for a single LVDS channel. Since this panel is dual LVDS they need to be doubled. With this change the panel reaches its nominal vrefresh rate of 60Fps, instead of the 64Fps with the current wrong blanking.
Philipp Zabel added:
The datasheet specifies 960 active clocks + 40/128/160 clocks blanking on each of the two LVDS channels (min/typical/max), so doubled this is now correct.
--- drivers/gpu/drm/panel/panel-simple.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/gpu/drm/panel/panel-simple.c +3 -3
@@ -689,9 +689,9 @@ static const struct panel_desc auo_g133han01 = {static const struct display_timing auo_g185han01_timings = { .pixelclock = {120000000 ,144000000 ,175000000 }, .hactive = {1920 ,1920 ,1920 }, - .hfront_porch = {18 ,60 ,74 }, - .hback_porch = {12 ,44 ,54 }, - .hsync_len = {10 ,24 ,32 }, + .hfront_porch = {36 ,120 ,148 }, + .hback_porch = {24 ,88 ,108 }, + .hsync_len = {20 ,48 ,64 }, .vactive = {1080 ,1080 ,1080 }, .vfront_porch = {6 ,10 ,40 }, .vback_porch = {2 ,5 ,20 },
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 5/106 video: ssd1307fb: Start page range at page_offset
In reply to Greg Kroah-HartmanFrom: Marko Kohtala <[email protected]>
[ Upstream commit dd9782834dd9dde3624ff1acea8859f3d3e792d4 ]
The page_offset was only applied to the end of the page range. This caused the display updates to cause a scrolling effect on the display because the amount of data written to the display did not match the range display expected.
--- drivers/video/fbdev/ssd1307fb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/video/fbdev/ssd1307fb.c +1 -1
@@ -433,7 +433,7 @@ static int ssd1307fb_init(struct ssd1307fb_par *par)if (ret <0 )return ret; - ret =ssd1307fb_write_cmd (par->client,0x0 ); + ret =ssd1307fb_write_cmd (par->client, par->page_offset);if (ret <0 )return ret;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 6/106 drm/stm: attach gem fence to atomic state
In reply to Greg Kroah-HartmanFrom: Ahmad Fatoum <[email protected]>
[ Upstream commit 8fabc9c3109a71b3577959a05408153ae69ccd8d ]
To properly synchronize with other devices the fence from the GEM object backing the framebuffer needs to be attached to the atomic state, so the commit work can wait on fence signaling.
--- drivers/gpu/drm/stm/ltdc.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/stm/ltdc.c +2 -0
@@ -19,6 +19,7 @@#include <drm/drm_crtc_helper.h> #include <drm/drm_fb_cma_helper.h> #include <drm/drm_gem_cma_helper.h> +#include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_of.h> #include <drm/drm_bridge.h> #include <drm/drm_plane_helper.h>
@@ -825,6 +826,7 @@ static const struct drm_plane_funcs ltdc_plane_funcs = { };static const struct drm_plane_helper_funcs ltdc_plane_helper_funcs = { + .prepare_fb = drm_gem_fb_prepare_fb, .atomic_check = ltdc_plane_atomic_check, .atomic_update = ltdc_plane_atomic_update, .atomic_disable = ltdc_plane_atomic_disable,
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 7/106 drm/panel: check failure cases in the probe func
In reply to Greg Kroah-HartmanFrom: Navid Emamdoost <[email protected]>
[ Upstream commit afd6d4f5a52c16e1483328ac074abb1cde92c29f ]
The following function calls may fail and return NULL, so the null check is added.of_graph_get_next_endpointof_graph_get_remote_port_parentof_graph_get_remote_port
Update: Thanks to Sam Ravnborg, for suggession on the use of goto to avoid leaking endpoint.
--- .../gpu/drm/panel/panel-raspberrypi-touchscreen.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c +13 -0
@@ -400,7 +400,13 @@ static int rpi_touchscreen_probe(struct i2c_client *i2c,/* Look up the DSI host. It needs to probe before we do. */ endpoint =of_graph_get_next_endpoint (dev->of_node,NULL ); +if (!endpoint) +return -ENODEV ; + dsi_host_node =of_graph_get_remote_port_parent (endpoint); +if (!dsi_host_node) + goto error; + host =of_find_mipi_dsi_host_by_node (dsi_host_node);of_node_put (dsi_host_node);if (!host) {
@@ -409,6 +415,9 @@ static int rpi_touchscreen_probe(struct i2c_client *i2c, } info.node =of_graph_get_remote_port (endpoint); +if (!info.node) + goto error; +of_node_put (endpoint); ts->dsi =mipi_dsi_device_register_full (host, &info);
@@ -429,6 +438,10 @@ static int rpi_touchscreen_probe(struct i2c_client *i2c,return ret;return 0 ; + +error: +of_node_put (endpoint); +return -ENODEV ; }static int rpi_touchscreen_remove (struct i2c_client *i2c)
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 8/106 drm/rockchip: Check for fast link training before enabling psr
In reply to Greg Kroah-HartmanFrom: Sean Paul <[email protected]>
[ Upstream commit ad309284a52be47c8b3126c9376358bf381861bc ]
Once we start shutting off the link during PSR, we're going to want fast training to work. If the display doesn't support fast training, don't enable psr.
Changes in v2:
- None
Changes in v3:
- None
Changes in v4:
- None
Changes in v5:
- None
Link to v1: https://patchwork.freedesktop.org/patch/msgid/[email protected]
Link to v2: https://patchwork.freedesktop.org/patch/msgid/[email protected]
Link to v3: https://patchwork.freedesktop.org/patch/msgid/[email protected]
Link to v4: https://patchwork.freedesktop.org/patch/msgid/[email protected]
--- drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +5 -4
@@ -1040,16 +1040,17 @@ static int analogix_dp_commit(struct analogix_dp_device *dp)if (ret)return ret; +/* Check whether panel supports fast training */ + ret =analogix_dp_fast_link_train_detection (dp); +if (ret) + dp->psr_enable = false; +if (dp->psr_enable) { ret =analogix_dp_enable_sink_psr (dp);if (ret)return ret; } -/* Check whether panel supports fast training */ - ret =analogix_dp_fast_link_train_detection (dp); -if (ret) - dp->psr_enable = false;return ret; }
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 9/106 drm/radeon: Fix EEH during kexec
In reply to Greg Kroah-HartmanFrom: KyleMahlkuch <[email protected]>
[ Upstream commit 6f7fe9a93e6c09bf988c5059403f5f88e17e21e6 ]
During kexec some adapters hit an EEH since they are not properly shut down in the radeon_pci_shutdown() function. Adding radeon_suspend_kms() fixes this issue.
--- drivers/gpu/drm/radeon/radeon_drv.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/gpu/drm/radeon/radeon_drv.c +8 -0
@@ -364,11 +364,19 @@ radeon_pci_remove(struct pci_dev *pdev)static void radeon_pci_shutdown (struct pci_dev *pdev) { +struct drm_device *ddev =pci_get_drvdata (pdev); +/* if we are running in a VM, make sure the device * torn down properly on reboot/shutdown */ if (radeon_device_is_virtual ())radeon_pci_remove (pdev); + +/* Some adapters need to be suspended before a +* shutdown occurs in order to prevent an error +* during kexec. +*/ +radeon_suspend_kms (ddev, true, true, false); }static int radeon_pmops_suspend (struct device *dev)
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 10/106 gpu: drm: radeon: Fix a possible null-pointer dereference in radeon_connector_set_property()
In reply to Greg Kroah-HartmanFrom: Jia-Ju Bai <[email protected]>
[ Upstream commit f3eb9b8f67bc28783eddc142ad805ebdc53d6339 ]
In radeon_connector_set_property(), there is an if statement on line 743 to check whether connector->encoder is NULL:
if (connector->encoder)
When connector->encoder is NULL, it is used on line 755:
if (connector->encoder->crtc)
Thus, a possible null-pointer dereference may occur.
To fix this bug, connector->encoder is checked before being used.
This bug is found by a static analysis tool STCheck written by us.
--- drivers/gpu/drm/radeon/radeon_connectors.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/radeon/radeon_connectors.c +1 -1
@@ -751,7 +751,7 @@ static int radeon_connector_set_property(struct drm_connector *connector, struct radeon_encoder->output_csc = val; -if (connector->encoder->crtc) { +if (connector->encoder && connector->encoder->crtc) {struct drm_crtc *crtc = connector->encoder->crtc;struct radeon_crtc *radeon_crtc =to_radeon_crtc (crtc);
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 11/106 PCI: rpaphp: Avoid a sometimes-uninitialized warning
In reply to Greg Kroah-HartmanFrom: Nathan Chancellor <[email protected]>
[ Upstream commit 0df3e42167caaf9f8c7b64de3da40a459979afe8 ]
When building with -Wsometimes-uninitialized, clang warns:
drivers/pci/hotplug/rpaphp_core.c:243:14: warning: variable 'fndit' is used uninitialized whenever 'for' loop exits because its condition is false [-Wsometimes-uninitialized]
for (j = 0; j < entries; j++) {
^~~~~~~~~~~
drivers/pci/hotplug/rpaphp_core.c:256:6: note: uninitialized use occurs
here
if (fndit)
^~~~~
drivers/pci/hotplug/rpaphp_core.c:243:14: note: remove the condition if
it is always true
for (j = 0; j < entries; j++) {
^~~~~~~~~~~
drivers/pci/hotplug/rpaphp_core.c:233:14: note: initialize the variable
'fndit' to silence this warning
int j, fndit;
^
= 0fndit is only used to gate a sprintf call, which can be moved into the loop to simplify the code and eliminate the local variable, which will fix this warning.
--- drivers/pci/hotplug/rpaphp_core.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-)
drivers/pci/hotplug/rpaphp_core.c +7 -11
@@ -230,7 +230,7 @@ static int rpaphp_check_drc_props_v2(struct device_node *dn, char *drc_name,struct of_drc_info drc;const __be32 *value;char cell_drc_name[MAX_DRC_NAME_LEN ]; -int j, fndit; +int j; info =of_find_property (dn->parent,"ibm,drc-info" ,NULL );if (info ==NULL )
@@ -245,17 +245,13 @@ static int rpaphp_check_drc_props_v2(struct device_node *dn, char *drc_name,/* Should now know end of current entry */ -if (my_index > drc.last_drc_index) -continue ; - - fndit =1 ; -break ; +/* Found it */ +if (my_index <= drc.last_drc_index) { +sprintf (cell_drc_name,"%s%d" , drc.drc_name_prefix, + my_index); +break ; + } } -/* Found it */ - -if (fndit) -sprintf (cell_drc_name,"%s%d" , drc.drc_name_prefix, - my_index); if (((drc_name == NULL) || (drc_name && !strcmp(drc_name, cell_drc_name))) &&
Signature · 1 line
2.20.1
Re: [PATCH 4.19 011/106] PCI: rpaphp: Avoid a sometimes-uninitialized warning
Hi!
Quoted 11 lines
From: Nathan Chancellor <[email protected]>
[ Upstream commit
0df3e42167caaf9f8c7b64de3da40a459979afe8]When building with -Wsometimes-uninitialized, clang warns:
drivers/pci/hotplug/rpaphp_core.c:243:14: warning: variable 'fndit' is used uninitialized whenever 'for' loop exits because its condition is false [-Wsometimes-uninitialized]for (j = 0; j < entries; j++) { ^~~~~~~~~~~
...
Quoted 3 lines
fndit is only used to gate a sprintf call, which can be moved into the loop to simplify the code and eliminate the local variable, which will fix this warning.
Well, you fixed the warning, but the code is still buggy:
Quoted 24 lines
+++
b/drivers/pci/hotplug/rpaphp_core.cdrivers/pci/hotplug/rpaphp_core.c +6
-6@@ -230,7 +230,7 @@ static int rpaphp_check_drc_props_v2(struct device_node *dn, char *drc_name,struct of_drc_info drc;const __be32 *value;char cell_drc_name[MAX_DRC_NAME_LEN ]; -int j, fndit; +int j; info =of_find_property (dn->parent,"ibm,drc-info" ,NULL );if (info ==NULL )@@ -245,17 +245,13 @@ static int rpaphp_check_drc_props_v2(struct device_node *dn, char *drc_name,/* Should now know end of current entry */ -if (my_index > drc.last_drc_index) -continue ; - - fndit =1 ; -break ; +/* Found it */ +if (my_index <= drc.last_drc_index) { +sprintf (cell_drc_name,"%s%d" , drc.drc_name_prefix, + my_index); +break ;
drivers/pci/hotplug/rpaphp_core.c static int rpaphp_check_drc_props_v2(struct device_node *dn, char *drc_name, · line 257
Quoted 10 lines
drivers/pci/hotplug/rpaphp_core.c +1
-5+ } } -/* Found it */ - -if (fndit) -sprintf (cell_drc_name,"%s%d" , drc.drc_name_prefix, - my_index); if (((drc_name == NULL) || (drc_name && !strcmp(drc_name, cell_drc_name))) &&
In case we do not find it, cell_drc_name is not initialized, yet we use it in strcmp(). Same bug exists in the mainline.
Best regards,
Pavel
Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
Greg Kroah-Hartman
maintainerPATCH 12/106 ipmi_si: Only schedule continuously in the thread in maintenance mode
In reply to Greg Kroah-HartmanFrom: Corey Minyard <[email protected]>
[ Upstream commit 340ff31ab00bca5c15915e70ad9ada3030c98cf8 ]
ipmi_thread() uses back-to-back schedule() to poll for command completion which, on some machines, can push up CPU consumption and heavily tax the scheduler locks leading to noticeable overall performance degradation.
This was originally added so firmware updates through IPMI would complete in a timely manner. But we can't kill the scheduler locks for that one use case.
Instead, only run schedule() continuously in maintenance mode, where firmware updates should run.
--- drivers/char/ipmi/ipmi_si_intf.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-)
drivers/char/ipmi/ipmi_si_intf.c +19 -5
@@ -221,6 +221,9 @@ struct smi_info {*/ bool irq_enable_broken; +/* Is the driver in maintenance mode? */ +bool in_maintenance_mode; +/* * Did we get an attention that we did not handle? */
@@ -1013,11 +1016,20 @@ static int ipmi_thread(void *data)spin_unlock_irqrestore (&(smi_info->si_lock), flags); busy_wait =ipmi_thread_busy_wait (smi_result, smi_info, &busy_until); -if (smi_result ==SI_SM_CALL_WITHOUT_DELAY ) +if (smi_result ==SI_SM_CALL_WITHOUT_DELAY ) { ;/* do nothing */ -else if (smi_result ==SI_SM_CALL_WITH_DELAY && busy_wait) -schedule (); -else if (smi_result ==SI_SM_IDLE ) { + }else if (smi_result ==SI_SM_CALL_WITH_DELAY && busy_wait) { +/* +* In maintenance mode we run as fast as +* possible to allow firmware updates to +* complete as fast as possible, but normally +* don't bang on the scheduler. +*/ +if (smi_info->in_maintenance_mode) +schedule (); +else +usleep_range (100 ,200 ); + }else if (smi_result ==SI_SM_IDLE ) {if (atomic_read (&smi_info->need_watch)) {schedule_timeout_interruptible (100 ); }else {
@@ -1025,8 +1037,9 @@ static int ipmi_thread(void *data)__set_current_state (TASK_INTERRUPTIBLE );schedule (); } - }else + }else {schedule_timeout_interruptible (1 ); + } }return 0 ; }
@@ -1201,6 +1214,7 @@ static void set_maintenance_mode(void *send_info, bool enable)if (!enable)atomic_set (&smi_info->req_events,0 ); + smi_info->in_maintenance_mode = enable; }static void shutdown_smi (void *send_info);
Signature · 1 line
2.20.1
Re: [PATCH 4.19 012/106] ipmi_si: Only schedule continuously in the thread in maintenance mode
Hi!
Quoted 12 lines
drivers/char/ipmi/ipmi_si_intf.c +3
-4@@ -1013,11 +1016,20 @@ static int ipmi_thread(void *data)spin_unlock_irqrestore (&(smi_info->si_lock), flags); busy_wait =ipmi_thread_busy_wait (smi_result, smi_info, &busy_until); -if (smi_result ==SI_SM_CALL_WITHOUT_DELAY ) +if (smi_result ==SI_SM_CALL_WITHOUT_DELAY ) { ;/* do nothing */ -else if (smi_result ==SI_SM_CALL_WITH_DELAY && busy_wait) -schedule (); -else if (smi_result ==SI_SM_IDLE ) { + }else if (smi_result ==SI_SM_CALL_WITH_DELAY && busy_wait) { +/*
drivers/char/ipmi/ipmi_si_intf.c static int ipmi_thread(void *data) · line 1032
Quoted 10 lines
drivers/char/ipmi/ipmi_si_intf.c +10
-0+* In maintenance mode we run as fast as +* possible to allow firmware updates to +* complete as fast as possible, but normally +* don't bang on the scheduler. +*/ +if (smi_info->in_maintenance_mode) +schedule (); +else +usleep_range (100 ,200 ); + }else if (smi_result ==SI_SM_IDLE ) {
This is quite crazy code. usleep() will need to do magic with high resolution timers to provide 200usec sleep... when all you want to do is unload the scheduler.
cond_resched() should be okay to call in a loop, can the code use that instead?
Best regards,
Pavel
Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
Re: [PATCH 4.19 012/106] ipmi_si: Only schedule continuously in the thread in maintenance mode
Quoted 29 lines · Pavel Machek
Hi!
Quoted 12 lines
drivers/char/ipmi/ipmi_si_intf.c +3
-4@@ -1013,11 +1016,20 @@ static int ipmi_thread(void *data)spin_unlock_irqrestore (&(smi_info->si_lock), flags); busy_wait =ipmi_thread_busy_wait (smi_result, smi_info, &busy_until); -if (smi_result ==SI_SM_CALL_WITHOUT_DELAY ) +if (smi_result ==SI_SM_CALL_WITHOUT_DELAY ) { ;/* do nothing */ -else if (smi_result ==SI_SM_CALL_WITH_DELAY && busy_wait) -schedule (); -else if (smi_result ==SI_SM_IDLE ) { + }else if (smi_result ==SI_SM_CALL_WITH_DELAY && busy_wait) { +/* drivers/char/ipmi/ipmi_si_intf.c static int ipmi_thread(void *data) · line 1032
Quoted 10 lines
drivers/char/ipmi/ipmi_si_intf.c +10
-0+* In maintenance mode we run as fast as +* possible to allow firmware updates to +* complete as fast as possible, but normally +* don't bang on the scheduler. +*/ +if (smi_info->in_maintenance_mode) +schedule (); +else +usleep_range (100 ,200 ); + }else if (smi_result ==SI_SM_IDLE ) {This is quite crazy code.
usleep()will need to do magic with high resolution timers to provide 200usec sleep... when all you want to do is unload the scheduler.
Quoted 2 lines
cond_resched()should be okay to call in a loop, can the code use that instead?
According to Tejun Heo, spinning in a loop sleeping was causing all sorts of issues with banging on scheduler locks on systems with lots of cores. I forgot to add him to the CC on the patch, adding him now for comment.
If cond_resched() would work, though, I'd be happy with that, it's certainly simpler.
-corey
Quoted 7 lines
Best regards,
PavelSignature · 2 lines
(english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
Greg Kroah-Hartman
maintainerPATCH 13/106 clk: qoriq: Fix -Wunused-const-variable
In reply to Greg Kroah-HartmanFrom: Nathan Huckleberry <[email protected]>
[ Upstream commit a95fb581b144b5e73da382eaedb2e32027610597 ]
drivers/clk/clk-qoriq.c:138:38: warning: unused variable 'p5020_cmux_grp1' [-Wunused-const-variable] static const struct clockgen_muxinfo p5020_cmux_grp1
drivers/clk/clk-qoriq.c:146:38: warning: unused variable 'p5020_cmux_grp2' [-Wunused-const-variable] static const struct clockgen_muxinfo p5020_cmux_grp2
In the definition of the p5020 chip, the p2041 chip's info was used instead. The p5020 and p2041 chips have different info. This is most likely a typo.
--- drivers/clk/clk-qoriq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/clk-qoriq.c +1 -1
@@ -610,7 +610,7 @@ static const struct clockgen_chipinfo chipinfo[] = { .guts_compat = "fsl,qoriq-device-config-1.0", .init_periph = p5020_init_periph, .cmux_groups = { - &p2041_cmux_grp1, &p2041_cmux_grp2 + &p5020_cmux_grp1, &p5020_cmux_grp2 }, .cmux_to_group = {0 ,1 ,-1
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 14/106 clk: sunxi-ng: v3s: add missing clock slices for MMC2 module clocks
In reply to Greg Kroah-HartmanFrom: Icenowy Zheng <[email protected]>
[ Upstream commit 720099603d1f62e37b789366d7e89824b009ca28 ]
The MMC2 clock slices are currently not defined in V3s CCU driver, which makes MMC2 not working.
Fix this issue.
--- drivers/clk/sunxi-ng/ccu-sun8i-v3s.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/clk/sunxi-ng/ccu-sun8i-v3s.c +3 -0
@@ -499,6 +499,9 @@ static struct clk_hw_onecell_data sun8i_v3s_hw_clks = { [CLK_MMC1] = &mmc1_clk.common.hw, [CLK_MMC1_SAMPLE] = &mmc1_sample_clk.common.hw, [CLK_MMC1_OUTPUT] = &mmc1_output_clk.common.hw, + [CLK_MMC2] = &mmc2_clk.common.hw, + [CLK_MMC2_SAMPLE] = &mmc2_sample_clk.common.hw, + [CLK_MMC2_OUTPUT] = &mmc2_output_clk.common.hw, [CLK_CE] = &ce_clk.common.hw, [CLK_SPI0] = &spi0_clk.common.hw, [CLK_USB_PHY0] = &usb_phy0_clk.common.hw,
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 15/106 drm/amd/display: fix issue where 252-255 values are clipped
In reply to Greg Kroah-HartmanFrom: Anthony Koo <[email protected]>
[ Upstream commit 1cbcfc975164f397b449efb17f59d81a703090db ]
[Why]
When endpoint is at the boundary of a region, such as at 2^0=1 we find that the last segment has a sharp slope and some points are clipped at the top.
[How]
If end point is 1, which is exactly at the 2^0 region boundary, we need to program an additional region beyond this point.
--- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c +2 -1
@@ -292,9 +292,10 @@ bool cm_helper_translate_curve_to_hw_format( seg_distr[7 ] =4 ; seg_distr[8 ] =4 ; seg_distr[9 ] =4 ; + seg_distr[10 ] =1 ; region_start =-10 ; - region_end =0 ; + region_end =1 ; }for (i = region_end - region_start; i <MAX_REGIONS_NUMBER ; i++)
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 16/106 drm/amd/display: reprogram VM config when system resume
In reply to Greg Kroah-HartmanFrom: Lewis Huang <[email protected]>
[ Upstream commit e5382701c3520b3ed66169a6e4aa6ce5df8c56e0 ]
[Why]
The vm config will be clear to 0 when system enter S4. It will cause hubbub didn't know how to fetch data when system resume. The flip always pending because earliest_inuse_address and request_address are different.
[How]
Reprogram VM config when system resume
--- drivers/gpu/drm/amd/display/dc/core/dc.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/gpu/drm/amd/display/dc/core/dc.c +8 -0
@@ -1585,6 +1585,14 @@ void dc_set_power_state(dc_resource_state_construct (dc, dc->current_state); dc->hwss.init_hw (dc); + +#ifdef CONFIG_DRM_AMD_DC_DCN2_0 +if (dc->hwss.init_sys_ctx !=NULL && + dc->vm_pa_config.valid) { + dc->hwss.init_sys_ctx (dc->hwseq, dc, &dc->vm_pa_config); + } +#endif +break ;default :
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 17/106 powerpc/powernv/ioda2: Allocate TCE table levels on demand for default DMA window
In reply to Greg Kroah-HartmanFrom: Alexey Kardashevskiy <[email protected]>
[ Upstream commit c37c792dec0929dbb6360a609fb00fa20bb16fc2 ]
We allocate only the first level of multilevel TCE tables for KVM already (alloc_userspace_copy==true), and the rest is allocated on demand. This is not enabled though for bare metal.
This removes the KVM limitation (implicit, via the alloc_userspace_copy parameter) and always allocates just the first level. The on-demand allocation of missing levels is already implemented.
As from now on DMA map might happen with disabled interrupts, this allocates TCEs with GFP_ATOMIC; otherwise lockdep reports errors 1]. In practice just a single page is allocated there so chances for failure are quite low.
To save time when creating a new clean table, this skips non-allocated indirect TCE entries in pnv_tce_free just like we already do in the VFIO IOMMU TCE driver.
This changes the default level number from 1 to 2 to reduce the amount of memory required for the default 32bit DMA window at the boot time. The default window size is up to 2GB which requires 4MB of TCEs which is unlikely to be used entirely or at all as most devices these days are 64bit capable so by switching to 2 levels by default we save 4032KB of RAM per a device.
While at this, add __GFP_NOWARN to alloc_pages_node() as the userspace can trigger this path via VFIO, see the failure and try creating a table again with different parameters which might succeed.
[1]:
===
BUG: sleeping function called from invalid context at mm/page_alloc.c:4596
in_atomic(): 1, irqs_disabled(): 1, pid: 1038, name: scsi_eh_1
2 locks held by scsi_eh_1/1038:
#0: 000000005efd659a (&host->eh_mutex){+.+.}, at: ata_eh_acquire+0x34/0x80 #1: 0000000006cf56a6 (&(&host->lock)->rlock){....}, at: ata_exec_internal_sg+0xb0/0x5c0
irq event stamp: 500 hardirqs last enabled at (499): [<c000000000cb8a74>] _raw_spin_unlock_irqrestore+0x94/0xd0 hardirqs last disabled at (500): [<c000000000cb85c4>] _raw_spin_lock_irqsave+0x44/0x120 softirqs last enabled at (0): [<c000000000101120>] copy_process.isra.4.part.5+0x640/0x1a80 softirqs last disabled at (0): [<0000000000000000>] 0x0 CPU: 73 PID: 1038 Comm: scsi_eh_1 Not tainted 5.2.0-rc6-le_nv2_aikATfstn1-p1 #634 Call Trace: [c000003d064cef50] [c000000000c8e6c4] dump_stack+0xe8/0x164 (unreliable) [c000003d064cefa0] [c00000000014ed78] ___might_sleep+0x2f8/0x310 [c000003d064cf020] [c0000000003ca084] __alloc_pages_nodemask+0x2a4/0x1560 [c000003d064cf220] [c0000000000c2530] pnv_alloc_tce_level.isra.0+0x90/0x130 [c000003d064cf290] [c0000000000c2888] pnv_tce+0x128/0x3b0 [c000003d064cf360] [c0000000000c2c00] pnv_tce_build+0xb0/0xf0 [c000003d064cf3c0] [c0000000000bbd9c] pnv_ioda2_tce_build+0x3c/0xb0 [c000003d064cf400] [c00000000004cfe0] ppc_iommu_map_sg+0x210/0x550 [c000003d064cf510] [c00000000004b7a4] dma_iommu_map_sg+0x74/0xb0 [c000003d064cf530] [c000000000863944] ata_qc_issue+0x134/0x470 [c000003d064cf5b0] [c000000000863ec4] ata_exec_internal_sg+0x244/0x5c0 [c000003d064cf700] [c0000000008642d0] ata_exec_internal+0x90/0xe0 [c000003d064cf780] [c0000000008650ac] ata_dev_read_id+0x2ec/0x640 [c000003d064cf8d0] [c000000000878e28] ata_eh_recover+0x948/0x16d0 [c000003d064cfa10] [c00000000087d760] sata_pmp_error_handler+0x480/0xbf0 [c000003d064cfbc0] [c000000000884624] ahci_error_handler+0x74/0xe0 [c000003d064cfbf0] [c000000000879fa8] ata_scsi_port_error_handler+0x2d8/0x7c0 [c000003d064cfca0] [c00000000087a544] ata_scsi_error+0xb4/0x100 [c000003d064cfd00] [c000000000802450] scsi_error_handler+0x120/0x510 [c000003d064cfdb0] [c000000000140c48] kthread+0x1b8/0x1c0 [c000003d064cfe20] [c00000000000bd8c] ret_from_kernel_thread+0x5c/0x70 ata1: SATA link up 6.0 Gbps (SStatus 133 SControl 300) irq event stamp: 2305
========================================================
hardirqs last enabled at (2305): [<c00000000000e4c8>] fast_exc_return_irq+0x28/0x34 hardirqs last disabled at (2303): [<c000000000cb9fd0>] __do_softirq+0x4a0/0x654 WARNING: possible irq lock inversion dependency detected 5.2.0-rc6-le_nv2_aikATfstn1-p1 #634 Tainted: G W softirqs last enabled at (2304): [<c000000000cba054>] __do_softirq+0x524/0x654 softirqs last disabled at (2297): [<c00000000010f278>] irq_exit+0x128/0x180 --------------------------------------------------------
swapper/0/0 just changed the state of lock:0000000006cf56a6 (&(&host->lock)->rlock){-...}, at: ahci_single_level_irq_intr+0xac/0x120 but this lock took another, HARDIRQ-unsafe lock in the past:
(fs_reclaim){+.+.}
and interrupts could create inverse lock ordering between them.
other info that might help us debug this:
Possible interrupt unsafe locking scenario:
CPU0 CPU1
---- ----
lock(fs_reclaim);
local_irq_disable();
lock(&(&host->lock)->rlock);
lock(fs_reclaim);
<Interrupt>
lock(&(&host->lock)->rlock);*** DEADLOCK ***
no locks held by swapper/0/0.
the shortest dependencies between 2nd lock and 1st lock:
-> (fs_reclaim){+.+.} ops: 167579 {
HARDIRQ-ON-W at:
lock_acquire+0xf8/0x2a0
fs_reclaim_acquire.part.23+0x44/0x60
kmem_cache_alloc_node_trace+0x80/0x590
alloc_desc+0x64/0x270
__irq_alloc_descs+0x2e4/0x3a0
irq_domain_alloc_descs+0xb0/0x150
irq_create_mapping+0x168/0x2c0
xics_smp_probe+0x2c/0x98
pnv_smp_probe+0x40/0x9c
smp_prepare_cpus+0x524/0x6c4
kernel_init_freeable+0x1b4/0x650
kernel_init+0x2c/0x148
ret_from_kernel_thread+0x5c/0x70
SOFTIRQ-ON-W at:
lock_acquire+0xf8/0x2a0
fs_reclaim_acquire.part.23+0x44/0x60
kmem_cache_alloc_node_trace+0x80/0x590
alloc_desc+0x64/0x270
__irq_alloc_descs+0x2e4/0x3a0
irq_domain_alloc_descs+0xb0/0x150
irq_create_mapping+0x168/0x2c0
xics_smp_probe+0x2c/0x98
pnv_smp_probe+0x40/0x9c
smp_prepare_cpus+0x524/0x6c4
kernel_init_freeable+0x1b4/0x650
kernel_init+0x2c/0x148
ret_from_kernel_thread+0x5c/0x70
INITIAL USE at:
lock_acquire+0xf8/0x2a0
fs_reclaim_acquire.part.23+0x44/0x60
kmem_cache_alloc_node_trace+0x80/0x590
alloc_desc+0x64/0x270
__irq_alloc_descs+0x2e4/0x3a0
irq_domain_alloc_descs+0xb0/0x150
irq_create_mapping+0x168/0x2c0
xics_smp_probe+0x2c/0x98
pnv_smp_probe+0x40/0x9c
smp_prepare_cpus+0x524/0x6c4
kernel_init_freeable+0x1b4/0x650
kernel_init+0x2c/0x148
ret_from_kernel_thread+0x5c/0x70 }
===
--- arch/powerpc/platforms/powernv/pci-ioda-tce.c | 20 +++++++++---------- arch/powerpc/platforms/powernv/pci.h | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-)
arch/powerpc/platforms/powernv/pci-ioda-tce.c +10 -10
@@ -36,7 +36,8 @@ static __be64 *pnv_alloc_tce_level(int nid, unsigned int shift)struct page *tce_mem =NULL ;__be64 *addr; - tce_mem =alloc_pages_node (nid,GFP_KERNEL , shift -PAGE_SHIFT ); + tce_mem =alloc_pages_node (nid,GFP_ATOMIC | __GFP_NOWARN, + shift -PAGE_SHIFT );if (!tce_mem) {pr_err ("Failed to allocate a TCE memory, level shift=%d\n" , shift);
@@ -161,6 +162,9 @@ void pnv_tce_free(struct iommu_table *tbl, long index, long npages)if (ptce) *ptce =cpu_to_be64 (0 ); +else +/* Skip the rest of the level */ + i |= tbl->it_level_size -1 ; } }
@@ -260,7 +264,6 @@ long pnv_pci_ioda2_table_alloc_pages(int nid, __u64 bus_offset, unsigned int table_shift = max_t(unsigned int, entries_shift + 3,PAGE_SHIFT );const unsigned long tce_table_size =1UL << table_shift; -unsigned int tmplevels = levels;if (!levels || (levels >POWERNV_IOMMU_MAX_LEVELS ))return -EINVAL ;
@@ -268,9 +271,6 @@ long pnv_pci_ioda2_table_alloc_pages(int nid, __u64 bus_offset,if (!is_power_of_2 (window_size))return -EINVAL ; -if (alloc_userspace_copy && (window_size > (1ULL <<32 ))) - tmplevels =1 ; -/* Adjust direct table size from window_size and levels */ entries_shift = (entries_shift + levels -1 ) / levels; level_shift = entries_shift +3 ;
@@ -281,7 +281,7 @@ long pnv_pci_ioda2_table_alloc_pages(int nid, __u64 bus_offset,/* Allocate TCE table */ addr =pnv_pci_ioda2_table_do_alloc_pages (nid, level_shift, - tmplevels, tce_table_size, &offset, &total_allocated); +1 , tce_table_size, &offset, &total_allocated);/* addr==NULL means that the first level allocation failed */ if (!addr)
@@ -292,18 +292,18 @@ long pnv_pci_ioda2_table_alloc_pages(int nid, __u64 bus_offset,* we did not allocate as much as we wanted, * release partially allocated table. */ -if (tmplevels == levels && offset < tce_table_size) +if (levels ==1 && offset < tce_table_size) goto free_tces_exit;/* Allocate userspace view of the TCE table */ if (alloc_userspace_copy) { offset =0 ; uas =pnv_pci_ioda2_table_do_alloc_pages (nid, level_shift, - tmplevels, tce_table_size, &offset, +1 , tce_table_size, &offset, &total_allocated_uas);if (!uas) goto free_tces_exit; -if (tmplevels == levels && (offset < tce_table_size || +if (levels ==1 && (offset < tce_table_size || total_allocated_uas != total_allocated)) goto free_uas_exit; }
@@ -318,7 +318,7 @@ long pnv_pci_ioda2_table_alloc_pages(int nid, __u64 bus_offset,pr_debug ("Created TCE table: ws=%08llx ts=%lx @%08llx base=%lx uas=%p levels=%d/%d\n" , window_size, tce_table_size, bus_offset, tbl->it_base, - tbl->it_userspace, tmplevels, levels); + tbl->it_userspace,1 , levels);return 0 ;
arch/powerpc/platforms/powernv/pci.h +1 -1
@@ -243,7 +243,7 @@ extern void pnv_npu_release_ownership(struct pnv_ioda_pe *npe);extern int pnv_npu2_init (struct pnv_phb *phb);/* pci-ioda-tce.c */ -#define POWERNV_IOMMU_DEFAULT_LEVELS 1 +#define POWERNV_IOMMU_DEFAULT_LEVELS 2#define POWERNV_IOMMU_MAX_LEVELS 5 extern int pnv_tce_build(struct iommu_table *tbl, long index, long npages,
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 18/106 clk: actions: Dont reference clk_init_data after registration
In reply to Greg Kroah-HartmanFrom: Stephen Boyd <[email protected]>
[ Upstream commit cf9ec1fc6d7cceb73e7f1efd079d2eae173fdf57 ]
A future patch is going to change semantics of clk_register() so that clk_hw::init is guaranteed to be NULL after a clk is registered. Avoid referencing this member here so that we don't run into NULL pointer exceptions.
--- drivers/clk/actions/owl-common.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/clk/actions/owl-common.c +3 -2
@@ -67,16 +67,17 @@ int owl_clk_probe(struct device *dev, struct clk_hw_onecell_data *hw_clks)struct clk_hw *hw;for (i =0 ; i < hw_clks->num; i++) { +const char *name; hw = hw_clks->hws[i]; -if (IS_ERR_OR_NULL (hw))continue ; + name = hw->init->name; ret =devm_clk_hw_register (dev, hw);if (ret) {dev_err (dev,"Couldn't register clock %d - %s\n" , - i, hw->init->name); + i, name);return ret; } }
Signature · 1 line
2.20.1
Re: [PATCH 4.19 018/106] clk: actions: Dont reference clk_init_data after registration
Quoted 8 lines · Greg Kroah-Hartman
From: Stephen Boyd <[email protected]>
[ Upstream commit
cf9ec1fc6d7cceb73e7f1efd079d2eae173fdf57]A future patch is going to change semantics of
clk_register()so thatclk_hw::initis guaranteed to be NULL after a clk is registered. Avoid referencing this member here so that we don't run into NULL pointer exceptions.
18,19,20,21: I see the patches make sense for mainline, but why were they selected for stable?
Pavel
Quoted 21 lines
+++
b/drivers/clk/actions/owl-common.cdrivers/clk/actions/owl-common.c +3
-2@@ -67,16 +67,17 @@ int owl_clk_probe(struct device *dev, struct clk_hw_onecell_data *hw_clks)struct clk_hw *hw;for (i =0 ; i < hw_clks->num; i++) { +const char *name; hw = hw_clks->hws[i]; -if (IS_ERR_OR_NULL (hw))continue ; + name = hw->init->name; ret =devm_clk_hw_register (dev, hw);if (ret) {dev_err (dev,"Couldn't register clock %d - %s\n" , - i, hw->init->name); + i, name);return ret; } }
Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
Greg Kroah-Hartman
maintainerPATCH 19/106 clk: sirf: Dont reference clk_init_data after registration
In reply to Greg Kroah-HartmanFrom: Stephen Boyd <[email protected]>
[ Upstream commit af55dadfbce35b4f4c6247244ce3e44b2e242b84 ]
A future patch is going to change semantics of clk_register() so that clk_hw::init is guaranteed to be NULL after a clk is registered. Avoid referencing this member here so that we don't run into NULL pointer exceptions.
--- drivers/clk/sirf/clk-common.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
drivers/clk/sirf/clk-common.c +8 -4
@@ -298,9 +298,10 @@ static u8 dmn_clk_get_parent(struct clk_hw *hw) {struct clk_dmn *clk =to_dmnclk (hw);u32 cfg =clkc_readl (clk->regofs); +const char *name =clk_hw_get_name (hw);/* parent of io domain can only be pll3 */ -if (strcmp (hw->init->name,"io" ) ==0 ) +if (strcmp (name,"io" ) ==0 )return 4 ;WARN_ON ((cfg & (BIT (3 ) -1 )) >4 );
@@ -312,9 +313,10 @@ static int dmn_clk_set_parent(struct clk_hw *hw, u8 parent) {struct clk_dmn *clk =to_dmnclk (hw);u32 cfg =clkc_readl (clk->regofs); +const char *name =clk_hw_get_name (hw);/* parent of io domain can only be pll3 */ -if (strcmp (hw->init->name,"io" ) ==0 ) +if (strcmp (name,"io" ) ==0 )return -EINVAL ; cfg &= ~(BIT (3 ) -1 );
@@ -354,7 +356,8 @@ static long dmn_clk_round_rate(struct clk_hw *hw, unsigned long rate, {unsigned long fin;unsigned ratio, wait, hold; -unsigned bits = (strcmp (hw->init->name,"mem" ) ==0 ) ?3 :4 ; +const char *name =clk_hw_get_name (hw); +unsigned bits = (strcmp (name,"mem" ) ==0 ) ?3 :4 ; fin = *parent_rate; ratio = fin / rate;
@@ -376,7 +379,8 @@ static int dmn_clk_set_rate(struct clk_hw *hw, unsigned long rate,struct clk_dmn *clk =to_dmnclk (hw);unsigned long fin;unsigned ratio, wait, hold, reg; -unsigned bits = (strcmp (hw->init->name,"mem" ) ==0 ) ?3 :4 ; +const char *name =clk_hw_get_name (hw); +unsigned bits = (strcmp (name,"mem" ) ==0 ) ?3 :4 ; fin = parent_rate; ratio = fin / rate;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 20/106 clk: sprd: Dont reference clk_init_data after registration
In reply to Greg Kroah-HartmanFrom: Stephen Boyd <[email protected]>
[ Upstream commit f6c90df8e7e33c3dc33d4d7471bc42c232b0510e ]
A future patch is going to change semantics of clk_register() so that clk_hw::init is guaranteed to be NULL after a clk is registered. Avoid referencing this member here so that we don't run into NULL pointer exceptions.
--- drivers/clk/sprd/common.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/clk/sprd/common.c +3 -2
@@ -71,16 +71,17 @@ int sprd_clk_probe(struct device *dev, struct clk_hw_onecell_data *clkhw)struct clk_hw *hw;for (i =0 ; i < clkhw->num; i++) { +const char *name; hw = clkhw->hws[i]; -if (!hw)continue ; + name = hw->init->name; ret =devm_clk_hw_register (dev, hw);if (ret) {dev_err (dev,"Couldn't register clock %d - %s\n" , - i, hw->init->name); + i, name);return ret; } }
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 21/106 clk: zx296718: Dont reference clk_init_data after registration
In reply to Greg Kroah-HartmanFrom: Stephen Boyd <[email protected]>
[ Upstream commit 1a4549c150e27dbc3aea762e879a88209df6d1a5 ]
A future patch is going to change semantics of clk_register() so that clk_hw::init is guaranteed to be NULL after a clk is registered. Avoid referencing this member here so that we don't run into NULL pointer exceptions.
--- drivers/clk/zte/clk-zx296718.c | 109 +++++++++++++++------------------ 1 file changed, 49 insertions(+), 60 deletions(-)
drivers/clk/zte/clk-zx296718.c +49 -60
@@ -567,6 +567,7 @@ static int __init top_clocks_init(struct device_node *np) {void __iomem *reg_base;int i, ret; +const char *name; reg_base =of_iomap (np,0 );if (!reg_base) {
@@ -576,11 +577,10 @@ static int __init top_clocks_init(struct device_node *np)for (i =0 ; i <ARRAY_SIZE (zx296718_pll_clk); i++) { zx296718_pll_clk[i].reg_base += (uintptr_t )reg_base; + name = zx296718_pll_clk[i].hw.init->name; ret =clk_hw_register (NULL , &zx296718_pll_clk[i].hw); -if (ret) { -pr_warn ("top clk %s init error!\n" , - zx296718_pll_clk[i].hw.init->name); - } +if (ret) +pr_warn ("top clk %s init error!\n" , name); }for (i =0 ; i <ARRAY_SIZE (top_ffactor_clk); i++) {
@@ -588,11 +588,10 @@ static int __init top_clocks_init(struct device_node *np) top_hw_onecell_data.hws[top_ffactor_clk[i].id] = &top_ffactor_clk[i].factor.hw; + name = top_ffactor_clk[i].factor.hw.init->name; ret =clk_hw_register (NULL , &top_ffactor_clk[i].factor.hw); -if (ret) { -pr_warn ("top clk %s init error!\n" , - top_ffactor_clk[i].factor.hw.init->name); - } +if (ret) +pr_warn ("top clk %s init error!\n" , name); }for (i =0 ; i <ARRAY_SIZE (top_mux_clk); i++) {
@@ -601,11 +600,10 @@ static int __init top_clocks_init(struct device_node *np) &top_mux_clk[i].mux.hw; top_mux_clk[i].mux.reg += (uintptr_t )reg_base; + name = top_mux_clk[i].mux.hw.init->name; ret =clk_hw_register (NULL , &top_mux_clk[i].mux.hw); -if (ret) { -pr_warn ("top clk %s init error!\n" , - top_mux_clk[i].mux.hw.init->name); - } +if (ret) +pr_warn ("top clk %s init error!\n" , name); }for (i =0 ; i <ARRAY_SIZE (top_gate_clk); i++) {
@@ -614,11 +612,10 @@ static int __init top_clocks_init(struct device_node *np) &top_gate_clk[i].gate.hw; top_gate_clk[i].gate.reg += (uintptr_t )reg_base; + name = top_gate_clk[i].gate.hw.init->name; ret =clk_hw_register (NULL , &top_gate_clk[i].gate.hw); -if (ret) { -pr_warn ("top clk %s init error!\n" , - top_gate_clk[i].gate.hw.init->name); - } +if (ret) +pr_warn ("top clk %s init error!\n" , name); }for (i =0 ; i <ARRAY_SIZE (top_div_clk); i++) {
@@ -627,11 +624,10 @@ static int __init top_clocks_init(struct device_node *np) &top_div_clk[i].div.hw; top_div_clk[i].div.reg += (uintptr_t )reg_base; + name = top_div_clk[i].div.hw.init->name; ret =clk_hw_register (NULL , &top_div_clk[i].div.hw); -if (ret) { -pr_warn ("top clk %s init error!\n" , - top_div_clk[i].div.hw.init->name); - } +if (ret) +pr_warn ("top clk %s init error!\n" , name); } ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get,
@@ -757,6 +753,7 @@ static int __init lsp0_clocks_init(struct device_node *np) {void __iomem *reg_base;int i, ret; +const char *name; reg_base =of_iomap (np,0 );if (!reg_base) {
@@ -770,11 +767,10 @@ static int __init lsp0_clocks_init(struct device_node *np) &lsp0_mux_clk[i].mux.hw; lsp0_mux_clk[i].mux.reg += (uintptr_t )reg_base; + name = lsp0_mux_clk[i].mux.hw.init->name; ret =clk_hw_register (NULL , &lsp0_mux_clk[i].mux.hw); -if (ret) { -pr_warn ("lsp0 clk %s init error!\n" , - lsp0_mux_clk[i].mux.hw.init->name); - } +if (ret) +pr_warn ("lsp0 clk %s init error!\n" , name); }for (i =0 ; i <ARRAY_SIZE (lsp0_gate_clk); i++) {
@@ -783,11 +779,10 @@ static int __init lsp0_clocks_init(struct device_node *np) &lsp0_gate_clk[i].gate.hw; lsp0_gate_clk[i].gate.reg += (uintptr_t )reg_base; + name = lsp0_gate_clk[i].gate.hw.init->name; ret =clk_hw_register (NULL , &lsp0_gate_clk[i].gate.hw); -if (ret) { -pr_warn ("lsp0 clk %s init error!\n" , - lsp0_gate_clk[i].gate.hw.init->name); - } +if (ret) +pr_warn ("lsp0 clk %s init error!\n" , name); }for (i =0 ; i <ARRAY_SIZE (lsp0_div_clk); i++) {
@@ -796,11 +791,10 @@ static int __init lsp0_clocks_init(struct device_node *np) &lsp0_div_clk[i].div.hw; lsp0_div_clk[i].div.reg += (uintptr_t )reg_base; + name = lsp0_div_clk[i].div.hw.init->name; ret =clk_hw_register (NULL , &lsp0_div_clk[i].div.hw); -if (ret) { -pr_warn ("lsp0 clk %s init error!\n" , - lsp0_div_clk[i].div.hw.init->name); - } +if (ret) +pr_warn ("lsp0 clk %s init error!\n" , name); } ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get,
@@ -865,6 +859,7 @@ static int __init lsp1_clocks_init(struct device_node *np) {void __iomem *reg_base;int i, ret; +const char *name; reg_base =of_iomap (np,0 );if (!reg_base) {
@@ -878,11 +873,10 @@ static int __init lsp1_clocks_init(struct device_node *np) &lsp0_mux_clk[i].mux.hw; lsp1_mux_clk[i].mux.reg += (uintptr_t )reg_base; + name = lsp1_mux_clk[i].mux.hw.init->name; ret =clk_hw_register (NULL , &lsp1_mux_clk[i].mux.hw); -if (ret) { -pr_warn ("lsp1 clk %s init error!\n" , - lsp1_mux_clk[i].mux.hw.init->name); - } +if (ret) +pr_warn ("lsp1 clk %s init error!\n" , name); }for (i =0 ; i <ARRAY_SIZE (lsp1_gate_clk); i++) {
@@ -891,11 +885,10 @@ static int __init lsp1_clocks_init(struct device_node *np) &lsp1_gate_clk[i].gate.hw; lsp1_gate_clk[i].gate.reg += (uintptr_t )reg_base; + name = lsp1_gate_clk[i].gate.hw.init->name; ret =clk_hw_register (NULL , &lsp1_gate_clk[i].gate.hw); -if (ret) { -pr_warn ("lsp1 clk %s init error!\n" , - lsp1_gate_clk[i].gate.hw.init->name); - } +if (ret) +pr_warn ("lsp1 clk %s init error!\n" , name); }for (i =0 ; i <ARRAY_SIZE (lsp1_div_clk); i++) {
@@ -904,11 +897,10 @@ static int __init lsp1_clocks_init(struct device_node *np) &lsp1_div_clk[i].div.hw; lsp1_div_clk[i].div.reg += (uintptr_t )reg_base; + name = lsp1_div_clk[i].div.hw.init->name; ret =clk_hw_register (NULL , &lsp1_div_clk[i].div.hw); -if (ret) { -pr_warn ("lsp1 clk %s init error!\n" , - lsp1_div_clk[i].div.hw.init->name); - } +if (ret) +pr_warn ("lsp1 clk %s init error!\n" , name); } ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get,
@@ -982,6 +974,7 @@ static int __init audio_clocks_init(struct device_node *np) {void __iomem *reg_base;int i, ret; +const char *name; reg_base =of_iomap (np,0 );if (!reg_base) {
@@ -995,11 +988,10 @@ static int __init audio_clocks_init(struct device_node *np) &audio_mux_clk[i].mux.hw; audio_mux_clk[i].mux.reg += (uintptr_t )reg_base; + name = audio_mux_clk[i].mux.hw.init->name; ret =clk_hw_register (NULL , &audio_mux_clk[i].mux.hw); -if (ret) { -pr_warn ("audio clk %s init error!\n" , - audio_mux_clk[i].mux.hw.init->name); - } +if (ret) +pr_warn ("audio clk %s init error!\n" , name); }for (i =0 ; i <ARRAY_SIZE (audio_adiv_clk); i++) {
@@ -1008,11 +1000,10 @@ static int __init audio_clocks_init(struct device_node *np) &audio_adiv_clk[i].hw; audio_adiv_clk[i].reg_base += (uintptr_t )reg_base; + name = audio_adiv_clk[i].hw.init->name; ret =clk_hw_register (NULL , &audio_adiv_clk[i].hw); -if (ret) { -pr_warn ("audio clk %s init error!\n" , - audio_adiv_clk[i].hw.init->name); - } +if (ret) +pr_warn ("audio clk %s init error!\n" , name); }for (i =0 ; i <ARRAY_SIZE (audio_div_clk); i++) {
@@ -1021,11 +1012,10 @@ static int __init audio_clocks_init(struct device_node *np) &audio_div_clk[i].div.hw; audio_div_clk[i].div.reg += (uintptr_t )reg_base; + name = audio_div_clk[i].div.hw.init->name; ret =clk_hw_register (NULL , &audio_div_clk[i].div.hw); -if (ret) { -pr_warn ("audio clk %s init error!\n" , - audio_div_clk[i].div.hw.init->name); - } +if (ret) +pr_warn ("audio clk %s init error!\n" , name); }for (i =0 ; i <ARRAY_SIZE (audio_gate_clk); i++) {
@@ -1034,11 +1024,10 @@ static int __init audio_clocks_init(struct device_node *np) &audio_gate_clk[i].gate.hw; audio_gate_clk[i].gate.reg += (uintptr_t )reg_base; + name = audio_gate_clk[i].gate.hw.init->name; ret =clk_hw_register (NULL , &audio_gate_clk[i].gate.hw); -if (ret) { -pr_warn ("audio clk %s init error!\n" , - audio_gate_clk[i].gate.hw.init->name); - } +if (ret) +pr_warn ("audio clk %s init error!\n" , name); } ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get,
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 22/106 powerpc/xmon: Check for HV mode when dumping XIVE info from OPAL
In reply to Greg Kroah-HartmanFrom: Cédric Le Goater <[email protected]>
[ Upstream commit c3e0dbd7f780a58c4695f1cd8fc8afde80376737 ]
Currently, the xmon 'dx' command calls OPAL to dump the XIVE state in the OPAL logs and also outputs some of the fields of the internal XIVE structures in Linux. The OPAL calls can only be done on baremetal (PowerNV) and they crash a pseries machine. Fix by checking the hypervisor feature of the CPU.
--- arch/powerpc/xmon/xmon.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
arch/powerpc/xmon/xmon.c +9 -6
@@ -2497,13 +2497,16 @@ static void dump_pacas(void)static void dump_one_xive (int cpu) {unsigned int hwid =get_hard_smp_processor_id (cpu); +bool hv =cpu_has_feature (CPU_FTR_HVMODE ); -opal_xive_dump (XIVE_DUMP_TM_HYP , hwid); -opal_xive_dump (XIVE_DUMP_TM_POOL , hwid); -opal_xive_dump (XIVE_DUMP_TM_OS , hwid); -opal_xive_dump (XIVE_DUMP_TM_USER , hwid); -opal_xive_dump (XIVE_DUMP_VP , hwid); -opal_xive_dump (XIVE_DUMP_EMU_STATE , hwid); +if (hv) { +opal_xive_dump (XIVE_DUMP_TM_HYP , hwid); +opal_xive_dump (XIVE_DUMP_TM_POOL , hwid); +opal_xive_dump (XIVE_DUMP_TM_OS , hwid); +opal_xive_dump (XIVE_DUMP_TM_USER , hwid); +opal_xive_dump (XIVE_DUMP_VP , hwid); +opal_xive_dump (XIVE_DUMP_EMU_STATE , hwid); + }if (setjmp (bus_error_jmp) !=0 ) { catch_memory_errors =0 ;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 23/106 powerpc/rtas: use device model APIs and serialization during LPM
In reply to Greg Kroah-HartmanFrom: Nathan Lynch <[email protected]>
[ Upstream commit a6717c01ddc259f6f73364779df058e2c67309f8 ]
The LPAR migration implementation and userspace-initiated cpu hotplug can interleave their executions like so:
1. Set cpu 7 offline via sysfs.
2. Begin a partition migration, whose implementation requires the OS to ensure all present cpus are online; cpu 7 is onlined:
rtas_ibm_suspend_me -> rtas_online_cpus_mask -> cpu_up
This sets cpu 7 online in all respects except for the cpu's corresponding struct device; dev->offline remains true.
3. Set cpu 7 online via sysfs. _cpu_up() determines that cpu 7 is already online and returns success. The driver core (device_online) sets dev->offline = false.
4. The migration completes and restores cpu 7 to offline state:
rtas_ibm_suspend_me -> rtas_offline_cpus_mask -> cpu_down
This leaves cpu7 in a state where the driver core considers the cpu device online, but in all other respects it is offline and unused. Attempts to online the cpu via sysfs appear to succeed but the driver core actually does not pass the request to the lower-level cpuhp support code. This makes the cpu unusable until the cpu device is manually set offline and then online again via sysfs.
Instead of directly calling cpu_up/cpu_down, the migration code should use the higher-level device core APIs to maintain consistent state and serialize operations.
--- arch/powerpc/kernel/rtas.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
arch/powerpc/kernel/rtas.c +8 -3
@@ -875,15 +875,17 @@ static int rtas_cpu_state_change_mask(enum rtas_cpu_state state,return 0 ;for_each_cpu (cpu, cpus) { +struct device *dev =get_cpu_device (cpu); +switch (state) {case DOWN : - cpuret =cpu_down (cpu); + cpuret =device_offline (dev);break ;case UP : - cpuret =cpu_up (cpu); + cpuret =device_online (dev);break ; } -if (cpuret) { +if (cpuret <0 ) { pr_debug("%s: cpu_%s for cpu#%d returned %d.\n", __func__, ((state == UP) ? "up" : "down"),
@@ -972,6 +974,8 @@ int rtas_ibm_suspend_me(u64 handle) data.token =rtas_token ("ibm,suspend-me" ); data.complete = &done; +lock_device_hotplug (); +/* All present CPUs must be online */ cpumask_andnot (offline_mask, cpu_present_mask, cpu_online_mask); cpuret =rtas_online_cpus_mask (offline_mask);
@@ -1003,6 +1007,7 @@ int rtas_ibm_suspend_me(u64 handle) __func__); out: +unlock_device_hotplug ();free_cpumask_var (offline_mask);return atomic_read (&data.error); }
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 24/106 powerpc/futex: Fix warning: oldval may be used uninitialized in this function
In reply to Greg Kroah-HartmanFrom: Christophe Leroy <[email protected]>
[ Upstream commit 38a0d0cdb46d3f91534e5b9839ec2d67be14c59d ]
We see warnings such as:
kernel/futex.c: In function 'do_futex':
kernel/futex.c:1676:17: warning: 'oldval' may be used uninitialized in this function [-Wmaybe-uninitialized]
return oldval == cmparg;
^
kernel/futex.c:1651:6: note: 'oldval' was declared here
int oldval, ret;
^This is because arch_futex_atomic_op_inuser() only sets *oval if ret is 0 and GCC doesn't see that it will only use it when ret is 0.
Anyway, the non-zero ret path is an error path that won't suffer from setting *oval, and as *oval is a local var in futex_atomic_op_inuser() it will have no impact.
--- arch/powerpc/include/asm/futex.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
arch/powerpc/include/asm/futex.h +1 -2
@@ -59,8 +59,7 @@ static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval,pagefault_enable (); -if (!ret) - *oval = oldval; + *oval = oldval;return ret; }
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 25/106 powerpc/pseries/mobility: use cond_resched when updating device tree
In reply to Greg Kroah-HartmanFrom: Nathan Lynch <[email protected]>
[ Upstream commit ccfb5bd71d3d1228090a8633800ae7cdf42a94ac ]
After a partition migration, pseries_devicetree_update() processes changes to the device tree communicated from the platform to Linux. This is a relatively heavyweight operation, with multiple device tree searches, memory allocations, and conversations with partition firmware.
There's a few levels of nested loops which are bounded only by decisions made by the platform, outside of Linux's control, and indeed we have seen RCU stalls on large systems while executing this call graph. Use cond_resched() in these loops so that the cpu is yielded when needed.
--- arch/powerpc/platforms/pseries/mobility.c | 9 +++++++++ 1 file changed, 9 insertions(+)
arch/powerpc/platforms/pseries/mobility.c +9 -0
@@ -12,6 +12,7 @@#include <linux/cpu.h> #include <linux/kernel.h> #include <linux/kobject.h> +#include <linux/sched.h> #include <linux/smp.h> #include <linux/stat.h> #include <linux/completion.h>
@@ -209,7 +210,11 @@ static int update_dt_node(__be32 phandle, s32 scope) prop_data += vd; } + +cond_resched (); } + +cond_resched (); }while (rtas_rc ==1 );of_node_put (dn);
@@ -318,8 +323,12 @@ int pseries_devicetree_update(s32 scope)add_dt_node (phandle, drc_index);break ; } + +cond_resched (); } } + +cond_resched (); }while (rc ==1 );kfree (rtas_buf);
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 26/106 pinctrl: tegra: Fix write barrier placement in pmx_writel
In reply to Greg Kroah-HartmanFrom: Sowjanya Komatineni <[email protected]>
[ Upstream commit c2cf351eba2ff6002ce8eb178452219d2521e38e ]
pmx_writel uses writel which inserts write barrier before the register write.
This patch has fix to replace writel with writel_relaxed followed by a readback and memory barrier to ensure write operation is completed for successful pinctrl change.
--- drivers/pinctrl/tegra/pinctrl-tegra.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/pinctrl/tegra/pinctrl-tegra.c +3 -1
@@ -40,7 +40,9 @@ static inline u32 pmx_readl(struct tegra_pmx *pmx, u32 bank, u32 reg)static inline void pmx_writel (struct tegra_pmx *pmx,u32 val,u32 bank,u32 reg) { -writel (val, pmx->regs[bank] + reg); +writel_relaxed (val, pmx->regs[bank] + reg); +/* make sure pinmux register write completed */ +pmx_readl (pmx, bank, reg); }static int tegra_pinctrl_get_groups_count (struct pinctrl_dev *pctldev)
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 27/106 powerpc/eeh: Clear stale EEH_DEV_NO_HANDLER flag
In reply to Greg Kroah-HartmanFrom: Sam Bobroff <[email protected]>
[ Upstream commit aa06e3d60e245284d1e55497eb3108828092818d ]
The EEH_DEV_NO_HANDLER flag is used by the EEH system to prevent the use of driver callbacks in drivers that have been bound part way through the recovery process. This is necessary to prevent later stage handlers from being called when the earlier stage handlers haven't, which can be confusing for drivers.
However, the flag is set for all devices that are added after boot time and only cleared at the end of the EEH recovery process. This results in hot plugged devices erroneously having the flag set during the first recovery after they are added (causing their driver's handlers to be incorrectly ignored).
To remedy this, clear the flag at the beginning of recovery processing. The flag is still cleared at the end of recovery processing, although it is no longer really necessary.
Also clear the flag during eeh_handle_special_event(), for the same reasons.
--- arch/powerpc/kernel/eeh_driver.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
arch/powerpc/kernel/eeh_driver.c +10 -1
@@ -811,6 +811,10 @@ void eeh_handle_normal_event(struct eeh_pe *pe)pr_warn ("EEH: This PCI device has failed %d times in the last hour and will be permanently disabled after %d failures.\n" , pe->freeze_count, eeh_max_freezes); +eeh_for_each_pe (pe, tmp_pe) +eeh_pe_for_each_dev (tmp_pe, edev, tmp) + edev->mode &= ~EEH_DEV_NO_HANDLER ; +/* Walk the various device drivers attached to this slot through * a reset sequence, giving each an opportunity to do what it needs * to accomplish the reset. Each child gets a report of the
@@ -1004,7 +1008,8 @@ final:*/ void eeh_handle_special_event (void ) { -struct eeh_pe *pe, *phb_pe; +struct eeh_pe *pe, *phb_pe, *tmp_pe; +struct eeh_dev *edev, *tmp_edev;struct pci_bus *bus;struct pci_controller *hose;unsigned long flags;
@@ -1075,6 +1080,10 @@ void eeh_handle_special_event(void) (phb_pe->state & EEH_PE_RECOVERING))continue ; +eeh_for_each_pe (pe, tmp_pe) +eeh_pe_for_each_dev (tmp_pe, edev, tmp_edev) + edev->mode &= ~EEH_DEV_NO_HANDLER ; +/* Notify all devices to be down */ eeh_pe_state_clear (pe,EEH_PE_PRI_BUS );eeh_set_channel_state (pe, pci_channel_io_perm_failure);
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 28/106 vfio_pci: Restore original state on release
In reply to Greg Kroah-HartmanFrom: hexin <[email protected]>
[ Upstream commit 92c8026854c25093946e0d7fe536fd9eac440f06 ]
vfio_pci_enable() saves the device's initial configuration information with the intent that it is restored in vfio_pci_disable(). However, the commit referenced in Fixes: below replaced the call to __pci_reset_function_locked(), which is not wrapped in a state save and restore, with pci_try_reset_function(), which overwrites the restored device state with the current state before applying it to the device. Reinstate use of __pci_reset_function_locked() to return to the desired behavior.
--- drivers/vfio/pci/vfio_pci.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-)
drivers/vfio/pci/vfio_pci.c +13 -4
@@ -373,11 +373,20 @@ static void vfio_pci_disable(struct vfio_pci_device *vdev)pci_write_config_word (pdev,PCI_COMMAND ,PCI_COMMAND_INTX_DISABLE );/* -* Try to reset the device. The success of this is dependent on -* being able to lock the device, which is not always possible. +* Try to get the locks ourselves to prevent a deadlock. The +* success of this is dependent on being able to lock the device, +* which is not always possible. +* We can not use the "try" reset interface here, which will +* overwrite the previously restored configuration information. */ -if (vdev->reset_works && !pci_try_reset_function (pdev)) - vdev->needs_reset = false; +if (vdev->reset_works &&pci_cfg_access_trylock (pdev)) { +if (device_trylock (&pdev->dev)) { +if (!__pci_reset_function_locked (pdev)) + vdev->needs_reset = false; +device_unlock (&pdev->dev); + } +pci_cfg_access_unlock (pdev); + }pci_restore_state (pdev); out:
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 29/106 drm/nouveau/volt: Fix for some cards having 0 maximum voltage
In reply to Greg Kroah-HartmanFrom: Mark Menzynski <[email protected]>
[ Upstream commit a1af2afbd244089560794c260b2d4326a86e39b6 ]
Some, mostly Fermi, vbioses appear to have zero max voltage. That causes Nouveau to not parse voltage entries, thus users not being able to set higher clocks.
When changing this value Nvidia driver still appeared to ignore it, and I wasn't able to find out why, thus the code is ignoring the value if it is zero.
--- drivers/gpu/drm/nouveau/nvkm/subdev/bios/volt.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/nouveau/nvkm/subdev/bios/volt.c +2 -0
@@ -96,6 +96,8 @@ nvbios_volt_parse(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len, info->min =min (info->base, info->base + info->step * info->vidmask); info->max =nvbios_rd32 (bios, volt +0x0e ); +if (!info->max) + info->max =max (info->base, info->base + info->step * info->vidmask);break ;case 0x50 : info->min =nvbios_rd32 (bios, volt +0x0a );
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 30/106 pinctrl: amd: disable spurious-firing GPIO IRQs
In reply to Greg Kroah-HartmanFrom: Daniel Drake <[email protected]>
[ Upstream commit d21b8adbd475dba19ac2086d3306327b4a297418 ]
When cold-booting Asus X434DA, GPIO 7 is found to be already configured as an interrupt, and the GPIO level is found to be in a state that causes the interrupt to fire.
As soon as pinctrl-amd probes, this interrupt fires and invokes amd_gpio_irq_handler(). The IRQ is acked, but no GPIO-IRQ handler was invoked, so the GPIO level being unchanged just causes another interrupt to fire again immediately after.
This results in an interrupt storm causing this platform to hang during boot, right after pinctrl-amd is probed.
Detect this situation and disable the GPIO interrupt when this happens. This enables the affected platform to boot as normal. GPIO 7 actually is the I2C touchpad interrupt line, and later on, i2c-multitouch loads and re-enables this interrupt when it is ready to handle it.
Instead of this approach, I considered disabling all GPIO interrupts at probe time, however that seems a little risky, and I also confirmed that Windows does not seem to have this behaviour: the same 41 GPIO IRQs are enabled under both Linux and Windows, which is a far larger collection than the GPIOs referenced by the DSDT on this platform.
--- drivers/pinctrl/pinctrl-amd.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
drivers/pinctrl/pinctrl-amd.c +11 -1
@@ -569,15 +569,25 @@ static irqreturn_t amd_gpio_irq_handler(int irq, void *dev_id) !(regval & BIT(INTERRUPT_MASK_OFF)))continue ; irq =irq_find_mapping (gc->irq.domain, irqnr + i); -generic_handle_irq (irq); +if (irq !=0 ) +generic_handle_irq (irq);/* Clear interrupt. * We must read the pin register again, in case the * value was changed while executing * generic_handle_irq() above. +* If we didn't find a mapping for the interrupt, +* disable it in order to avoid a system hang caused +* by an interrupt storm. */ raw_spin_lock_irqsave (&gpio_dev->lock, flags); regval =readl (regs + i); +if (irq ==0 ) { + regval &= ~BIT (INTERRUPT_ENABLE_OFF ); +dev_dbg (&gpio_dev->pdev->dev, +"Disabling spurious GPIO IRQ %d\n" , + irqnr + i); + }writel (regval, regs + i);raw_spin_unlock_irqrestore (&gpio_dev->lock, flags); ret =IRQ_HANDLED ;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 31/106 clk: renesas: mstp: Set GENPD_FLAG_ALWAYS_ON for clock domain
In reply to Greg Kroah-HartmanFrom: Geert Uytterhoeven <[email protected]>
[ Upstream commit a459a184c978ca9ad538aab93aafdde873953f30 ]
The CPG/MSTP Clock Domain driver does not implement the generic_pm_domain.power_{on,off}() callbacks, as the domain itself cannot be powered down. Hence the domain should be marked as always-on by setting the GENPD_FLAG_ALWAYS_ON flag, to prevent the core PM Domain code from considering it for power-off, and doing unnessary processing.
This also gets rid of a boot warning when the Clock Domain contains an IRQ-safe device, e.g. on RZ/A1:
sh_mtu2 fcff0000.timer: PM domain cpg_clocks will not be powered off
--- drivers/clk/renesas/clk-mstp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/clk/renesas/clk-mstp.c +2 -1
@@ -341,7 +341,8 @@ void __init cpg_mstp_add_clk_domain(struct device_node *np)return ; pd->name = np->name; - pd->flags =GENPD_FLAG_PM_CLK |GENPD_FLAG_ACTIVE_WAKEUP ; + pd->flags =GENPD_FLAG_PM_CLK |GENPD_FLAG_ALWAYS_ON | +GENPD_FLAG_ACTIVE_WAKEUP ; pd->attach_dev = cpg_mstp_attach_dev; pd->detach_dev = cpg_mstp_detach_dev;pm_genpd_init (pd, &pm_domain_always_on_gov, false);
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 32/106 clk: renesas: cpg-mssr: Set GENPD_FLAG_ALWAYS_ON for clock domain
In reply to Greg Kroah-HartmanFrom: Geert Uytterhoeven <[email protected]>
[ Upstream commit f787216f33ce5b5a2567766398f44ab62157114c ]
The CPG/MSSR Clock Domain driver does not implement the generic_pm_domain.power_{on,off}() callbacks, as the domain itself cannot be powered down. Hence the domain should be marked as always-on by setting the GENPD_FLAG_ALWAYS_ON flag, to prevent the core PM Domain code from considering it for power-off, and doing unnessary processing.
Note that this only affects RZ/A2 SoCs. On R-Car Gen2 and Gen3 SoCs, the R-Car SYSC driver handles Clock Domain creation, and offloads only device attachment/detachment to the CPG/MSSR driver.
--- drivers/clk/renesas/renesas-cpg-mssr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/clk/renesas/renesas-cpg-mssr.c +2 -1
@@ -514,7 +514,8 @@ static int __init cpg_mssr_add_clk_domain(struct device *dev, genpd = &pd->genpd; genpd->name = np->name; - genpd->flags =GENPD_FLAG_PM_CLK |GENPD_FLAG_ACTIVE_WAKEUP ; + genpd->flags =GENPD_FLAG_PM_CLK |GENPD_FLAG_ALWAYS_ON | +GENPD_FLAG_ACTIVE_WAKEUP ; genpd->attach_dev = cpg_mssr_attach_dev; genpd->detach_dev = cpg_mssr_detach_dev;pm_genpd_init (genpd, &pm_domain_always_on_gov, false);
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 33/106 drm/amd/display: support spdif
In reply to Greg Kroah-HartmanFrom: Charlene Liu <[email protected]>
[ Upstream commit b5a41620bb88efb9fb31a4fa5e652e3d5bead7d4 ]
[Description]
port spdif fix to staging:
spdif hardwired to afmt inst 1.
spdif func pointer
spdif resource allocation (reserve last audio endpoint for spdif only)
--- .../gpu/drm/amd/display/dc/core/dc_resource.c | 17 ++++++++--------- drivers/gpu/drm/amd/display/dc/dce/dce_audio.c | 4 ++-- 2 files changed, 10 insertions(+), 11 deletions(-)
drivers/gpu/drm/amd/display/dc/core/dc_resource.c +8 -9
@@ -229,12 +229,10 @@ bool resource_construct(DC_ERR ("DC: failed to create audio!\n" );return false; } -if (!aud->funcs->endpoint_valid (aud)) { aud->funcs->destroy (&aud);break ; } - pool->audios[i] = aud; pool->audio_count++; }
@@ -1703,24 +1701,25 @@ static struct audio *find_first_free_audio(const struct resource_pool *pool, enum engine_id id) { - int i; -for (i =0 ; i < pool->audio_count; i++) { + int i, available_audio_count; + + available_audio_count = pool->audio_count; + +for (i =0 ; i < available_audio_count; i++) {if ((res_ctx->is_audio_acquired[i] == false) && (res_ctx->is_stream_enc_acquired[i] == true)) {/*we have enough audio endpoint, find the matching inst*/ if (id != i)continue ; -return pool->audios[i]; } } -/* use engine id to find free audio */ -if ((id < pool->audio_count) && (res_ctx->is_audio_acquired[id] == false)) { +/* use engine id to find free audio */ +if ((id < available_audio_count) && (res_ctx->is_audio_acquired[id] == false)) {return pool->audios[id]; } -/*not found the matching one, first come first serve*/ -for (i =0 ; i < pool->audio_count; i++) { +for (i =0 ; i < available_audio_count; i++) {if (res_ctx->is_audio_acquired[i] == false) {return pool->audios[i]; }
drivers/gpu/drm/amd/display/dc/dce/dce_audio.c +2 -2
@@ -611,6 +611,8 @@ void dce_aud_az_configure(AZ_REG_WRITE (AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO1 , value); +DC_LOG_HW_AUDIO ("\n\tAUDIO:az_configure: index: %u data, 0x%x, displayName %s: \n" , + audio->inst, value, audio_info->display_name);/* *write the port ID:
@@ -922,7 +924,6 @@ static const struct audio_funcs funcs = { .az_configure = dce_aud_az_configure, .destroy = dce_aud_destroy, }; -void dce_aud_destroy (struct audio **audio) {struct dce_audio *aud =DCE_AUD (*audio);
@@ -953,7 +954,6 @@ struct audio *dce_audio_create( audio->regs = reg; audio->shifts = shifts; audio->masks = masks; -return &audio->base; }
Signature · 1 line
2.20.1
Re: [PATCH 4.19 033/106] drm/amd/display: support spdif
Hi!
Quoted 7 lines
[ Upstream commit
b5a41620bb88efb9fb31a4fa5e652e3d5bead7d4][Description]
port spdif fix to staging:
spdif hardwired to afmt inst 1.
spdif func pointer
spdif resource allocation (reserve last audio endpoint for spdif only)
I'm sorry, but I don't understand this changelog. Code below modifies whitespace, adds a debug output, and uses local variable for pool->audio_count.
Does not seem to be a bugfix, and does not seem to do anything with staging.
Best regards,
Pavel
Quoted 76 lines
+++
b/drivers/gpu/drm/amd/display/dc/core/dc_resource.cdrivers/gpu/drm/amd/display/dc/core/dc_resource.c +8
-9@@ -229,12 +229,10 @@ bool resource_construct(DC_ERR ("DC: failed to create audio!\n" );return false; } -if (!aud->funcs->endpoint_valid (aud)) { aud->funcs->destroy (&aud);break ; } - pool->audios[i] = aud; pool->audio_count++; }@@ -1703,24 +1701,25 @@ static struct audio *find_first_free_audio(const struct resource_pool *pool, enum engine_id id) { - int i; -for (i =0 ; i < pool->audio_count; i++) { + int i, available_audio_count; + + available_audio_count = pool->audio_count; + +for (i =0 ; i < available_audio_count; i++) {if ((res_ctx->is_audio_acquired[i] == false) && (res_ctx->is_stream_enc_acquired[i] == true)) {/*we have enough audio endpoint, find the matching inst*/ if (id != i)continue ; -return pool->audios[i]; } } -/* use engine id to find free audio */ -if ((id < pool->audio_count) && (res_ctx->is_audio_acquired[id] == false)) { +/* use engine id to find free audio */ +if ((id < available_audio_count) && (res_ctx->is_audio_acquired[id] == false)) {return pool->audios[id]; } -/*not found the matching one, first come first serve*/ -for (i =0 ; i < pool->audio_count; i++) { +for (i =0 ; i < available_audio_count; i++) {if (res_ctx->is_audio_acquired[i] == false) {return pool->audios[i]; }drivers/gpu/drm/amd/display/dc/dce/dce_audio.c +2
-2@@ -611,6 +611,8 @@ void dce_aud_az_configure(AZ_REG_WRITE (AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO1 , value); +DC_LOG_HW_AUDIO ("\n\tAUDIO:az_configure: index: %u data, 0x%x, displayName %s: \n" , + audio->inst, value, audio_info->display_name);/* *write the port ID: @@ -922,7 +924,6 @@ static const struct audio_funcs funcs = { .az_configure = dce_aud_az_configure, .destroy = dce_aud_destroy, }; -void dce_aud_destroy (struct audio **audio) {struct dce_audio *aud =DCE_AUD (*audio);@@ -953,7 +954,6 @@ struct audio *dce_audio_create( audio->regs = reg; audio->shifts = shifts; audio->masks = masks; -return &audio->base; }
Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
Greg Kroah-Hartman
maintainerRe: [PATCH 4.19 033/106] drm/amd/display: support spdif
Quoted 10 lines · Pavel Machek
Hi!
Quoted 7 lines
[ Upstream commit
b5a41620bb88efb9fb31a4fa5e652e3d5bead7d4][Description]
port spdif fix to staging:
spdif hardwired to afmt inst 1.
spdif func pointer
spdif resource allocation (reserve last audio endpoint for spdif only)
Quoted 6 lines
I'm sorry, but I don't understand this changelog. Code below modifies whitespace, adds a debug output, and uses local variable for
pool->audio_count.Does not seem to be a bugfix, and does not seem to do anything with staging.
That's what the original changelog had in it, so I kept it.
thanks,
greg k-h
Re: [PATCH 4.19 033/106] drm/amd/display: support spdif
In reply to Pavel Machek+Harry
You're completely right. This was part of a larger patch dealing with embargoed code and is meaningless without the embargoed code. It should've been caught and never gone upstream. We've already put some new processes in place to deal with patches like this going forward.
This isn't a good candidate for stable trees but shouldn't really hurt anything if it's already in.
Quoted 96 lines · Pavel Machek
Hi!
Quoted 7 lines
[ Upstream commit
b5a41620bb88efb9fb31a4fa5e652e3d5bead7d4][Description]
port spdif fix to staging:
spdif hardwired to afmt inst 1.
spdif func pointer
spdif resource allocation (reserve last audio endpoint for spdif only)I'm sorry, but I don't understand this changelog. Code below modifies whitespace, adds a debug output, and uses local variable for
pool->audio_count.Does not seem to be a bugfix, and does not seem to do anything with staging.
Best regards,
PavelQuoted 76 lines
+++
b/drivers/gpu/drm/amd/display/dc/core/dc_resource.cdrivers/gpu/drm/amd/display/dc/core/dc_resource.c +8
-9@@ -229,12 +229,10 @@ bool resource_construct(DC_ERR ("DC: failed to create audio!\n" );return false; } -if (!aud->funcs->endpoint_valid (aud)) { aud->funcs->destroy (&aud);break ; } - pool->audios[i] = aud; pool->audio_count++; }@@ -1703,24 +1701,25 @@ static struct audio *find_first_free_audio(const struct resource_pool *pool, enum engine_id id) { - int i; -for (i =0 ; i < pool->audio_count; i++) { + int i, available_audio_count; + + available_audio_count = pool->audio_count; + +for (i =0 ; i < available_audio_count; i++) {if ((res_ctx->is_audio_acquired[i] == false) && (res_ctx->is_stream_enc_acquired[i] == true)) {/*we have enough audio endpoint, find the matching inst*/ if (id != i)continue ; -return pool->audios[i]; } } -/* use engine id to find free audio */ -if ((id < pool->audio_count) && (res_ctx->is_audio_acquired[id] == false)) { +/* use engine id to find free audio */ +if ((id < available_audio_count) && (res_ctx->is_audio_acquired[id] == false)) {return pool->audios[id]; } -/*not found the matching one, first come first serve*/ -for (i =0 ; i < pool->audio_count; i++) { +for (i =0 ; i < available_audio_count; i++) {if (res_ctx->is_audio_acquired[i] == false) {return pool->audios[i]; }drivers/gpu/drm/amd/display/dc/dce/dce_audio.c +2
-2@@ -611,6 +611,8 @@ void dce_aud_az_configure(AZ_REG_WRITE (AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO1 , value); +DC_LOG_HW_AUDIO ("\n\tAUDIO:az_configure: index: %u data, 0x%x, displayName %s: \n" , + audio->inst, value, audio_info->display_name);/* *write the port ID: @@ -922,7 +924,6 @@ static const struct audio_funcs funcs = { .az_configure = dce_aud_az_configure, .destroy = dce_aud_destroy, }; -void dce_aud_destroy (struct audio **audio) {struct dce_audio *aud =DCE_AUD (*audio);@@ -953,7 +954,6 @@ struct audio *dce_audio_create( audio->regs = reg; audio->shifts = shifts; audio->masks = masks; -return &audio->base; }
Greg Kroah-Hartman
maintainerPATCH 34/106 drm/amdgpu/si: fix ASIC tests
In reply to Greg Kroah-HartmanFrom: Jean Delvare <[email protected]>
[ Upstream commit 77efe48a729588527afb4d5811b9e0acb29f5e51 ]
Comparing adev->family with CHIP constants is not correct. adev->family can only be compared with AMDGPU_FAMILY constants and adev->asic_type is the struct member to compare with CHIP constants. They are separate identification spaces.
--- drivers/gpu/drm/amd/amdgpu/si.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/gpu/drm/amd/amdgpu/si.c +3 -3
@@ -1813,7 +1813,7 @@ static void si_program_aspm(struct amdgpu_device *adev)if (orig != data)si_pif_phy1_wreg (adev,PB1_PIF_PWRDOWN_1 , data); -if ((adev->family !=CHIP_OLAND ) && (adev->family !=CHIP_HAINAN )) { +if ((adev->asic_type !=CHIP_OLAND ) && (adev->asic_type !=CHIP_HAINAN )) { orig = data =si_pif_phy0_rreg (adev,PB0_PIF_PWRDOWN_0 ); data &= ~PLL_RAMP_UP_TIME_0_MASK ;if (orig != data)
@@ -1862,14 +1862,14 @@ static void si_program_aspm(struct amdgpu_device *adev) orig = data =si_pif_phy0_rreg (adev,PB0_PIF_CNTL ); data &= ~LS2_EXIT_TIME_MASK ; -if ((adev->family ==CHIP_OLAND ) || (adev->family ==CHIP_HAINAN )) +if ((adev->asic_type ==CHIP_OLAND ) || (adev->asic_type ==CHIP_HAINAN )) data |=LS2_EXIT_TIME (5 );if (orig != data)si_pif_phy0_wreg (adev,PB0_PIF_CNTL , data); orig = data =si_pif_phy1_rreg (adev,PB1_PIF_CNTL ); data &= ~LS2_EXIT_TIME_MASK ; -if ((adev->family ==CHIP_OLAND ) || (adev->family ==CHIP_HAINAN )) +if ((adev->asic_type ==CHIP_OLAND ) || (adev->asic_type ==CHIP_HAINAN )) data |=LS2_EXIT_TIME (5 );if (orig != data)si_pif_phy1_wreg (adev,PB1_PIF_CNTL , data);
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 35/106 powerpc/64s/exception: machine check use correct cfar for late handler
In reply to Greg Kroah-HartmanFrom: Nicholas Piggin <[email protected]>
[ Upstream commit 0b66370c61fcf5fcc1d6901013e110284da6e2bb ]
Bare metal machine checks run an "early" handler in real mode before running the main handler which reports the event.
The main handler runs exactly as a normal interrupt handler, after the "windup" which sets registers back as they were at interrupt entry. CFAR does not get restored by the windup code, so that will be wrong when the handler is run.
Restore the CFAR to the saved value before running the late handler.
--- arch/powerpc/kernel/exceptions-64s.S | 4 ++++ 1 file changed, 4 insertions(+)
arch/powerpc/kernel/exceptions-64s.S +4 -0
@@ -520,6 +520,10 @@ EXC_COMMON_BEGIN(machine_check_handle_early) RFI_TO_USER_OR_KERNEL 9: /* Deliver the machine check to host kernel in V mode. */ +BEGIN_FTR_SECTION + ld r10,ORIG_GPR3(r1) + mtspr SPRN_CFAR,r10 +END_FTR_SECTION_IFSET(CPU_FTR_CFAR) MACHINE_CHECK_HANDLER_WINDUP b machine_check_pSeries
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 36/106 pstore: fs superblock limits
In reply to Greg Kroah-HartmanFrom: Deepa Dinamani <[email protected]>
[ Upstream commit 83b8a3fbe3aa82ac3c253b698ae6a9be2dbdd5e0 ]
Leaving granularity at 1ns because it is dependent on the specific attached backing pstore module. ramoops has microsecond resolution.
Fix the readback of ramoops fractional timestamp microseconds, which has incorrectly been reporting the value as nanoseconds.
--- fs/pstore/ram.c | 2 ++ 1 file changed, 2 insertions(+)
fs/pstore/ram.c +2 -0
@@ -162,6 +162,7 @@ static int ramoops_read_kmsg_hdr(char *buffer, struct timespec64 *time,if (sscanf (buffer,RAMOOPS_KERNMSG_HDR "%lld.%lu-%c\n%n" , (time64_t *)&time->tv_sec, &time->tv_nsec, &data_type, &header_length) ==3 ) { + time->tv_nsec *=1000 ;if (data_type =='C' ) *compressed = true;else
@@ -169,6 +170,7 @@ static int ramoops_read_kmsg_hdr(char *buffer, struct timespec64 *time, }else if (sscanf (buffer,RAMOOPS_KERNMSG_HDR "%lld.%lu\n%n" , (time64_t *)&time->tv_sec, &time->tv_nsec, &header_length) ==2 ) { + time->tv_nsec *=1000 ; *compressed = false; }else { time->tv_sec =0 ;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 37/106 clk: qcom: gcc-sdm845: Use floor ops for sdcc clks
In reply to Greg Kroah-HartmanFrom: Stephen Boyd <[email protected]>
[ Upstream commit 5e4b7e82d497580bc430576c4c9bce157dd72512 ]
Some MMC cards fail to enumerate properly when inserted into an MMC slot on sdm845 devices. This is because the clk ops for qcom clks round the frequency up to the nearest rate instead of down to the nearest rate. For example, the MMC driver requests a frequency of 52MHz from clk_set_rate() but the qcom implementation for these clks rounds 52MHz up to the next supported frequency of 100MHz. The MMC driver could be modified to request clk rate ranges but for now we can fix this in the clk driver by changing the rounding policy for this clk to be round down instead of round up.
--- drivers/clk/qcom/gcc-sdm845.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/clk/qcom/gcc-sdm845.c +2 -2
@@ -647,7 +647,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { .name = "gcc_sdcc2_apps_clk_src", .parent_names = gcc_parent_names_10, .num_parents = 5, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_floor_ops, }, };
@@ -671,7 +671,7 @@ static struct clk_rcg2 gcc_sdcc4_apps_clk_src = { .name = "gcc_sdcc4_apps_clk_src", .parent_names = gcc_parent_names_0, .num_parents = 4, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_floor_ops, }, };
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 38/106 powerpc/pseries: correctly track irq state in default idle
In reply to Greg Kroah-HartmanFrom: Nathan Lynch <[email protected]>
[ Upstream commit 92c94dfb69e350471473fd3075c74bc68150879e ]
prep_irq_for_idle() is intended to be called before entering H_CEDE (and it is used by the pseries cpuidle driver). However the default pseries idle routine does not call it, leading to mismanaged lazy irq state when the cpuidle driver isn't in use. Manifestations of this include:
* Dropped IPIs in the time immediately after a cpu comes online (before it has installed the cpuidle handler), making the online operation block indefinitely waiting for the new cpu to respond.
* Hitting this WARN_ON in arch_local_irq_restore():
/* * We should already be hard disabled here. We had bugs * where that wasn't the case so let's dbl check it and * warn if we are wrong. Only do that when IRQ tracing * is enabled as mfmsr() can be costly. */ if (WARN_ON_ONCE(mfmsr() & MSR_EE)) __hard_irq_disable();
Call prep_irq_for_idle() from pseries_lpar_idle() and honor its result.
--- arch/powerpc/platforms/pseries/setup.c | 3 +++ 1 file changed, 3 insertions(+)
arch/powerpc/platforms/pseries/setup.c +3 -0
@@ -325,6 +325,9 @@ static void pseries_lpar_idle(void)* low power mode by ceding processor to hypervisor */ +if (!prep_irq_for_idle ()) +return ; +/* Indicate to hypervisor that we are idle. */ get_lppaca ()->idle =1 ;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 39/106 pinctrl: meson-gxbb: Fix wrong pinning definition for uart_c
In reply to Greg Kroah-HartmanFrom: Otto Meier <[email protected]>
[ Upstream commit cb0438e4436085d89706b5ccfce4d5da531253de ]
Hi i tried to use the uart_C of the the odroid-c2.
I enabled it in the dts file. During boot it crashed when the the sdcard slot is addressed.
After long search in the net i found this:
https://forum.odroid.com/viewtopic.php?f=139&t=25371&p=194370&hilit=uart_C#p177856
After changing the pin definitions accordingly erverything works. Uart_c is functioning and sdcard ist working.
--- drivers/pinctrl/meson/pinctrl-meson-gxbb.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/pinctrl/meson/pinctrl-meson-gxbb.c +6 -6
@@ -198,8 +198,8 @@ static const unsigned int uart_rts_b_pins[] = { GPIODV_27 };static const unsigned int uart_tx_c_pins[] = {GPIOY_13 };static const unsigned int uart_rx_c_pins[] = {GPIOY_14 }; -static const unsigned int uart_cts_c_pins[] = {GPIOX_11 }; -static const unsigned int uart_rts_c_pins[] = {GPIOX_12 }; +static const unsigned int uart_cts_c_pins[] = {GPIOY_11 }; +static const unsigned int uart_rts_c_pins[] = {GPIOY_12 };static const unsigned int i2c_sck_a_pins[] = {GPIODV_25 };static const unsigned int i2c_sda_a_pins[] = {GPIODV_24 };
@@ -445,10 +445,10 @@ static struct meson_pmx_group meson_gxbb_periphs_groups[] = {GROUP (pwm_f_x,3 ,18 ),/* Bank Y */ -GROUP (uart_cts_c,1 ,19 ), -GROUP (uart_rts_c,1 ,18 ), -GROUP (uart_tx_c,1 ,17 ), -GROUP (uart_rx_c,1 ,16 ), +GROUP (uart_cts_c,1 ,17 ), +GROUP (uart_rts_c,1 ,16 ), +GROUP (uart_tx_c,1 ,19 ), +GROUP (uart_rx_c,1 ,18 ),GROUP (pwm_a_y,1 ,21 ),GROUP (pwm_f_y,1 ,20 ), GROUP(i2s_out_ch23_y, 1, 5),
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 40/106 arm64: fix unreachable code issue with cmpxchg
In reply to Greg Kroah-HartmanFrom: Arnd Bergmann <[email protected]>
[ Upstream commit 920fdab7b3ce98c14c840261e364f490f3679a62 ]
On arm64 build with clang, sometimes the __cmpxchg_mb is not inlined when CONFIG_OPTIMIZE_INLINING is set.
Clang then fails a compile-time assertion, because it cannot tell at compile time what the size of the argument is:
mm/memcontrol.o: In function `__cmpxchg_mb':
memcontrol.c:(.text+0x1a4c): undefined reference to __compiletime_assert_175' memcontrol.c:(.text+0x1a4c): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol __compiletime_assert_175'
Mark all of the cmpxchg() style functions as __always_inline to ensure that the compiler can see the result.
--- arch/arm64/include/asm/cmpxchg.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
arch/arm64/include/asm/cmpxchg.h +3 -3
@@ -74,7 +74,7 @@ __XCHG_CASE( , , mb_8, dmb ish, nop, , a, l, "memory")#undef __XCHG_CASE#define __XCHG_GEN (sfx) \ -static inline unsigned long __xchg##sfx(unsigned long x, \ +static __always_inline unsigned long __xchg##sfx(unsigned long x, \ volatile void *ptr, \ int size) \ { \
@@ -116,7 +116,7 @@ __XCHG_GEN(_mb)#define xchg (...) __xchg_wrapper( _mb, __VA_ARGS__)#define __CMPXCHG_GEN (sfx) \ -static inline unsigned long __cmpxchg##sfx(volatile void *ptr, \ +static __always_inline unsigned long __cmpxchg##sfx(volatile void *ptr, \ unsigned long old, \ unsigned long new, \ int size) \
@@ -223,7 +223,7 @@ __CMPWAIT_CASE( , , 8);#undef __CMPWAIT_CASE#define __CMPWAIT_GEN (sfx) \ -static inline void __cmpwait##sfx(volatile void *ptr, \ +static __always_inline void __cmpwait##sfx(volatile void *ptr, \ unsigned long val, \ int size) \ { \
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 41/106 clk: at91: select parent if main oscillator or bypass is enabled
In reply to Greg Kroah-HartmanFrom: Eugen Hristev <[email protected]>
[ Upstream commit 69a6bcde7fd3fe6f3268ce26f31d9d9378384c98 ]
Selecting the right parent for the main clock is done using only main oscillator enabled bit.
In case we have this oscillator bypassed by an external signal (no driving on the XOUT line), we still use external clock, but with BYPASS bit set. So, in this case we must select the same parent as before. Create a macro that will select the right parent considering both bits from the MOR register.
Use this macro when looking for the right parent.
--- drivers/clk/at91/clk-main.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
drivers/clk/at91/clk-main.c +7 -3
@@ -27,6 +27,10 @@#define MOR_KEY_MASK (0xff << 16) +#define clk_main_parent_select (s) (((s) & \ + (AT91_PMC_MOSCEN | \ + AT91_PMC_OSCBYPASS)) ? 1 : 0) +struct clk_main_osc {struct clk_hw hw;struct regmap *regmap;
@@ -119,7 +123,7 @@ static int clk_main_osc_is_prepared(struct clk_hw *hw)regmap_read (regmap,AT91_PMC_SR , &status); -return (status &AT91_PMC_MOSCS ) && (tmp &AT91_PMC_MOSCEN ); +return (status &AT91_PMC_MOSCS ) &&clk_main_parent_select (tmp); }static const struct clk_ops main_osc_ops = {
@@ -530,7 +534,7 @@ static u8 clk_sam9x5_main_get_parent(struct clk_hw *hw)regmap_read (clkmain->regmap,AT91_CKGR_MOR , &status); -return status &AT91_PMC_MOSCEN ?1 :0 ; +return clk_main_parent_select (status); }static const struct clk_ops sam9x5_main_ops = {
@@ -572,7 +576,7 @@ at91_clk_register_sam9x5_main(struct regmap *regmap, clkmain->hw.init = &init; clkmain->regmap = regmap;regmap_read (clkmain->regmap,AT91_CKGR_MOR , &status); - clkmain->parent = status &AT91_PMC_MOSCEN ?1 :0 ; + clkmain->parent =clk_main_parent_select (status); hw = &clkmain->hw; ret =clk_hw_register (NULL , &clkmain->hw);
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 42/106 powerpc: dump kernel log before carrying out fadump or kdump
In reply to Greg Kroah-HartmanFrom: Ganesh Goudar <[email protected]>
[ Upstream commit e7ca44ed3ba77fc26cf32650bb71584896662474 ]
Since commit 4388c9b3a6ee ("powerpc: Do not send system reset request through the oops path"), pstore dmesg file is not updated when dump is triggered from HMC. This commit modified system reset (sreset) handler to invoke fadump or kdump (if configured), without pushing dmesg to pstore. This leaves pstore to have old dmesg data which won't be much of a help if kdump fails to capture the dump. This patch fixes that by calling kmsg_dump() before heading to fadump ot kdump.
--- arch/powerpc/kernel/traps.c | 1 + 1 file changed, 1 insertion(+)
arch/powerpc/kernel/traps.c +1 -0
@@ -399,6 +399,7 @@ void system_reset_exception(struct pt_regs *regs)if (debugger (regs)) goto out; +kmsg_dump (KMSG_DUMP_OOPS );/* * A system reset is a request to dump, so we always send * it through the crashdump code (if fadump or kdump are
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 43/106 mbox: qcom: add APCS child device for QCS404
In reply to Greg Kroah-HartmanFrom: Jorge Ramirez-Ortiz <[email protected]>
[ Upstream commit 78c86458a440ff356073c21b568cb58ddb67b82b ]
There is clock controller functionality in the APCS hardware block of qcs404 devices similar to msm8916.
--- drivers/mailbox/qcom-apcs-ipc-mailbox.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/mailbox/qcom-apcs-ipc-mailbox.c +6 -2
@@ -55,7 +55,6 @@ static const struct mbox_chan_ops qcom_apcs_ipc_ops = {static int qcom_apcs_ipc_probe (struct platform_device *pdev) { -struct device_node *np = pdev->dev.of_node;struct qcom_apcs_ipc *apcs;struct regmap *regmap;struct resource *res;
@@ -63,6 +62,11 @@ static int qcom_apcs_ipc_probe(struct platform_device *pdev)void __iomem *base;unsigned long i;int ret; +const struct of_device_id apcs_clk_match_table[] = { + { .compatible ="qcom,msm8916-apcs-kpss-global" , }, + { .compatible ="qcom,qcs404-apcs-apps-global" , }, + {} + }; apcs =devm_kzalloc (&pdev->dev,sizeof (*apcs),GFP_KERNEL );if (!apcs)
@@ -97,7 +101,7 @@ static int qcom_apcs_ipc_probe(struct platform_device *pdev)return ret; } -if (of_device_is_compatible (np,"qcom,msm8916-apcs-kpss-global" )) { +if (of_match_device (apcs_clk_match_table, &pdev->dev)) { apcs->clk =platform_device_register_data (&pdev->dev,"qcom-apcs-msm8916-clk" ,-1 ,NULL ,0 );
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 44/106 clk: sprd: add missing kfree
In reply to Greg Kroah-HartmanFrom: Chunyan Zhang <[email protected]>
[ Upstream commit 5e75ea9c67433a065b0e8595ad3c91c7c0ca0d2d ]
The number of config registers for different pll clocks probably are not same, so we have to use malloc, and should free the memory before return.
--- drivers/clk/sprd/pll.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/clk/sprd/pll.c +2 -0
@@ -136,6 +136,7 @@ static unsigned long _sprd_pll_recalc_rate(const struct sprd_pll *pll, k2 + refin * nint *CLK_PLL_1M ; } +kfree (cfg);return rate; }
@@ -222,6 +223,7 @@ static int _sprd_pll_set_rate(const struct sprd_pll *pll,if (!ret)udelay (pll->udelay); +kfree (cfg);return ret; }
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 45/106 scsi: core: Reduce memory required for SCSI logging
In reply to Greg Kroah-HartmanFrom: Bart Van Assche <[email protected]>
[ Upstream commit dccc96abfb21dc19d69e707c38c8ba439bba7160 ]
The data structure used for log messages is so large that it can cause a boot failure. Since allocations from that data structure can fail anyway, use kmalloc() / kfree() instead of that data structure.
See also https://bugzilla.kernel.org/show_bug.cgi?id=204119.
See also commit ded85c193a39 ("scsi: Implement per-cpu logging buffer") # v4.0.
--- drivers/scsi/scsi_logging.c | 48 +++---------------------------------- include/scsi/scsi_dbg.h | 2 -- 2 files changed, 3 insertions(+), 47 deletions(-)
drivers/scsi/scsi_logging.c +3 -45
@@ -16,57 +16,15 @@#include <scsi/scsi_eh.h> #include <scsi/scsi_dbg.h> -#define SCSI_LOG_SPOOLSIZE 4096 - -#if (SCSI_LOG_SPOOLSIZE /SCSI_LOG_BUFSIZE ) >BITS_PER_LONG -#warning SCSI logging bitmask too large -#endif - -struct scsi_log_buf { -char buffer[SCSI_LOG_SPOOLSIZE ]; -unsigned long map; -}; - -static DEFINE_PER_CPU(struct scsi_log_buf, scsi_format_log); -static char *scsi_log_reserve_buffer (size_t *len) { -struct scsi_log_buf *buf; -unsigned long map_bits =sizeof (buf->buffer) /SCSI_LOG_BUFSIZE ; -unsigned long idx =0 ; - -preempt_disable (); - buf =this_cpu_ptr (&scsi_format_log); - idx =find_first_zero_bit (&buf->map, map_bits); -if (likely (idx < map_bits)) { -while (test_and_set_bit (idx, &buf->map)) { - idx =find_next_zero_bit (&buf->map, map_bits, idx); -if (idx >= map_bits) -break ; - } - } -if (WARN_ON (idx >= map_bits)) { -preempt_enable (); -return NULL ; - } - *len =SCSI_LOG_BUFSIZE ; -return buf->buffer + idx *SCSI_LOG_BUFSIZE ; + *len =128 ; +return kmalloc (*len,GFP_ATOMIC ); }static void scsi_log_release_buffer (char *bufptr) { -struct scsi_log_buf *buf; -unsigned long idx; -int ret; - - buf =this_cpu_ptr (&scsi_format_log); -if (bufptr >= buf->buffer && - bufptr < buf->buffer +SCSI_LOG_SPOOLSIZE ) { - idx = (bufptr - buf->buffer) /SCSI_LOG_BUFSIZE ; - ret =test_and_clear_bit (idx, &buf->map); -WARN_ON (!ret); - } -preempt_enable (); +kfree (bufptr); }static inline const char *scmd_name (const struct scsi_cmnd *scmd)
include/scsi/scsi_dbg.h +0 -2
@@ -6,8 +6,6 @@ struct scsi_cmnd;struct scsi_device ;struct scsi_sense_hdr ; -#define SCSI_LOG_BUFSIZE 128 -extern void scsi_print_command (struct scsi_cmnd *);extern size_t __scsi_format_command (char *,size_t ,const unsigned char *,size_t );
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 46/106 dma-buf/sw_sync: Synchronize signal vs syncpt free
In reply to Greg Kroah-HartmanFrom: Chris Wilson <[email protected]>
[ Upstream commit d3c6dd1fb30d3853c2012549affe75c930f4a2f9 ]
During release of the syncpt, we remove it from the list of syncpt and the tree, but only if it is not already been removed. However, during signaling, we first remove the syncpt from the list. So, if we concurrently free and signal the syncpt, the free may decide that it is not part of the tree and immediately free itself -- meanwhile the signaler goes on to use the now freed datastructure.
In particular, we get struck by commit 0e2f733addbf ("dma-buf: make dma_fence structure a bit smaller v2") as the cb_list is immediately clobbered by the kfree_rcu.
v2: Avoid calling into timeline_fence_release() from under the spinlock
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=111381
--- drivers/dma-buf/sw_sync.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-)
drivers/dma-buf/sw_sync.c +7 -9
@@ -141,17 +141,14 @@ static void timeline_fence_release(struct dma_fence *fence) {struct sync_pt *pt =dma_fence_to_sync_pt (fence);struct sync_timeline *parent =dma_fence_parent (fence); +unsigned long flags; +spin_lock_irqsave (fence->lock, flags);if (!list_empty (&pt->link)) { -unsigned long flags; - -spin_lock_irqsave (fence->lock, flags); -if (!list_empty (&pt->link)) { -list_del (&pt->link); -rb_erase (&pt->node, &parent->pt_tree); - } -spin_unlock_irqrestore (fence->lock, flags); +list_del (&pt->link); +rb_erase (&pt->node, &parent->pt_tree); } +spin_unlock_irqrestore (fence->lock, flags);sync_timeline_put (parent);dma_fence_free (fence);
@@ -274,7 +271,8 @@ static struct sync_pt *sync_pt_create(struct sync_timeline *obj, p = &parent->rb_left; }else {if (dma_fence_get_rcu (&other->base)) { -dma_fence_put (&pt->base); +sync_timeline_put (obj); +kfree (pt); pt = other; goto unlock; }
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 47/106 ext4: fix potential use after free after remounting with noblock_validity
In reply to Greg Kroah-HartmanFrom: zhangyi (F) <[email protected]>
[ Upstream commit 7727ae52975d4f4ef7ff69ed8e6e25f6a4168158 ]
Remount process will release system zone which was allocated before if "noblock_validity" is specified. If we mount an ext4 file system to two mountpoints with default mount options, and then remount one of them with "noblock_validity", it may trigger a use after free problem when someone accessing the other one.
# mount /dev/sda foo # mount /dev/sda bar
User access mountpoint "foo" | Remount mountpoint "bar"
|
ext4_map_blocks() | ext4_remount()
check_block_validity() | ext4_setup_system_zone()
ext4_data_block_valid() | ext4_release_system_zone()
| free system_blks rb nodes
access system_blks rb nodes |
trigger use after free |This problem can also be reproduced by one mountpint, At the same time, add_system_zone() can get called during remount as well so there can be racing ext4_data_block_valid() reading the rbtree at the same time.
This patch add RCU to protect system zone from releasing or building when doing a remount which inverse current "noblock_validity" mount option. It assign the rbtree after the whole tree was complete and do actual freeing after rcu grace period, avoid any intermediate state.
--- fs/ext4/block_validity.c | 189 ++++++++++++++++++++++++++++----------- fs/ext4/ext4.h | 10 ++- 2 files changed, 147 insertions(+), 52 deletions(-)
fs/ext4/block_validity.c +138 -51
@@ -38,6 +38,7 @@ int __init ext4_init_system_zone(void)void ext4_exit_system_zone (void ) { +rcu_barrier ();kmem_cache_destroy (ext4_system_zone_cachep); }
@@ -49,17 +50,26 @@ static inline int can_merge(struct ext4_system_zone *entry1,return 0 ; } +static void release_system_zone (struct ext4_system_blocks *system_blks) +{ +struct ext4_system_zone *entry, *n; + +rbtree_postorder_for_each_entry_safe (entry, n, + &system_blks->root, node) +kmem_cache_free (ext4_system_zone_cachep, entry); +} +/* * Mark a range of blocks as belonging to the "system zone" --- that * is, filesystem metadata blocks which should never be used by * inodes. */ -static int add_system_zone (struct ext4_sb_info *sbi, +static int add_system_zone (struct ext4_system_blocks *system_blks,ext4_fsblk_t start_blk,unsigned int count) {struct ext4_system_zone *new_entry =NULL , *entry; -struct rb_node **n = &sbi->system_blks.rb_node, *node; +struct rb_node **n = &system_blks->root.rb_node, *node;struct rb_node *parent =NULL , *new_node =NULL ;while (*n) {
@@ -91,7 +101,7 @@ static int add_system_zone(struct ext4_sb_info *sbi, new_node = &new_entry->node;rb_link_node (new_node, parent, n); -rb_insert_color (new_node, &sbi->system_blks); +rb_insert_color (new_node, &system_blks->root); }/* Can we merge to the left? */
@@ -101,7 +111,7 @@ static int add_system_zone(struct ext4_sb_info *sbi,if (can_merge (entry, new_entry)) { new_entry->start_blk = entry->start_blk; new_entry->count += entry->count; -rb_erase (node, &sbi->system_blks); +rb_erase (node, &system_blks->root);kmem_cache_free (ext4_system_zone_cachep, entry); } }
@@ -112,7 +122,7 @@ static int add_system_zone(struct ext4_sb_info *sbi, entry = rb_entry(node, struct ext4_system_zone, node);if (can_merge (new_entry, entry)) { new_entry->count += entry->count; -rb_erase (node, &sbi->system_blks); +rb_erase (node, &system_blks->root);kmem_cache_free (ext4_system_zone_cachep, entry); } }
@@ -126,7 +136,7 @@ static void debug_print_tree(struct ext4_sb_info *sbi)int first =1 ;printk (KERN_INFO "System zones: " ); - node =rb_first (&sbi->system_blks); + node =rb_first (&sbi->system_blks->root);while (node) { entry = rb_entry(node, struct ext4_system_zone, node); printk(KERN_CONT "%s%llu-%llu", first ? "" : ", ",
@@ -137,7 +147,47 @@ static void debug_print_tree(struct ext4_sb_info *sbi)printk (KERN_CONT "\n" ); } -static int ext4_protect_reserved_inode (struct super_block *sb,u32 ino) +/* +* Returns 1 if the passed-in block region (start_blk, +* start_blk+count) is valid; 0 if some part of the block region +* overlaps with filesystem metadata blocks. +*/ +static int ext4_data_block_valid_rcu (struct ext4_sb_info *sbi, +struct ext4_system_blocks *system_blks, +ext4_fsblk_t start_blk, +unsigned int count) +{ +struct ext4_system_zone *entry; +struct rb_node *n; + +if ((start_blk <=le32_to_cpu (sbi->s_es->s_first_data_block)) || + (start_blk + count < start_blk) || + (start_blk + count >ext4_blocks_count (sbi->s_es))) { + sbi->s_es->s_last_error_block =cpu_to_le64 (start_blk); +return 0 ; + } + +if (system_blks ==NULL ) +return 1 ; + + n = system_blks->root.rb_node; +while (n) { + entry = rb_entry(n, struct ext4_system_zone, node); +if (start_blk + count -1 < entry->start_blk) + n = n->rb_left; +else if (start_blk >= (entry->start_blk + entry->count)) + n = n->rb_right; +else { + sbi->s_es->s_last_error_block =cpu_to_le64 (start_blk); +return 0 ; + } + } +return 1 ; +} + +static int ext4_protect_reserved_inode (struct super_block *sb, +struct ext4_system_blocks *system_blks, +u32 ino) {struct inode *inode;struct ext4_sb_info *sbi =EXT4_SB (sb);
@@ -163,14 +213,15 @@ static int ext4_protect_reserved_inode(struct super_block *sb, u32 ino)if (n ==0 ) { i++; }else { -if (!ext4_data_block_valid (sbi, map.m_pblk, n)) { +if (!ext4_data_block_valid_rcu (sbi, system_blks, + map.m_pblk, n)) {ext4_error (sb,"blocks %llu-%llu from inode %u " "overlap system zone" , map.m_pblk, map.m_pblk + map.m_len -1 , ino); err = -EFSCORRUPTED ;break ; } - err =add_system_zone (sbi, map.m_pblk, n); + err =add_system_zone (system_blks, map.m_pblk, n);if (err <0 )break ; i += n;
@@ -180,93 +231,129 @@ static int ext4_protect_reserved_inode(struct super_block *sb, u32 ino)return err; } +static void ext4_destroy_system_zone (struct rcu_head *rcu) +{ +struct ext4_system_blocks *system_blks; + + system_blks = container_of(rcu, struct ext4_system_blocks, rcu); +release_system_zone (system_blks); +kfree (system_blks); +} + +/* +* Build system zone rbtree which is used for block validity checking. +* +* The update of system_blks pointer in this function is protected by +* sb->s_umount semaphore. However we have to be careful as we can be +* racing with ext4_data_block_valid() calls reading system_blks rbtree +* protected only by RCU. That's why we first build the rbtree and then +* swap it in place. +*/ int ext4_setup_system_zone (struct super_block *sb) {ext4_group_t ngroups =ext4_get_groups_count (sb);struct ext4_sb_info *sbi =EXT4_SB (sb); +struct ext4_system_blocks *system_blks;struct ext4_group_desc *gdp;ext4_group_t i;int flex_size =ext4_flex_bg_size (sbi);int ret;if (!test_opt (sb,BLOCK_VALIDITY )) { -if (sbi->system_blks.rb_node) +if (sbi->system_blks)ext4_release_system_zone (sb);return 0 ; } -if (sbi->system_blks.rb_node) +if (sbi->system_blks)return 0 ; + system_blks =kzalloc (sizeof (*system_blks),GFP_KERNEL ); +if (!system_blks) +return -ENOMEM ; +for (i=0 ; i < ngroups; i++) {if (ext4_bg_has_super (sb, i) && ((i <5 ) || ((i % flex_size) ==0 ))) -add_system_zone (sbi,ext4_group_first_block_no (sb, i), +add_system_zone (system_blks, +ext4_group_first_block_no (sb, i),ext4_bg_num_gdb (sb, i) +1 ); gdp =ext4_get_group_desc (sb, i,NULL ); - ret =add_system_zone (sbi,ext4_block_bitmap (sb, gdp),1 ); + ret =add_system_zone (system_blks, +ext4_block_bitmap (sb, gdp),1 );if (ret) -return ret; - ret =add_system_zone (sbi,ext4_inode_bitmap (sb, gdp),1 ); + goto err; + ret =add_system_zone (system_blks, +ext4_inode_bitmap (sb, gdp),1 );if (ret) -return ret; - ret =add_system_zone (sbi,ext4_inode_table (sb, gdp), + goto err; + ret =add_system_zone (system_blks, +ext4_inode_table (sb, gdp), sbi->s_itb_per_group);if (ret) -return ret; + goto err; }if (ext4_has_feature_journal (sb) && sbi->s_es->s_journal_inum) { - ret =ext4_protect_reserved_inode (sb, + ret =ext4_protect_reserved_inode (sb, system_blks,le32_to_cpu (sbi->s_es->s_journal_inum));if (ret) -return ret; + goto err; } +/* +* System blks rbtree complete, announce it once to prevent racing +* with ext4_data_block_valid() accessing the rbtree at the same +* time. +*/ +rcu_assign_pointer (sbi->system_blks, system_blks); +if (test_opt (sb,DEBUG ))debug_print_tree (sbi);return 0 ; +err: +release_system_zone (system_blks); +kfree (system_blks); +return ret; } -/* Called when the filesystem is unmounted */ +/* +* Called when the filesystem is unmounted or when remounting it with +* noblock_validity specified. +* +* The update of system_blks pointer in this function is protected by +* sb->s_umount semaphore. However we have to be careful as we can be +* racing with ext4_data_block_valid() calls reading system_blks rbtree +* protected only by RCU. So we first clear the system_blks pointer and +* then free the rbtree only after RCU grace period expires. +*/ void ext4_release_system_zone (struct super_block *sb) { -struct ext4_system_zone *entry, *n; +struct ext4_system_blocks *system_blks; -rbtree_postorder_for_each_entry_safe (entry, n, - &EXT4_SB (sb)->system_blks, node) -kmem_cache_free (ext4_system_zone_cachep, entry); + system_blks =rcu_dereference_protected (EXT4_SB (sb)->system_blks, +lockdep_is_held (&sb->s_umount)); +rcu_assign_pointer (EXT4_SB (sb)->system_blks,NULL ); -EXT4_SB (sb)->system_blks =RB_ROOT ; +if (system_blks) +call_rcu (&system_blks->rcu, ext4_destroy_system_zone); } -/* -* Returns 1 if the passed-in block region (start_blk, -* start_blk+count) is valid; 0 if some part of the block region -* overlaps with filesystem metadata blocks. -*/ int ext4_data_block_valid (struct ext4_sb_info *sbi,ext4_fsblk_t start_blk,unsigned int count) { -struct ext4_system_zone *entry; -struct rb_node *n = sbi->system_blks.rb_node; +struct ext4_system_blocks *system_blks; +int ret; -if ((start_blk <=le32_to_cpu (sbi->s_es->s_first_data_block)) || - (start_blk + count < start_blk) || - (start_blk + count >ext4_blocks_count (sbi->s_es))) { - sbi->s_es->s_last_error_block =cpu_to_le64 (start_blk); -return 0 ; - } -while (n) { - entry = rb_entry(n, struct ext4_system_zone, node); -if (start_blk + count -1 < entry->start_blk) - n = n->rb_left; -else if (start_blk >= (entry->start_blk + entry->count)) - n = n->rb_right; -else { - sbi->s_es->s_last_error_block =cpu_to_le64 (start_blk); -return 0 ; - } - } -return 1 ; +/* +* Lock the system zone to prevent it being released concurrently +* when doing a remount which inverse current "[no]block_validity" +* mount option. +*/ +rcu_read_lock (); + system_blks =rcu_dereference (sbi->system_blks); + ret =ext4_data_block_valid_rcu (sbi, system_blks, start_blk, + count); +rcu_read_unlock (); +return ret; } int ext4_check_blockref(const char *function, unsigned int line,
fs/ext4/ext4.h +9 -1
@@ -194,6 +194,14 @@ struct ext4_map_blocks {unsigned int m_flags; }; +/* +* Block validity checking, system zone rbtree. +*/ +struct ext4_system_blocks { +struct rb_root root; +struct rcu_head rcu; +}; +/* * Flags for ext4_io_end->flags */
@@ -1409,7 +1417,7 @@ struct ext4_sb_info {int s_jquota_fmt;/* Format of quota to use */ #endif unsigned int s_want_extra_isize;/* New inodes should reserve # bytes */ -struct rb_root system_blks; +struct ext4_system_blocks __rcu *system_blks;#ifdef EXTENTS_STATS /* ext4 extents stats */
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 48/106 MIPS: Ingenic: Disable broken BTB lookup optimization.
In reply to Greg Kroah-HartmanFrom: Zhou Yanjie <[email protected]>
[ Upstream commit 053951dda71ecb4b554a2cdbe26f5f6f9bee9dd2 ]
In order to further reduce power consumption, the XBurst core by default attempts to avoid branch target buffer lookups by detecting & special casing loops. This feature will cause BogoMIPS and lpj calculate in error. Set cp0 config7 bit 4 to disable this feature.
--- arch/mips/include/asm/mipsregs.h | 4 ++++ arch/mips/kernel/cpu-probe.c | 7 +++++++ 2 files changed, 11 insertions(+)
arch/mips/include/asm/mipsregs.h +4 -0
@@ -688,6 +688,9 @@#define MIPS_CONF7_IAR (_ULCAST_(1) << 10)#define MIPS_CONF7_AR (_ULCAST_(1) << 16) +/* Ingenic Config7 bits */ +#define MIPS_CONF7_BTB_LOOP_EN (_ULCAST_(1) << 4) +/* Config7 Bits specific to MIPS Technologies. */ /* Performance counters implemented Per TC */
@@ -2774,6 +2777,7 @@ __BUILD_SET_C0(status) __BUILD_SET_C0(cause) __BUILD_SET_C0(config) __BUILD_SET_C0(config5) +__BUILD_SET_C0(config7) __BUILD_SET_C0(intcontrol) __BUILD_SET_C0(intctl) __BUILD_SET_C0(srsmap)
arch/mips/kernel/cpu-probe.c +7 -0
@@ -1879,6 +1879,13 @@ static inline void cpu_probe_ingenic(struct cpuinfo_mips *c, unsigned int cpu) c->cputype =CPU_JZRISC ; c->writecombine = _CACHE_UNCACHED_ACCELERATED; __cpu_name[cpu] ="Ingenic JZRISC" ; +/* +* The XBurst core by default attempts to avoid branch target +* buffer lookups by detecting & special casing loops. This +* feature will cause BogoMIPS and lpj calculate in error. +* Set cp0 config7 bit 4 to disable this feature. +*/ +set_c0_config7 (MIPS_CONF7_BTB_LOOP_EN );break ;default :panic ("Unknown Ingenic Processor ID!" );
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 49/106 MIPS: tlbex: Explicitly cast _PAGE_NO_EXEC to a boolean
In reply to Greg Kroah-HartmanFrom: Nathan Chancellor <[email protected]>
[ Upstream commit c59ae0a1055127dd3828a88e111a0db59b254104 ]
clang warns:
arch/mips/mm/tlbex.c:634:19: error: use of logical '&&' with constant operand [-Werror,-Wconstant-logical-operand]
if (cpu_has_rixi && _PAGE_NO_EXEC) {
^ ~~~~~~~~~~~~~
arch/mips/mm/tlbex.c:634:19: note: use '&' for a bitwise operation
if (cpu_has_rixi && _PAGE_NO_EXEC) {
^~
&
arch/mips/mm/tlbex.c:634:19: note: remove constant to silence this
warning
if (cpu_has_rixi && _PAGE_NO_EXEC) {
~^~~~~~~~~~~~~~~~1 error generated.
Explicitly cast this value to a boolean so that clang understands we intend for this to be a non-zero value.
--- arch/mips/mm/tlbex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/mips/mm/tlbex.c +1 -1
@@ -630,7 +630,7 @@ static __maybe_unused void build_convert_pte_to_entrylo(u32 **p,return ; } -if (cpu_has_rixi && _PAGE_NO_EXEC) { +if (cpu_has_rixi && !!_PAGE_NO_EXEC) {if (fill_includes_sw_bits) {UASM_i_ROTR (p, reg, reg,ilog2 (_PAGE_GLOBAL)); }else {
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 50/106 i2c-cht-wc: Fix lockdep warning
In reply to Greg Kroah-HartmanFrom: Hans de Goede <[email protected]>
[ Upstream commit 232219b9a464c2479c98aa589acb1bd3383ae9d6 ]
When the kernel is build with lockdep support and the i2c-cht-wc driver is used, the following warning is shown:
[ 66.674334] ======================================================
[ 66.674337] WARNING: possible circular locking dependency detected
[ 66.674340] 5.3.0-rc4+ #83 Not tainted
[ 66.674342] ------------------------------------------------------
[ 66.674345] systemd-udevd/1232 is trying to acquire lock:
[ 66.674349] 00000000a74dab07 (intel_soc_pmic_chtwc:167:(&cht_wc_regmap_cfg)->lock){+.+.}, at: regmap_write+0x31/0x70
[ 66.674360]
but task is already holding lock:
[ 66.674362] 00000000d44a85b7 (i2c_register_adapter){+.+.}, at: i2c_smbus_xfer+0x49/0xf0
[ 66.674370]
which lock already depends on the new lock.[ 66.674371]
the existing dependency chain (in reverse order) is:
[ 66.674374]
-> #1 (i2c_register_adapter){+.+.}:
[ 66.674381] rt_mutex_lock_nested+0x46/0x60
[ 66.674384] i2c_smbus_xfer+0x49/0xf0
[ 66.674387] i2c_smbus_read_byte_data+0x45/0x70
[ 66.674391] cht_wc_byte_reg_read+0x35/0x50
[ 66.674394] _regmap_read+0x63/0x1a0
[ 66.674396] _regmap_update_bits+0xa8/0xe0
[ 66.674399] regmap_update_bits_base+0x63/0xa0
[ 66.674403] regmap_irq_update_bits.isra.0+0x3b/0x50
[ 66.674406] regmap_add_irq_chip+0x592/0x7a0
[ 66.674409] devm_regmap_add_irq_chip+0x89/0xed
[ 66.674412] cht_wc_probe+0x102/0x158
[ 66.674415] i2c_device_probe+0x95/0x250
[ 66.674419] really_probe+0xf3/0x380
[ 66.674422] driver_probe_device+0x59/0xd0
[ 66.674425] device_driver_attach+0x53/0x60
[ 66.674428] __driver_attach+0x92/0x150
[ 66.674431] bus_for_each_dev+0x7d/0xc0
[ 66.674434] bus_add_driver+0x14d/0x1f0
[ 66.674437] driver_register+0x6d/0xb0
[ 66.674440] i2c_register_driver+0x45/0x80
[ 66.674445] do_one_initcall+0x60/0x2f4
[ 66.674450] kernel_init_freeable+0x20d/0x2b4
[ 66.674453] kernel_init+0xa/0x10c
[ 66.674457] ret_from_fork+0x3a/0x50
[ 66.674459]
-> #0 (intel_soc_pmic_chtwc:167:(&cht_wc_regmap_cfg)->lock){+.+.}:
[ 66.674465] __lock_acquire+0xe07/0x1930
[ 66.674468] lock_acquire+0x9d/0x1a0
[ 66.674472] __mutex_lock+0xa8/0x9a0
[ 66.674474] regmap_write+0x31/0x70
[ 66.674480] cht_wc_i2c_adap_smbus_xfer+0x72/0x240 [i2c_cht_wc]
[ 66.674483] __i2c_smbus_xfer+0x1a3/0x640
[ 66.674486] i2c_smbus_xfer+0x67/0xf0
[ 66.674489] i2c_smbus_read_byte_data+0x45/0x70
[ 66.674494] bq24190_probe+0x26b/0x410 [bq24190_charger]
[ 66.674497] i2c_device_probe+0x189/0x250
[ 66.674500] really_probe+0xf3/0x380
[ 66.674503] driver_probe_device+0x59/0xd0
[ 66.674506] device_driver_attach+0x53/0x60
[ 66.674509] __driver_attach+0x92/0x150
[ 66.674512] bus_for_each_dev+0x7d/0xc0
[ 66.674515] bus_add_driver+0x14d/0x1f0
[ 66.674518] driver_register+0x6d/0xb0
[ 66.674521] i2c_register_driver+0x45/0x80
[ 66.674524] do_one_initcall+0x60/0x2f4
[ 66.674528] do_init_module+0x5c/0x230
[ 66.674531] load_module+0x2707/0x2a20
[ 66.674534] __do_sys_init_module+0x188/0x1b0
[ 66.674537] do_syscall_64+0x5c/0xb0
[ 66.674541] entry_SYSCALL_64_after_hwframe+0x49/0xbe
[ 66.674543]
other info that might help us debug this:[ 66.674545] Possible unsafe locking scenario:
[ 66.674547] CPU0 CPU1
[ 66.674548] ---- ----
[ 66.674550] lock(i2c_register_adapter);
[ 66.674553] lock(intel_soc_pmic_chtwc:167:(&cht_wc_regmap_cfg)->lock);
[ 66.674556] lock(i2c_register_adapter);
[ 66.674559] lock(intel_soc_pmic_chtwc:167:(&cht_wc_regmap_cfg)->lock);
[ 66.674561]
*** DEADLOCK ***The problem is that the CHT Whiskey Cove PMIC's builtin i2c-adapter is itself a part of an i2c-client (the PMIC). This means that transfers done through it take adapter->bus_lock twice, once for the parent i2c-adapter and once for its own bus_lock. Lockdep does not like this nested locking.
To make lockdep happy in the case of busses with muxes, the i2c-core's i2c_adapter_lock_bus function calls:
rt_mutex_lock_nested(&adapter->bus_lock, i2c_adapter_depth(adapter));
But i2c_adapter_depth only works when the direct parent of the adapter is another adapter, as it is only meant for muxes. In this case there is an i2c-client and MFD instantiated platform_device in the parent->child chain between the 2 devices.
This commit overrides the default i2c_lock_operations, passing a hardcoded depth of 1 to rt_mutex_lock_nested, making lockdep happy.
Note that if there were to be a mux attached to the i2c-wc-cht adapter, this would break things again since the i2c-mux code expects the root-adapter to have a locking depth of 0. But the i2c-wc-cht adapter always has only 1 client directly attached in the form of the charger IC paired with the CHT Whiskey Cove PMIC.
--- drivers/i2c/busses/i2c-cht-wc.c | 46 +++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+)
drivers/i2c/busses/i2c-cht-wc.c +46 -0
@@ -187,6 +187,51 @@ static const struct i2c_algorithm cht_wc_i2c_adap_algo = { .smbus_xfer = cht_wc_i2c_adap_smbus_xfer, }; +/* +* We are an i2c-adapter which itself is part of an i2c-client. This means that +* transfers done through us take adapter->bus_lock twice, once for our parent +* i2c-adapter and once to take our own bus_lock. Lockdep does not like this +* nested locking, to make lockdep happy in the case of busses with muxes, the +* i2c-core's i2c_adapter_lock_bus function calls: +* rt_mutex_lock_nested(&adapter->bus_lock, i2c_adapter_depth(adapter)); +* +* But i2c_adapter_depth only works when the direct parent of the adapter is +* another adapter, as it is only meant for muxes. In our case there is an +* i2c-client and MFD instantiated platform_device in the parent->child chain +* between the 2 devices. +* +* So we override the default i2c_lock_operations and pass a hardcoded +* depth of 1 to rt_mutex_lock_nested, to make lockdep happy. +* +* Note that if there were to be a mux attached to our adapter, this would +* break things again since the i2c-mux code expects the root-adapter to have +* a locking depth of 0. But we always have only 1 client directly attached +* in the form of the Charger IC paired with the CHT Whiskey Cove PMIC. +*/ +static void cht_wc_i2c_adap_lock_bus (struct i2c_adapter *adapter, +unsigned int flags) +{ +rt_mutex_lock_nested (&adapter->bus_lock,1 ); +} + +static int cht_wc_i2c_adap_trylock_bus (struct i2c_adapter *adapter, +unsigned int flags) +{ +return rt_mutex_trylock (&adapter->bus_lock); +} + +static void cht_wc_i2c_adap_unlock_bus (struct i2c_adapter *adapter, +unsigned int flags) +{ +rt_mutex_unlock (&adapter->bus_lock); +} + +static const struct i2c_lock_operations cht_wc_i2c_adap_lock_ops = { + .lock_bus = cht_wc_i2c_adap_lock_bus, + .trylock_bus = cht_wc_i2c_adap_trylock_bus, + .unlock_bus = cht_wc_i2c_adap_unlock_bus, +}; +/**** irqchip for the client connected to the extchgr i2c adapter ****/ static void cht_wc_i2c_irq_lock (struct irq_data *data) {
@@ -295,6 +340,7 @@ static int cht_wc_i2c_adap_i2c_probe(struct platform_device *pdev) adap->adapter.owner =THIS_MODULE ; adap->adapter.class =I2C_CLASS_HWMON ; adap->adapter.algo = &cht_wc_i2c_adap_algo; + adap->adapter.lock_ops = &cht_wc_i2c_adap_lock_ops;strlcpy (adap->adapter.name,"PMIC I2C Adapter" ,sizeof (adap->adapter.name)); adap->adapter.dev.parent = &pdev->dev;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 51/106 mfd: intel-lpss: Remove D3cold delay
In reply to Greg Kroah-HartmanFrom: Kai-Heng Feng <[email protected]>
[ Upstream commit 76380a607ba0b28627c9b4b55cd47a079a59624b ]
Goodix touchpad may drop its first couple input events when i2c-designware-platdrv and intel-lpss it connects to took too long to runtime resume from runtime suspended state.
This issue happens becuase the touchpad has a rather small buffer to store up to 13 input events, so if the host doesn't read those events in time (i.e. runtime resume takes too long), events are dropped from the touchpad's buffer.
The bottleneck is D3cold delay it waits when transitioning from D3cold to D0, hence remove the delay to make the resume faster. I've tested some systems with intel-lpss and haven't seen any regression.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=202683
--- drivers/mfd/intel-lpss-pci.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/mfd/intel-lpss-pci.c +2 -0
@@ -39,6 +39,8 @@ static int intel_lpss_pci_probe(struct pci_dev *pdev, info->mem = &pdev->resource[0 ]; info->irq = pdev->irq; + pdev->d3cold_delay =0 ; +/* Probably it is enough to set this for iDMA capable devices only */ pci_set_master (pdev);pci_try_set_mwi (pdev);
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 52/106 PCI: tegra: Fix OF node reference leak
In reply to Greg Kroah-HartmanFrom: Nishka Dasgupta <[email protected]>
[ Upstream commit 9e38e690ace3e7a22a81fc02652fc101efb340cf ]
Each iteration of for_each_child_of_node() executes of_node_put() on the previous node, but in some return paths in the middle of the loop of_node_put() is missing thus causing a reference leak.
Hence stash these mid-loop return values in a variable 'err' and add a new label err_node_put which executes of_node_put() on the previous node and returns 'err' on failure.
Change mid-loop return statements to point to jump to this label to fix the reference leak.
Issue found with Coccinelle.
--- drivers/pci/controller/pci-tegra.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-)
drivers/pci/controller/pci-tegra.c +15 -7
@@ -1975,14 +1975,15 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie) err =of_pci_get_devfn (port);if (err <0 ) {dev_err (dev,"failed to parse address: %d\n" , err); -return err; + goto err_node_put; } index =PCI_SLOT (err);if (index <1 || index > soc->num_ports) {dev_err (dev,"invalid port number: %d\n" , index); -return -EINVAL ; + err = -EINVAL ; + goto err_node_put; } index--;
@@ -1991,12 +1992,13 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)if (err <0 ) {dev_err (dev,"failed to parse # of lanes: %d\n" , err); -return err; + goto err_node_put; }if (value >16 ) {dev_err (dev,"invalid # of lanes: %u\n" , value); -return -EINVAL ; + err = -EINVAL ; + goto err_node_put; } lanes |= value << (index <<3 );
@@ -2010,13 +2012,15 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie) lane += value; rp =devm_kzalloc (dev,sizeof (*rp),GFP_KERNEL ); -if (!rp) -return -ENOMEM ; +if (!rp) { + err = -ENOMEM ; + goto err_node_put; + } err =of_address_to_resource (port,0 , &rp->regs);if (err <0 ) {dev_err (dev,"failed to parse address: %d\n" , err); -return err; + goto err_node_put; }INIT_LIST_HEAD (&rp->list);
@@ -2043,6 +2047,10 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)return err;return 0 ; + +err_node_put: +of_node_put (port); +return err; }/*
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 53/106 HID: wacom: Fix several minor compiler warnings
In reply to Greg Kroah-HartmanFrom: Jason Gerecke <[email protected]>
[ Upstream commit 073b50bccbbf99a3b79a1913604c656d0e1a56c9 ]
Addresses a few issues that were noticed when compiling with non-default warnings enabled. The trimmed-down warnings in the order they are fixed below are:
* declaration of 'size' shadows a parameter
* '%s' directive output may be truncated writing up to 5 bytes into a region of size between 1 and 64
* pointer targets in initialization of 'char *' from 'unsigned char *' differ in signedness
* left shift of negative value
--- drivers/hid/wacom_sys.c | 7 ++++--- drivers/hid/wacom_wac.c | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-)
drivers/hid/wacom_sys.c +4 -3
@@ -91,7 +91,7 @@ static void wacom_wac_queue_flush(struct hid_device *hdev, }static int wacom_wac_pen_serial_enforce (struct hid_device *hdev, -struct hid_report *report,u8 *raw_data,int size) +struct hid_report *report,u8 *raw_data,int report_size) {struct wacom *wacom =hid_get_drvdata (hdev);struct wacom_wac *wacom_wac = &wacom->wacom_wac;
@@ -152,7 +152,8 @@ static int wacom_wac_pen_serial_enforce(struct hid_device *hdev,if (flush)wacom_wac_queue_flush (hdev, &wacom_wac->pen_fifo);else if (insert) -wacom_wac_queue_insert (hdev, &wacom_wac->pen_fifo, raw_data, size); +wacom_wac_queue_insert (hdev, &wacom_wac->pen_fifo, + raw_data, report_size);return insert && !flush; }
@@ -2147,7 +2148,7 @@ static void wacom_update_name(struct wacom *wacom, const char *suffix) {struct wacom_wac *wacom_wac = &wacom->wacom_wac;struct wacom_features *features = &wacom_wac->features; -char name[WACOM_NAME_MAX ]; +char name[WACOM_NAME_MAX -20 ];/* Leave some room for suffixes */ /* Generic devices name unspecified */ if ((features->type ==HID_GENERIC ) && !strcmp ("Wacom HID" , features->name)) {
drivers/hid/wacom_wac.c +2 -2
@@ -255,7 +255,7 @@ static int wacom_dtu_irq(struct wacom_wac *wacom)static int wacom_dtus_irq (struct wacom_wac *wacom) { -char *data = wacom->data; +unsigned char *data = wacom->data;struct input_dev *input = wacom->pen_input;unsigned short prox, pressure =0 ;
@@ -576,7 +576,7 @@ static int wacom_intuos_pad(struct wacom_wac *wacom) strip2 = ((data[3 ] &0x1f ) <<8 ) | data[4 ]; } - prox = (buttons & ~(~0 << nbuttons)) | (keys & ~(~0 << nkeys)) | + prox = (buttons & ~(~0U << nbuttons)) | (keys & ~(~0U << nkeys)) | (ring1 &0x80 ) | (ring2 &0x80 ) | strip1 | strip2;wacom_report_numbered_buttons (input, nbuttons, buttons);
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 54/106 livepatch: Nullify obj->mod in klp_module_coming()s error path
In reply to Greg Kroah-HartmanFrom: Miroslav Benes <[email protected]>
[ Upstream commit 4ff96fb52c6964ad42e0a878be8f86a2e8052ddd ]
klp_module_coming() is called for every module appearing in the system. It sets obj->mod to a patched module for klp_object obj. Unfortunately it leaves it set even if an error happens later in the function and the patched module is not allowed to be loaded.
klp_is_object_loaded() uses obj->mod variable and could currently give a wrong return value. The bug is probably harmless as of now.
--- kernel/livepatch/core.c | 1 + 1 file changed, 1 insertion(+)
kernel/livepatch/core.c +1 -0
@@ -1027,6 +1027,7 @@ err:pr_warn ("patch '%s' failed for module '%s', refusing to load module '%s'\n" , patch->mod->name, obj->mod->name, obj->mod->name); mod->klp_alive = false; + obj->mod =NULL ;klp_cleanup_module_patches_limited (mod, patch);mutex_unlock (&klp_mutex);
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 55/106 ARM: 8898/1: mm: Dont treat faults reported from cache maintenance as writes
In reply to Greg Kroah-HartmanFrom: Will Deacon <[email protected]>
[ Upstream commit 834020366da9ab3fb87d1eb9a3160eb22dbed63a ]
Translation faults arising from cache maintenance instructions are rather unhelpfully reported with an FSR value where the WnR field is set to 1, indicating that the faulting access was a write. Since cache maintenance instructions on 32-bit ARM do not require any particular permissions, this can cause our private 'cacheflush' system call to fail spuriously if a translation fault is generated due to page aging when targetting a read-only VMA.
In this situation, we will return -EFAULT to userspace, although this is unfortunately suppressed by the popular '__builtin___clear_cache()' intrinsic provided by GCC, which returns void.
Although it's tempting to write this off as a userspace issue, we can actually do a little bit better on CPUs that support LPAE, even if the short-descriptor format is in use. On these CPUs, cache maintenance faults additionally set the CM field in the FSR, which we can use to suppress the write permission checks in the page fault handler and succeed in performing cache maintenance to read-only areas even in the presence of a translation fault.
--- arch/arm/mm/fault.c | 4 ++-- arch/arm/mm/fault.h | 1 + 2 files changed, 3 insertions(+), 2 deletions(-)
arch/arm/mm/fault.c +2 -2
@@ -216,7 +216,7 @@ static inline bool access_error(unsigned int fsr, struct vm_area_struct *vma) {unsigned int mask =VM_READ |VM_WRITE |VM_EXEC ; -if (fsr &FSR_WRITE ) +if ((fsr &FSR_WRITE ) && !(fsr &FSR_CM )) mask =VM_WRITE ;if (fsr &FSR_LNX_PF ) mask =VM_EXEC ;
@@ -287,7 +287,7 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)if (user_mode (regs)) flags |=FAULT_FLAG_USER ; -if (fsr &FSR_WRITE ) +if ((fsr &FSR_WRITE ) && !(fsr &FSR_CM )) flags |=FAULT_FLAG_WRITE ;/*
arch/arm/mm/fault.h +1 -0
@@ -6,6 +6,7 @@* Fault status register encodings. We steal bit 31 for our own purposes. */ #define FSR_LNX_PF (1 << 31) +#define FSR_CM (1 << 13)#define FSR_WRITE (1 << 11)#define FSR_FS4 (1 << 10)#define FSR_FS3_0 (15)
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 56/106 soundwire: intel: fix channel number reported by hardware
In reply to Greg Kroah-HartmanFrom: Pierre-Louis Bossart <[email protected]>
[ Upstream commit 18046335643de6d21327f5ae034c8fb8463f6715 ]
On all released Intel controllers (CNL/CML/ICL), PDI2 reports an invalid count, force the correct hardware-supported value
This may have to be revisited with platform-specific values if the hardware changes, but for now this is good enough.
--- drivers/soundwire/intel.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
drivers/soundwire/intel.c +10 -0
@@ -282,6 +282,16 @@ intel_pdi_get_ch_cap(struct sdw_intel *sdw, unsigned int pdi_num, bool pcm)if (pcm) { count =intel_readw (shim,SDW_SHIM_PCMSYCHC (link_id, pdi_num)); + +/* +* WORKAROUND: on all existing Intel controllers, pdi +* number 2 reports channel count as 1 even though it +* supports 8 channels. Performing hardcoding for pdi +* number 2. +*/ +if (pdi_num ==2 ) + count =7 ; + }else { count =intel_readw (shim,SDW_SHIM_PDMSCAP (link_id)); count = ((count & SDW_SHIM_PDMSCAP_CPSS) >>
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 57/106 ARM: 8875/1: Kconfig: default to AEABI w/ Clang
In reply to Greg Kroah-HartmanFrom: Nick Desaulniers <[email protected]>
[ Upstream commit a05b9608456e0d4464c6f7ca8572324ace57a3f4 ]
Clang produces references to __aeabi_uidivmod and __aeabi_idivmod for arm-linux-gnueabi and arm-linux-gnueabihf targets incorrectly when AEABI is not selected (such as when OABI_COMPAT is selected).
While this means that OABI userspaces wont be able to upgraded to kernels built with Clang, it means that boards that don't enable AEABI like s3c2410_defconfig will stop failing to link in KernelCI when built with Clang.
--- arch/arm/Kconfig | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
arch/arm/Kconfig +3 -2
@@ -1586,8 +1586,9 @@ config ARM_PATCH_IDIV code to do integer division. config AEABI - bool "Use the ARM EABI to compile the kernel" if !CPU_V7 && !CPU_V7M && !CPU_V6 && !CPU_V6K - default CPU_V7 || CPU_V7M || CPU_V6 || CPU_V6K + bool "Use the ARM EABI to compile the kernel" if !CPU_V7 && \ + !CPU_V7M && !CPU_V6 && !CPU_V6K && !CC_IS_CLANG + default CPU_V7 || CPU_V7M || CPU_V6 || CPU_V6K || CC_IS_CLANG help This option allows for the kernel to be compiled using the latest ARM ABI (aka EABI). This is only useful if you are using a user
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 58/106 rtc: snvs: fix possible race condition
In reply to Greg Kroah-HartmanFrom: Anson Huang <[email protected]>
[ Upstream commit 6fd4fe9b496d9ba3382992ff4fde3871d1b6f63d ]
The RTC IRQ is requested before the struct rtc_device is allocated, this may lead to a NULL pointer dereference in IRQ handler.
To fix this issue, allocating the rtc_device struct before requesting the RTC IRQ using devm_rtc_allocate_device, and use rtc_register_device to register the RTC device.
--- drivers/rtc/rtc-snvs.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
drivers/rtc/rtc-snvs.c +7 -4
@@ -273,6 +273,10 @@ static int snvs_rtc_probe(struct platform_device *pdev)if (!data)return -ENOMEM ; + data->rtc =devm_rtc_allocate_device (&pdev->dev); +if (IS_ERR (data->rtc)) +return PTR_ERR (data->rtc); + data->regmap =syscon_regmap_lookup_by_phandle (pdev->dev.of_node,"regmap" );if (IS_ERR (data->regmap)) {
@@ -335,10 +339,9 @@ static int snvs_rtc_probe(struct platform_device *pdev) goto error_rtc_device_register; } - data->rtc =devm_rtc_device_register (&pdev->dev, pdev->name, - &snvs_rtc_ops,THIS_MODULE ); -if (IS_ERR (data->rtc)) { - ret =PTR_ERR (data->rtc); + data->rtc->ops = &snvs_rtc_ops; + ret =rtc_register_device (data->rtc); +if (ret) {dev_err (&pdev->dev,"failed to register rtc: %d\n" , ret); goto error_rtc_device_register; }
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 59/106 rtc: pcf85363/pcf85263: fix regmap error in set_time
In reply to Greg Kroah-HartmanFrom: Biwen Li <[email protected]>
[ Upstream commit 7ef66122bdb3b839e9f51b76d7e600b6e21ef648 ]
Issue:
- # hwclock -w
hwclock: RTC_SET_TIME: Invalid argument
Why:
- Relative commit: 8b9f9d4dc511 ("regmap: verify if register is writeable before writing operations"), this patch will always check for unwritable registers, it will compare reg with max_register in regmap_writeable.
- The pcf85363/pcf85263 has the capability of address wrapping which means if you access an address outside the allowed range (0x00-0x2f) hardware actually wraps the access to a lower address. The rtc-pcf85363 driver will use this feature to configure the time and execute 2 actions in the same i2c write operation (stopping the clock and configure the time). However the driver has also configured the regmap maxregister protection mechanism that will block accessing addresses outside valid range (0x00-0x2f).
How:
- Split of writing regs to two parts, first part writes control registers about stop_enable and resets, second part writes RTC time and date registers.
--- drivers/rtc/rtc-pcf85363.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/rtc/rtc-pcf85363.c +6 -1
@@ -169,7 +169,12 @@ static int pcf85363_rtc_set_time(struct device *dev, struct rtc_time *tm) buf[DT_YEARS ] =bin2bcd (tm->tm_year %100 ); ret =regmap_bulk_write (pcf85363->regmap,CTRL_STOP_EN , - tmp,sizeof (tmp)); + tmp,2 ); +if (ret) +return ret; + + ret =regmap_bulk_write (pcf85363->regmap,DT_100THS , + buf,sizeof (tmp) -2 );if (ret)return ret;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 60/106 HID: apple: Fix stuck function keys when using FN
In reply to Greg Kroah-HartmanFrom: Joao Moreno <[email protected]>
[ Upstream commit aec256d0ecd561036f188dbc8fa7924c47a9edfd ]
This fixes an issue in which key down events for function keys would be repeatedly emitted even after the user has raised the physical key. For example, the driver fails to emit the F5 key up event when going through the following steps:
- fnmode=1: hold FN, hold F5, release FN, release F5
- fnmode=2: hold F5, hold FN, release F5, release FN
The repeated F5 key down events can be easily verified using xev.
--- drivers/hid/hid-apple.c | 49 +++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 21 deletions(-)
drivers/hid/hid-apple.c +28 -21
@@ -57,7 +57,6 @@ MODULE_PARM_DESC(swap_opt_cmd, "Swap the Option (\"Alt\") and Command (\"Flag\")struct apple_sc {unsigned long quirks;unsigned int fn_on; - DECLARE_BITMAP(pressed_fn, KEY_CNT); DECLARE_BITMAP(pressed_numlock, KEY_CNT); };
@@ -184,6 +183,8 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, {struct apple_sc *asc =hid_get_drvdata (hid);const struct apple_key_translation *trans, *table; +bool do_translate; +u16 code =0 ;if (usage->code ==KEY_FN ) { asc->fn_on = !!value;
@@ -192,8 +193,6 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, }if (fnmode) { -int do_translate; -if (hid->product >=USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI && hid->product <=USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS ) table = macbookair_fn_keys;
@@ -205,25 +204,33 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, trans =apple_find_translation (table, usage->code);if (trans) { -if (test_bit (usage->code, asc->pressed_fn)) - do_translate =1 ; -else if (trans->flags &APPLE_FLAG_FKEY ) - do_translate = (fnmode ==2 && asc->fn_on) || - (fnmode ==1 && !asc->fn_on); -else - do_translate = asc->fn_on; - -if (do_translate) { -if (value) -set_bit (usage->code, asc->pressed_fn); -else -clear_bit (usage->code, asc->pressed_fn); - -input_event (input, usage->type, trans->to, - value); - -return 1 ; +if (test_bit (trans->from, input->key)) + code = trans->from; +else if (test_bit (trans->to, input->key)) + code = trans->to; + +if (!code) { +if (trans->flags &APPLE_FLAG_FKEY ) { +switch (fnmode) { +case 1 : + do_translate = !asc->fn_on; +break ; +case 2 : + do_translate = asc->fn_on; +break ; +default : +/* should never happen */ + do_translate = false; + } + }else { + do_translate = asc->fn_on; + } + + code = do_translate ? trans->to : trans->from; } + +input_event (input, usage->type, code, value); +return 1 ; } if (asc->quirks & APPLE_NUMLOCK_EMULATION &&
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 61/106 PCI: rockchip: Propagate errors for optional regulators
In reply to Greg Kroah-HartmanFrom: Thierry Reding <[email protected]>
[ Upstream commit 0e3ff0ac5f71bdb6be2a698de0ed0c7e6e738269 ]
regulator_get_optional() can fail for a number of reasons besides probe deferral. It can for example return -ENOMEM if it runs out of memory as it tries to allocate data structures. Propagating only -EPROBE_DEFER is problematic because it results in these legitimately fatal errors being treated as "regulator not specified in DT".
What we really want is to ignore the optional regulators only if they have not been specified in DT. regulator_get_optional() returns -ENODEV in this case, so that's the special case that we need to handle. So we propagate all errors, except -ENODEV, so that real failures will still cause the driver to fail probe.
--- drivers/pci/controller/pcie-rockchip-host.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
drivers/pci/controller/pcie-rockchip-host.c +8 -8
@@ -608,29 +608,29 @@ static int rockchip_pcie_parse_host_dt(struct rockchip_pcie *rockchip) rockchip->vpcie12v =devm_regulator_get_optional (dev,"vpcie12v" );if (IS_ERR (rockchip->vpcie12v)) { -if (PTR_ERR (rockchip->vpcie12v) == -EPROBE_DEFER ) -return -EPROBE_DEFER ; +if (PTR_ERR (rockchip->vpcie12v) != -ENODEV ) +return PTR_ERR (rockchip->vpcie12v);dev_info (dev,"no vpcie12v regulator found\n" ); } rockchip->vpcie3v3 =devm_regulator_get_optional (dev,"vpcie3v3" );if (IS_ERR (rockchip->vpcie3v3)) { -if (PTR_ERR (rockchip->vpcie3v3) == -EPROBE_DEFER ) -return -EPROBE_DEFER ; +if (PTR_ERR (rockchip->vpcie3v3) != -ENODEV ) +return PTR_ERR (rockchip->vpcie3v3);dev_info (dev,"no vpcie3v3 regulator found\n" ); } rockchip->vpcie1v8 =devm_regulator_get_optional (dev,"vpcie1v8" );if (IS_ERR (rockchip->vpcie1v8)) { -if (PTR_ERR (rockchip->vpcie1v8) == -EPROBE_DEFER ) -return -EPROBE_DEFER ; +if (PTR_ERR (rockchip->vpcie1v8) != -ENODEV ) +return PTR_ERR (rockchip->vpcie1v8);dev_info (dev,"no vpcie1v8 regulator found\n" ); } rockchip->vpcie0v9 =devm_regulator_get_optional (dev,"vpcie0v9" );if (IS_ERR (rockchip->vpcie0v9)) { -if (PTR_ERR (rockchip->vpcie0v9) == -EPROBE_DEFER ) -return -EPROBE_DEFER ; +if (PTR_ERR (rockchip->vpcie0v9) != -ENODEV ) +return PTR_ERR (rockchip->vpcie0v9);dev_info (dev,"no vpcie0v9 regulator found\n" ); }
Signature · 1 line
2.20.1
Re: [PATCH 4.19 061/106] PCI: rockchip: Propagate errors for optional regulators
Quoted 10 lines · Greg Kroah-Hartman
From: Thierry Reding <[email protected]>
[ Upstream commit
0e3ff0ac5f71bdb6be2a698de0ed0c7e6e738269]
regulator_get_optional()can fail for a number of reasons besides probe deferral. It can for example return-ENOMEMif it runs out of memory as it tries to allocate data structures. Propagating only -EPROBE_DEFER is problematic because it results in these legitimately fatal errors being treated as "regulator not specified in DT".
Quoted 5 lines
What we really want is to ignore the optional regulators only if they have not been specified in DT.
regulator_get_optional()returns-ENODEVin this case, so that's the special case that we need to handle. So we propagate all errors, except-ENODEV, so that real failures will still cause the driver to fail probe.
61,62,63,64: Is this fixing any real bug? Why is it suitable for -stable?
Pavel
Quoted 39 lines
+++
b/drivers/pci/controller/pcie-rockchip-host.cdrivers/pci/controller/pcie-rockchip-host.c +8
-8@@ -608,29 +608,29 @@ static int rockchip_pcie_parse_host_dt(struct rockchip_pcie *rockchip) rockchip->vpcie12v =devm_regulator_get_optional (dev,"vpcie12v" );if (IS_ERR (rockchip->vpcie12v)) { -if (PTR_ERR (rockchip->vpcie12v) == -EPROBE_DEFER ) -return -EPROBE_DEFER ; +if (PTR_ERR (rockchip->vpcie12v) != -ENODEV ) +return PTR_ERR (rockchip->vpcie12v);dev_info (dev,"no vpcie12v regulator found\n" ); } rockchip->vpcie3v3 =devm_regulator_get_optional (dev,"vpcie3v3" );if (IS_ERR (rockchip->vpcie3v3)) { -if (PTR_ERR (rockchip->vpcie3v3) == -EPROBE_DEFER ) -return -EPROBE_DEFER ; +if (PTR_ERR (rockchip->vpcie3v3) != -ENODEV ) +return PTR_ERR (rockchip->vpcie3v3);dev_info (dev,"no vpcie3v3 regulator found\n" ); } rockchip->vpcie1v8 =devm_regulator_get_optional (dev,"vpcie1v8" );if (IS_ERR (rockchip->vpcie1v8)) { -if (PTR_ERR (rockchip->vpcie1v8) == -EPROBE_DEFER ) -return -EPROBE_DEFER ; +if (PTR_ERR (rockchip->vpcie1v8) != -ENODEV ) +return PTR_ERR (rockchip->vpcie1v8);dev_info (dev,"no vpcie1v8 regulator found\n" ); } rockchip->vpcie0v9 =devm_regulator_get_optional (dev,"vpcie0v9" );if (IS_ERR (rockchip->vpcie0v9)) { -if (PTR_ERR (rockchip->vpcie0v9) == -EPROBE_DEFER ) -return -EPROBE_DEFER ; +if (PTR_ERR (rockchip->vpcie0v9) != -ENODEV ) +return PTR_ERR (rockchip->vpcie0v9);dev_info (dev,"no vpcie0v9 regulator found\n" ); }
Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
Greg Kroah-Hartman
maintainerPATCH 62/106 PCI: histb: Propagate errors for optional regulators
In reply to Greg Kroah-HartmanFrom: Thierry Reding <[email protected]>
[ Upstream commit 8f9e1641ba445437095411d9fda2324121110d5d ]
regulator_get_optional() can fail for a number of reasons besides probe deferral. It can for example return -ENOMEM if it runs out of memory as it tries to allocate data structures. Propagating only -EPROBE_DEFER is problematic because it results in these legitimately fatal errors being treated as "regulator not specified in DT".
What we really want is to ignore the optional regulators only if they have not been specified in DT. regulator_get_optional() returns -ENODEV in this case, so that's the special case that we need to handle. So we propagate all errors, except -ENODEV, so that real failures will still cause the driver to fail probe.
--- drivers/pci/controller/dwc/pcie-histb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/pci/controller/dwc/pcie-histb.c +2 -2
@@ -340,8 +340,8 @@ static int histb_pcie_probe(struct platform_device *pdev) hipcie->vpcie =devm_regulator_get_optional (dev,"vpcie" );if (IS_ERR (hipcie->vpcie)) { -if (PTR_ERR (hipcie->vpcie) == -EPROBE_DEFER ) -return -EPROBE_DEFER ; +if (PTR_ERR (hipcie->vpcie) != -ENODEV ) +return PTR_ERR (hipcie->vpcie); hipcie->vpcie =NULL ; }
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 63/106 PCI: imx6: Propagate errors for optional regulators
In reply to Greg Kroah-HartmanFrom: Thierry Reding <[email protected]>
[ Upstream commit 2170a09fb4b0f66e06e5bcdcbc98c9ccbf353650 ]
regulator_get_optional() can fail for a number of reasons besides probe deferral. It can for example return -ENOMEM if it runs out of memory as it tries to allocate data structures. Propagating only -EPROBE_DEFER is problematic because it results in these legitimately fatal errors being treated as "regulator not specified in DT".
What we really want is to ignore the optional regulators only if they have not been specified in DT. regulator_get_optional() returns -ENODEV in this case, so that's the special case that we need to handle. So we propagate all errors, except -ENODEV, so that real failures will still cause the driver to fail probe.
--- drivers/pci/controller/dwc/pci-imx6.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/pci/controller/dwc/pci-imx6.c +2 -2
@@ -807,8 +807,8 @@ static int imx6_pcie_probe(struct platform_device *pdev) imx6_pcie->vpcie =devm_regulator_get_optional (&pdev->dev,"vpcie" );if (IS_ERR (imx6_pcie->vpcie)) { -if (PTR_ERR (imx6_pcie->vpcie) == -EPROBE_DEFER ) -return -EPROBE_DEFER ; +if (PTR_ERR (imx6_pcie->vpcie) != -ENODEV ) +return PTR_ERR (imx6_pcie->vpcie); imx6_pcie->vpcie =NULL ; }
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 64/106 PCI: exynos: Propagate errors for optional PHYs
In reply to Greg Kroah-HartmanFrom: Thierry Reding <[email protected]>
[ Upstream commit ddd6960087d4b45759434146d681a94bbb1c54ad ]
devm_of_phy_get() can fail for a number of reasons besides probe deferral. It can for example return -ENOMEM if it runs out of memory as it tries to allocate devres structures. Propagating only -EPROBE_DEFER is problematic because it results in these legitimately fatal errors being treated as "PHY not specified in DT".
What we really want is to ignore the optional PHYs only if they have not been specified in DT. devm_of_phy_get() returns -ENODEV in this case, so that's the special case that we need to handle. So we propagate all errors, except -ENODEV, so that real failures will still cause the driver to fail probe.
--- drivers/pci/controller/dwc/pci-exynos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pci/controller/dwc/pci-exynos.c +1 -1
@@ -465,7 +465,7 @@ static int __init exynos_pcie_probe(struct platform_device *pdev) ep->phy =devm_of_phy_get (dev, np,NULL );if (IS_ERR (ep->phy)) { -if (PTR_ERR (ep->phy) == -EPROBE_DEFER ) +if (PTR_ERR (ep->phy) != -ENODEV )return PTR_ERR (ep->phy); ep->phy =NULL ;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 65/106 security: smack: Fix possible null-pointer dereferences in smack_socket_sock_rcv_skb()
In reply to Greg Kroah-HartmanFrom: Jia-Ju Bai <[email protected]>
[ Upstream commit 3f4287e7d98a2954f20bf96c567fdffcd2b63eb9 ]
In smack_socket_sock_rcv_skb(), there is an if statement on line 3920 to check whether skb is NULL:
if (skb && skb->secmark != 0)
This check indicates skb can be NULL in some cases.
But on lines 3931 and 3932, skb is used:
ad.a.u.net->netif = skb->skb_iif;
ipv6_skb_to_auditdata(skb, &ad.a, NULL);Thus, possible null-pointer dereferences may occur when skb is NULL.
To fix these possible bugs, an if statement is added to check skb.
These bugs are found by a static analysis tool STCheck written by us.
--- security/smack/smack_lsm.c | 2 ++ 1 file changed, 2 insertions(+)
security/smack/smack_lsm.c +2 -0
@@ -4005,6 +4005,8 @@ access_check: skp =smack_ipv6host_label (&sadd);if (skp ==NULL ) skp = smack_net_ambient; +if (skb ==NULL ) +break ;#ifdef CONFIG_AUDIT smk_ad_init_net (&ad, __func__,LSM_AUDIT_DATA_NET , &net); ad.a.u.net->family = family;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 66/106 ARM: 8903/1: ensure that usable memory in bank 0 starts from a PMD-aligned address
In reply to Greg Kroah-HartmanFrom: Mike Rapoport <[email protected]>
[ Upstream commit 00d2ec1e6bd82c0538e6dd3e4a4040de93ba4fef ]
The calculation of memblock_limit in adjust_lowmem_bounds() assumes that bank 0 starts from a PMD-aligned address. However, the beginning of the first bank may be NOMAP memory and the start of usable memory will be not aligned to PMD boundary. In such case the memblock_limit will be set to the end of the NOMAP region, which will prevent any memblock allocations.
Mark the region between the end of the NOMAP area and the next PMD-aligned address as NOMAP as well, so that the usable memory will start at PMD-aligned address.
--- arch/arm/mm/mmu.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
arch/arm/mm/mmu.c +16 -0
@@ -1175,6 +1175,22 @@ void __init adjust_lowmem_bounds(void)*/ vmalloc_limit = (u64 )(uintptr_t )vmalloc_min -PAGE_OFFSET +PHYS_OFFSET ; +/* +* The first usable region must be PMD aligned. Mark its start +* as MEMBLOCK_NOMAP if it isn't +*/ +for_each_memblock (memory, reg) { +if (!memblock_is_nomap (reg)) { +if (!IS_ALIGNED (reg->base,PMD_SIZE )) { +phys_addr_t len; + + len =round_up (reg->base,PMD_SIZE ) - reg->base; +memblock_mark_nomap (reg->base, len); + } +break ; + } + } +for_each_memblock (memory, reg) {phys_addr_t block_start = reg->base;phys_addr_t block_end = reg->base + reg->size;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 67/106 fat: work around race with userspaces read via blockdev while mounting
In reply to Greg Kroah-HartmanFrom: OGAWA Hirofumi <[email protected]>
[ Upstream commit 07bfa4415ab607e459b69bd86aa7e7602ce10b4f ]
If userspace reads the buffer via blockdev while mounting, sb_getblk()+modify can race with buffer read via blockdev.
For example,
FS userspace
bh = sb_getblk()
modify bh->b_data
read
ll_rw_block(bh)
fill bh->b_data by on-disk data
/* lost modified data by FS */
set_buffer_uptodate(bh)
set_buffer_uptodate(bh)Userspace should not use the blockdev while mounting though, the udev seems to be already doing this. Although I think the udev should try to avoid this, workaround the race by small overhead.
--- fs/fat/dir.c | 13 +++++++++++-- fs/fat/fatent.c | 3 +++ 2 files changed, 14 insertions(+), 2 deletions(-)
fs/fat/dir.c +11 -2
@@ -1097,8 +1097,11 @@ static int fat_zeroed_cluster(struct inode *dir, sector_t blknr, int nr_used, err = -ENOMEM ; goto error; } +/* Avoid race with userspace read via bdev */ +lock_buffer (bhs[n]);memset (bhs[n]->b_data,0 , sb->s_blocksize);set_buffer_uptodate (bhs[n]); +unlock_buffer (bhs[n]);mark_buffer_dirty_inode (bhs[n], dir); n++;
@@ -1155,6 +1158,8 @@ int fat_alloc_new_dir(struct inode *dir, struct timespec64 *ts)fat_time_unix2fat (sbi, ts, &time, &date, &time_cs); de = (struct msdos_dir_entry *)bhs[0 ]->b_data; +/* Avoid race with userspace read via bdev */ +lock_buffer (bhs[0 ]);/* filling the new directory slots ("." and ".." entries) */ memcpy (de[0 ].name,MSDOS_DOT ,MSDOS_NAME );memcpy (de[1 ].name,MSDOS_DOTDOT ,MSDOS_NAME );
@@ -1177,6 +1182,7 @@ int fat_alloc_new_dir(struct inode *dir, struct timespec64 *ts) de[0 ].size = de[1 ].size =0 ;memset (de +2 ,0 , sb->s_blocksize -2 *sizeof (*de));set_buffer_uptodate (bhs[0 ]); +unlock_buffer (bhs[0 ]);mark_buffer_dirty_inode (bhs[0 ], dir); err =fat_zeroed_cluster (dir, blknr,1 , bhs,MAX_BUF_PER_PAGE );
@@ -1234,11 +1240,14 @@ static int fat_add_new_entries(struct inode *dir, void *slots, int nr_slots,/* fill the directory entry */ copy =min (size, sb->s_blocksize); +/* Avoid race with userspace read via bdev */ +lock_buffer (bhs[n]);memcpy (bhs[n]->b_data, slots, copy); - slots += copy; - size -= copy;set_buffer_uptodate (bhs[n]); +unlock_buffer (bhs[n]);mark_buffer_dirty_inode (bhs[n], dir); + slots += copy; + size -= copy;if (!size)break ; n++;
fs/fat/fatent.c +3 -0
@@ -390,8 +390,11 @@ static int fat_mirror_bhs(struct super_block *sb, struct buffer_head **bhs, err = -ENOMEM ; goto error; } +/* Avoid race with userspace read via bdev */ +lock_buffer (c_bh);memcpy (c_bh->b_data, bhs[n]->b_data, sb->s_blocksize);set_buffer_uptodate (c_bh); +unlock_buffer (c_bh);mark_buffer_dirty_inode (c_bh, sbi->fat_inode);if (sb->s_flags &SB_SYNCHRONOUS ) err =sync_dirty_buffer (c_bh);
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 68/106 pktcdvd: remove warning on attempting to register non-passthrough dev
In reply to Greg Kroah-HartmanFrom: Jens Axboe <[email protected]>
[ Upstream commit eb09b3cc464d2c3bbde9a6648603c8d599ea8582 ]
Anatoly reports that he gets the below warning when booting -git on a sparc64 box on debian unstable:
...
[ 13.352975] aes_sparc64: Using sparc64 aes opcodes optimized AES implementation [ 13.428002] ------------[ cut here ]------------ [ 13.428081] WARNING: CPU: 21 PID: 586 at drivers/block/pktcdvd.c:2597 pkt_setup_dev+0x2e4/0x5a0 [pktcdvd] [ 13.428147] Attempt to register a non-SCSI queue [ 13.428184] Modules linked in: pktcdvd libdes cdrom aes_sparc64
n2_rng md5_sparc64 sha512_sparc64 rng_core sha256_sparc64 flash sha1_sparc64 ip_tables x_tables ipv6 crc_ccitt nf_defrag_ipv6 autofs4 ext4 crc16 mbcache jbd2 raid10 raid456 async_raid6_recov async_memcpy async_pq async_xor xor async_tx raid6_pq raid1 raid0 multipath linear md_mod crc32c_sparc64
[ 13.428452] CPU: 21 PID: 586 Comm: pktsetup Not tainted 5.3.0-10169-g574cc4539762 #1234 [ 13.428507] Call Trace: [ 13.428542] [00000000004635c0] __warn+0xc0/0x100 [ 13.428582] [0000000000463634] warn_slowpath_fmt+0x34/0x60 [ 13.428626] [000000001045b244] pkt_setup_dev+0x2e4/0x5a0 [pktcdvd] [ 13.428674] [000000001045ccf4] pkt_ctl_ioctl+0x94/0x220 [pktcdvd] [ 13.428724] [00000000006b95c8] do_vfs_ioctl+0x628/0x6e0 [ 13.428764] [00000000006b96c8] ksys_ioctl+0x48/0x80 [ 13.428803] [00000000006b9714] sys_ioctl+0x14/0x40 [ 13.428847] [0000000000406294] linux_sparc_syscall+0x34/0x44 [ 13.428890] irq event stamp: 4181 [ 13.428924] hardirqs last enabled at (4189): [<00000000004e0a74>] console_unlock+0x634/0x6c0 [ 13.428984] hardirqs last disabled at (4196): [<00000000004e0540>] console_unlock+0x100/0x6c0 [ 13.429048] softirqs last enabled at (3978): [<0000000000b2e2d8>] __do_softirq+0x498/0x520 [ 13.429110] softirqs last disabled at (3967): [<000000000042cfb4>] do_softirq_own_stack+0x34/0x60 [ 13.429172] ---[ end trace 2220ca468f32967d ]--- [ 13.430018] pktcdvd: setup of pktcdvd device failed [ 13.455589] des_sparc64: Using sparc64 des opcodes optimized DES implementation [ 13.515334] camellia_sparc64: Using sparc64 camellia opcodes optimized CAMELLIA implementation [ 13.522856] pktcdvd: setup of pktcdvd device failed [ 13.529327] pktcdvd: setup of pktcdvd device failed [ 13.532932] pktcdvd: setup of pktcdvd device failed [ 13.536165] pktcdvd: setup of pktcdvd device failed [ 13.539372] pktcdvd: setup of pktcdvd device failed [ 13.542834] pktcdvd: setup of pktcdvd device failed [ 13.546536] pktcdvd: setup of pktcdvd device failed [ 15.431071] XFS (dm-0): Mounting V5 Filesystem
...
Apparently debian auto-attaches any cdrom like device to pktcdvd, which can lead to the above warning. There's really no reason to warn for this situation, kill it.
--- drivers/block/pktcdvd.c | 1 - 1 file changed, 1 deletion(-)
drivers/block/pktcdvd.c +0 -1
@@ -2596,7 +2596,6 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev)if (ret)return ret;if (!blk_queue_scsi_passthrough (bdev_get_queue (bdev))) { -WARN_ONCE (true,"Attempt to register a non-SCSI queue\n" );blkdev_put (bdev,FMODE_READ |FMODE_NDELAY );return -EINVAL ; }
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 69/106 hypfs: Fix error number left in struct pointer member
In reply to Greg Kroah-HartmanFrom: David Howells <[email protected]>
[ Upstream commit b54c64f7adeb241423cd46598f458b5486b0375e ]
In hypfs_fill_super(), if hypfs_create_update_file() fails, sbi->update_file is left holding an error number. This is passed to hypfs_kill_super() which doesn't check for this.
Fix this by not setting sbi->update_value until after we've checked for error.
--- arch/s390/hypfs/inode.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
arch/s390/hypfs/inode.c +5 -4
@@ -269,7 +269,7 @@ static int hypfs_show_options(struct seq_file *s, struct dentry *root)static int hypfs_fill_super (struct super_block *sb,void *data,int silent) {struct inode *root_inode; -struct dentry *root_dentry; +struct dentry *root_dentry, *update_file;int rc =0 ;struct hypfs_sb_info *sbi;
@@ -300,9 +300,10 @@ static int hypfs_fill_super(struct super_block *sb, void *data, int silent) rc =hypfs_diag_create_files (root_dentry);if (rc)return rc; - sbi->update_file =hypfs_create_update_file (root_dentry); -if (IS_ERR (sbi->update_file)) -return PTR_ERR (sbi->update_file); + update_file =hypfs_create_update_file (root_dentry); +if (IS_ERR (update_file)) +return PTR_ERR (update_file); + sbi->update_file = update_file;hypfs_update_update (sb);pr_info ("Hypervisor filesystem mounted\n" );return 0 ;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 70/106 crypto: hisilicon - Fix double free in sec_free_hw_sgl()
In reply to Greg Kroah-HartmanFrom: Yunfeng Ye <[email protected]>
[ Upstream commit 24fbf7bad888767bed952f540ac963bc57e47e15 ]
There are two problems in sec_free_hw_sgl():
First, when sgl_current->next is valid, @hw_sgl will be freed in the first loop, but it free again after the loop.
Second, sgl_current and sgl_current->next_sgl is not match when dma_pool_free() is invoked, the third parameter should be the dma address of sgl_current, but sgl_current->next_sgl is the dma address of next chain, so use sgl_current->next_sgl is wrong.
Fix this by deleting the last dma_pool_free() in sec_free_hw_sgl(), modifying the condition for while loop, and matching the address for dma_pool_free().
--- drivers/crypto/hisilicon/sec/sec_algs.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
drivers/crypto/hisilicon/sec/sec_algs.c +7 -6
@@ -215,17 +215,18 @@ static void sec_free_hw_sgl(struct sec_hw_sgl *hw_sgl, dma_addr_t psec_sgl, struct sec_dev_info *info) { struct sec_hw_sgl *sgl_current, *sgl_next; +dma_addr_t sgl_next_dma; -if (!hw_sgl) -return ; sgl_current = hw_sgl; -while (sgl_current->next) { +while (sgl_current) { sgl_next = sgl_current->next; -dma_pool_free (info->hw_sgl_pool, sgl_current, - sgl_current->next_sgl); + sgl_next_dma = sgl_current->next_sgl; + +dma_pool_free (info->hw_sgl_pool, sgl_current, psec_sgl); + sgl_current = sgl_next; + psec_sgl = sgl_next_dma; } -dma_pool_free (info->hw_sgl_pool, hw_sgl, psec_sgl); } static int sec_alg_skcipher_setkey(struct crypto_skcipher *tfm,
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 71/106 kbuild: clean compressed initramfs image
In reply to Greg Kroah-HartmanFrom: Greg Thelen <[email protected]>
[ Upstream commit 6279eb3dd7946c69346a3b98473ed13d3a44adb5 ]
Since 9e3596b0c653 ("kbuild: initramfs cleanup, set target from Kconfig") "make clean" leaves behind compressed initramfs images. Example:
$ make defconfig $ sed -i 's|CONFIG_INITRAMFS_SOURCE=""|CONFIG_INITRAMFS_SOURCE="/tmp/ir.cpio"|' .config $ make olddefconfig $ make -s $ make -s clean $ git clean -ndxf | grep initramfs Would remove usr/initramfs_data.cpio.gz
clean rules do not have CONFIG_* context so they do not know which compression format was used. Thus they don't know which files to delete.
Tell clean to delete all possible compression formats.
Once patched usr/initramfs_data.cpio.gz and friends are deleted by "make clean".
--- usr/Makefile | 3 +++ 1 file changed, 3 insertions(+)
usr/Makefile +3 -0
@@ -11,6 +11,9 @@ datafile_y = initramfs_data.cpio$(suffix_y) datafile_d_y = .$(datafile_y).d AFLAGS_initramfs_data.o += -DINITRAMFS_IMAGE="usr/$(datafile_y)" +# clean rules do not have CONFIG_INITRAMFS_COMPRESSION. So clean up after all +# possible compression formats. +clean-files += initramfs_data.cpio* # Generate builtin.o based on initramfs_data.o obj-$(CONFIG_BLK_DEV_INITRD) := initramfs_data.o
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 72/106 ocfs2: wait for recovering done after direct unlock request
In reply to Greg Kroah-HartmanFrom: Changwei Ge <[email protected]>
[ Upstream commit 0a3775e4f883912944481cf2ef36eb6383a9cc74 ]
There is a scenario causing ocfs2 umount hang when multiple hosts are rebooting at the same time.
NODE1 NODE2 NODE3
send unlock requset to NODE2
dies
become recovery master recover NODE2
find NODE2 dead
mark resource RECOVERING
directly remove lock from grant list
calculate usage but RECOVERING marked
**miss the window of purging
clear RECOVERING
To reproduce this issue, crash a host and then umount ocfs2 from another node.
To solve this, just let unlock progress wait for recovery done.
--- fs/ocfs2/dlm/dlmunlock.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-)
fs/ocfs2/dlm/dlmunlock.c +19 -4
@@ -105,7 +105,8 @@ static enum dlm_status dlmunlock_common(struct dlm_ctxt *dlm,enum dlm_status status;int actions =0 ;int in_use; -u8 owner; +u8 owner; +int recovery_wait =0 ;mlog (0 ,"master_node = %d, valblk = %d\n" , master_node, flags &LKM_VALBLK );
@@ -208,9 +209,12 @@ static enum dlm_status dlmunlock_common(struct dlm_ctxt *dlm, }if (flags &LKM_CANCEL ) lock->cancel_pending =0 ; -else - lock->unlock_pending =0 ; - +else { +if (!lock->unlock_pending) + recovery_wait =1 ; +else + lock->unlock_pending =0 ; + } }/* get an extra ref on lock. if we are just switching
@@ -244,6 +248,17 @@ leave:spin_unlock (&res->spinlock);wake_up (&res->wq); +if (recovery_wait) { +spin_lock (&res->spinlock); +/* Unlock request will directly succeed after owner dies, +* and the lock is already removed from grant list. We have to +* wait for RECOVERING done or we miss the chance to purge it +* since the removement is much faster than RECOVERING proc. +*/ +__dlm_wait_on_lockres_flags (res,DLM_LOCK_RES_RECOVERING ); +spin_unlock (&res->spinlock); + } +/* let the caller's final dlm_lock_put handle the actual kfree */ if (actions &DLM_UNLOCK_FREE_LOCK ) {/* this should always be coupled with list removal */
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 73/106 kmemleak: increase DEBUG_KMEMLEAK_EARLY_LOG_SIZE default to 16K
In reply to Greg Kroah-HartmanFrom: Nicolas Boichat <[email protected]>
[ Upstream commit b751c52bb587ae66f773b15204ef7a147467f4c7 ]
The current default value (400) is too low on many systems (e.g. some ARM64 platform takes up 1000+ entries).
syzbot uses 16000 as default value, and has proved to be enough on beefy configurations, so let's pick that value.
This consumes more RAM on boot (each entry is 160 bytes, so in total ~2.5MB of RAM), but the memory would later be freed (early_log is __initdata).
--- lib/Kconfig.debug | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
lib/Kconfig.debug +1 -1
@@ -570,7 +570,7 @@ config DEBUG_KMEMLEAK_EARLY_LOG_SIZE int "Maximum kmemleak early log entries" depends on DEBUG_KMEMLEAK range 200 40000 - default 400 + default 16000 help Kmemleak must track all the memory allocations to avoid reporting false positives. Since memory may be allocated or
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 74/106 arm64: consider stack randomization for mmap base only when necessary
In reply to Greg Kroah-HartmanFrom: Alexandre Ghiti <[email protected]>
[ Upstream commit e8d54b62c55ab6201de6d195fc2c276294c1f6ae ]
Do not offset mmap base address because of stack randomization if current task does not want randomization. Note that x86 already implements this behaviour.
--- arch/arm64/mm/mmap.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
arch/arm64/mm/mmap.c +5 -1
@@ -65,7 +65,11 @@ unsigned long arch_mmap_rnd(void)static unsigned long mmap_base (unsigned long rnd,struct rlimit *rlim_stack) {unsigned long gap = rlim_stack->rlim_cur; -unsigned long pad = (STACK_RND_MASK <<PAGE_SHIFT ) + stack_guard_gap; +unsigned long pad = stack_guard_gap; + +/* Account for stack randomization if necessary */ +if (current->flags &PF_RANDOMIZE ) + pad += (STACK_RND_MASK <<PAGE_SHIFT );/* Values close to RLIM_INFINITY can overflow. */ if (gap + pad > gap)
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 75/106 mips: properly account for stack randomization and stack guard gap
In reply to Greg Kroah-HartmanFrom: Alexandre Ghiti <[email protected]>
[ Upstream commit b1f61b5bde3a1f50392c97b4c8513d1b8efb1cf2 ]
This commit takes care of stack randomization and stack guard gap when computing mmap base address and checks if the task asked for randomization. This fixes the problem uncovered and not fixed for arm
here: https://lkml.kernel.org/r/[email protected]
--- arch/mips/mm/mmap.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
arch/mips/mm/mmap.c +12 -2
@@ -21,8 +21,9 @@ unsigned long shm_align_mask = PAGE_SIZE - 1; /* Sane caches */EXPORT_SYMBOL (shm_align_mask);/* gap between mmap and stack */ -#define MIN_GAP (128*1024*1024UL) -#define MAX_GAP ((TASK_SIZE)/6*5) +#define MIN_GAP (128*1024*1024UL) +#define MAX_GAP ((TASK_SIZE)/6*5) +#define STACK_RND_MASK (0x7ff >> (PAGE_SHIFT - 12))static int mmap_is_legacy (struct rlimit *rlim_stack) {
@@ -38,6 +39,15 @@ static int mmap_is_legacy(struct rlimit *rlim_stack)static unsigned long mmap_base (unsigned long rnd,struct rlimit *rlim_stack) {unsigned long gap = rlim_stack->rlim_cur; +unsigned long pad = stack_guard_gap; + +/* Account for stack randomization if necessary */ +if (current->flags &PF_RANDOMIZE ) + pad += (STACK_RND_MASK <<PAGE_SHIFT ); + +/* Values close to RLIM_INFINITY can overflow. */ +if (gap + pad > gap) + gap += pad;if (gap <MIN_GAP ) gap =MIN_GAP ;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 76/106 arm: properly account for stack randomization and stack guard gap
In reply to Greg Kroah-HartmanFrom: Alexandre Ghiti <[email protected]>
[ Upstream commit af0f4297286f13a75edf93677b1fb2fc16c412a7 ]
This commit takes care of stack randomization and stack guard gap when computing mmap base address and checks if the task asked for randomization. This fixes the problem uncovered and not fixed for arm
here: https://lkml.kernel.org/r/[email protected]
--- arch/arm/mm/mmap.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
arch/arm/mm/mmap.c +12 -2
@@ -18,8 +18,9 @@ (((pgoff)<<PAGE_SHIFT) & (SHMLBA-1)))/* gap between mmap and stack */ -#define MIN_GAP (128*1024*1024UL) -#define MAX_GAP ((TASK_SIZE)/6*5) +#define MIN_GAP (128*1024*1024UL) +#define MAX_GAP ((TASK_SIZE)/6*5) +#define STACK_RND_MASK (0x7ff >> (PAGE_SHIFT - 12))static int mmap_is_legacy (struct rlimit *rlim_stack) {
@@ -35,6 +36,15 @@ static int mmap_is_legacy(struct rlimit *rlim_stack)static unsigned long mmap_base (unsigned long rnd,struct rlimit *rlim_stack) {unsigned long gap = rlim_stack->rlim_cur; +unsigned long pad = stack_guard_gap; + +/* Account for stack randomization if necessary */ +if (current->flags &PF_RANDOMIZE ) + pad += (STACK_RND_MASK <<PAGE_SHIFT ); + +/* Values close to RLIM_INFINITY can overflow. */ +if (gap + pad > gap) + gap += pad;if (gap <MIN_GAP ) gap =MIN_GAP ;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 77/106 arm: use STACK_TOP when computing mmap base address
In reply to Greg Kroah-HartmanFrom: Alexandre Ghiti <[email protected]>
[ Upstream commit 86e568e9c0525fc40e76d827212d5e9721cf7504 ]
mmap base address must be computed wrt stack top address, using TASK_SIZE is wrong since STACK_TOP and TASK_SIZE are not equivalent.
--- arch/arm/mm/mmap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm/mm/mmap.c +2 -2
@@ -19,7 +19,7 @@/* gap between mmap and stack */ #define MIN_GAP (128*1024*1024UL) -#define MAX_GAP ((TASK_SIZE)/6*5) +#define MAX_GAP ((STACK_TOP)/6*5)#define STACK_RND_MASK (0x7ff >> (PAGE_SHIFT - 12))static int mmap_is_legacy (struct rlimit *rlim_stack)
@@ -51,7 +51,7 @@ static unsigned long mmap_base(unsigned long rnd, struct rlimit *rlim_stack)else if (gap >MAX_GAP ) gap =MAX_GAP ; -return PAGE_ALIGN (TASK_SIZE - gap - rnd); +return PAGE_ALIGN (STACK_TOP - gap - rnd); }/*
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 78/106 block: mq-deadline: Fix queue restart handling
In reply to Greg Kroah-HartmanFrom: Damien Le Moal <[email protected]>
[ Upstream commit cb8acabbe33b110157955a7425ee876fb81e6bbc ]
Commit 7211aef86f79 ("block: mq-deadline: Fix write completion handling") added a call to blk_mq_sched_mark_restart_hctx() in dd_dispatch_request() to make sure that write request dispatching does not stall when all target zones are locked. This fix left a subtle race when a write completion happens during a dispatch execution on another CPU:
CPU 0: Dispatch CPU1: write completion
dd_dispatch_request()
lock(&dd->lock);
...
lock(&dd->zone_lock); dd_finish_request()
rq = find request lock(&dd->zone_lock);
unlock(&dd->zone_lock);
zone write unlock
unlock(&dd->zone_lock);
...
__blk_mq_free_request
check restart flag (not set)
-> queue not run
...
if (!rq && have writes)
blk_mq_sched_mark_restart_hctx()
unlock(&dd->lock)Since the dispatch context finishes after the write request completion handling, marking the queue as needing a restart is not seen from __blk_mq_free_request() and blk_mq_sched_restart() not executed leading to the dispatch stall under 100% write workloads.
Fix this by moving the call to blk_mq_sched_mark_restart_hctx() from dd_dispatch_request() into dd_finish_request() under the zone lock to ensure full mutual exclusion between write request dispatch selection and zone unlock on write request completion.
--- block/mq-deadline.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-)
block/mq-deadline.c +13 -10
@@ -376,13 +376,6 @@ static struct request *__dd_dispatch_request(struct deadline_data *dd)* hardware queue, but we may return a request that is for a * different hardware queue. This is because mq-deadline has shared * state for all hardware queues, in terms of sorting, FIFOs, etc. -* -* For a zoned block device, __dd_dispatch_request() may return NULL -* if all the queued write requests are directed at zones that are already -* locked due to on-going write requests. In this case, make sure to mark -* the queue as needing a restart to ensure that the queue is run again -* and the pending writes dispatched once the target zones for the ongoing -* write requests are unlocked in dd_finish_request(). */ static struct request *dd_dispatch_request (struct blk_mq_hw_ctx *hctx) {
@@ -391,9 +384,6 @@ static struct request *dd_dispatch_request(struct blk_mq_hw_ctx *hctx)spin_lock (&dd->lock); rq =__dd_dispatch_request (dd); -if (!rq &&blk_queue_is_zoned (hctx->queue) && - !list_empty (&dd->fifo_list[WRITE ])) -blk_mq_sched_mark_restart_hctx (hctx);spin_unlock (&dd->lock);return rq;
@@ -559,6 +549,13 @@ static void dd_prepare_request(struct request *rq, struct bio *bio)* spinlock so that the zone is never unlocked while deadline_fifo_request() * or deadline_next_request() are executing. This function is called for * all requests, whether or not these requests complete successfully. +* +* For a zoned block device, __dd_dispatch_request() may have stopped +* dispatching requests if all the queued requests are write requests directed +* at zones that are already locked due to on-going write requests. To ensure +* write request dispatch progress in this case, mark the queue as needing a +* restart to ensure that the queue is run again after completion of the +* request and zones being unlocked. */ static void dd_finish_request (struct request *rq) {
@@ -570,6 +567,12 @@ static void dd_finish_request(struct request *rq)spin_lock_irqsave (&dd->zone_lock, flags);blk_req_zone_write_unlock (rq); +if (!list_empty (&dd->fifo_list[WRITE ])) { +struct blk_mq_hw_ctx *hctx; + + hctx =blk_mq_map_queue (q, rq->mq_ctx->cpu); +blk_mq_sched_mark_restart_hctx (hctx); + }spin_unlock_irqrestore (&dd->zone_lock, flags); } }
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 79/106 bpf: fix use after free in prog symbol exposure
In reply to Greg Kroah-HartmanFrom: Daniel Borkmann <[email protected]>
commit c751798aa224fadc5124b49eeb38fb468c0fa039 upstream.
syzkaller managed to trigger the warning in bpf_jit_free() which checks via bpf_prog_kallsyms_verify_off() for potentially unlinked JITed BPF progs in kallsyms, and subsequently trips over GPF when walking kallsyms entries:
[...]
8021q: adding VLAN 0 to HW filter on device batadv0 8021q: adding VLAN 0 to HW filter on device batadv0
WARNING: CPU: 0 PID: 9869 at kernel/bpf/core.c:810 bpf_jit_free+0x1e8/0x2a0 Kernel panic - not syncing: panic_on_warn set ... CPU: 0 PID: 9869 Comm: kworker/0:7 Not tainted 5.0.0-rc8+ #1 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Workqueue: events bpf_prog_free_deferred Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0x113/0x167 lib/dump_stack.c:113 panic+0x212/0x40b kernel/panic.c:214 __warn.cold.8+0x1b/0x38 kernel/panic.c:571 report_bug+0x1a4/0x200 lib/bug.c:186 fixup_bug arch/x86/kernel/traps.c:178 [inline] do_error_trap+0x11b/0x200 arch/x86/kernel/traps.c:271 do_invalid_op+0x36/0x40 arch/x86/kernel/traps.c:290 invalid_op+0x14/0x20 arch/x86/entry/entry_64.S:973 RIP: 0010:bpf_jit_free+0x1e8/0x2a0 Code: 02 4c 89 e2 83 e2 07 38 d0 7f 08 84 c0 0f 85 86 00 00 00 48 ba 00 02 00 00 00 00 ad de 0f b6 43 02 49 39 d6 0f 84 5f fe ff ff <0f> 0b e9 58 fe ff ff 48 b8 00 00 00 00 00 fc ff df 4c 89 e2 48 c1 RSP: 0018:ffff888092f67cd8 EFLAGS: 00010202 RAX: 0000000000000007 RBX: ffffc90001947000 RCX: ffffffff816e9d88 RDX: dead000000000200 RSI: 0000000000000008 RDI: ffff88808769f7f0 RBP: ffff888092f67d00 R08: fffffbfff1394059 R09: fffffbfff1394058 R10: fffffbfff1394058 R11: ffffffff89ca02c7 R12: ffffc90001947002 R13: ffffc90001947020 R14: ffffffff881eca80 R15: ffff88808769f7e8 BUG: unable to handle kernel paging request at fffffbfff400d000 #PF error: [normal kernel read fault] PGD 21ffee067 P4D 21ffee067 PUD 21ffed067 PMD 9f942067 PTE 0 Oops: 0000 [#1] PREEMPT SMP KASAN CPU: 0 PID: 9869 Comm: kworker/0:7 Not tainted 5.0.0-rc8+ #1 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Workqueue: events bpf_prog_free_deferred RIP: 0010:bpf_get_prog_addr_region kernel/bpf/core.c:495 [inline] RIP: 0010:bpf_tree_comp kernel/bpf/core.c:558 [inline] RIP: 0010:__lt_find include/linux/rbtree_latch.h:115 [inline] RIP: 0010:latch_tree_find include/linux/rbtree_latch.h:208 [inline] RIP: 0010:bpf_prog_kallsyms_find+0x107/0x2e0 kernel/bpf/core.c:632 Code: 00 f0 ff ff 44 38 c8 7f 08 84 c0 0f 85 fa 00 00 00 41 f6 45 02 01 75 02 0f 0b 48 39 da 0f 82 92 00 00 00 48 89 d8 48 c1 e8 03 <42> 0f b6 04 30 84 c0 74 08 3c 03 0f 8e 45 01 00 00 8b 03 48 c1 e0 [...]
Upon further debugging, it turns out that whenever we trigger this issue, the kallsyms removal in bpf_prog_ksym_node_del() was /skipped/ but yet bpf_jit_free() reported that the entry is /in use/.
Problem is that symbol exposure via bpf_prog_kallsyms_add() but also perf_event_bpf_event() were done /after/ bpf_prog_new_fd(). Once the fd is exposed to the public, a parallel close request came in right before we attempted to do the bpf_prog_kallsyms_add().
Given at this time the prog reference count is one, we start to rip everything underneath us via bpf_prog_release() -> bpf_prog_put(). The memory is eventually released via deferred free, so we're seeing that bpf_jit_free() has a kallsym entry because we added it from bpf_prog_load() but /after/ bpf_prog_put() from the remote CPU.
Therefore, move both notifications /before/ we install the fd. The issue was never seen between bpf_prog_alloc_id() and bpf_prog_new_fd() because upon bpf_prog_get_fd_by_id() we'll take another reference to the BPF prog, so we're still holding the original reference from the bpf_prog_load().
--- kernel/bpf/syscall.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-)
kernel/bpf/syscall.c +17 -11
@@ -1454,19 +1454,25 @@ static int bpf_prog_load(union bpf_attr *attr)if (err) goto free_used_maps; +/* Upon success of bpf_prog_alloc_id(), the BPF prog is +* effectively publicly exposed. However, retrieving via +* bpf_prog_get_fd_by_id() will take another reference, +* therefore it cannot be gone underneath us. +* +* Only for the time /after/ successful bpf_prog_new_fd() +* and before returning to userspace, we might just hold +* one reference and any parallel close on that fd could +* rip everything out. Hence, below notifications must +* happen before bpf_prog_new_fd(). +* +* Also, any failure handling from this point onwards must +* be using bpf_prog_put() given the program is exposed. +*/ +bpf_prog_kallsyms_add (prog); + err =bpf_prog_new_fd (prog); -if (err <0 ) { -/* failed to allocate fd. -* bpf_prog_put() is needed because the above -* bpf_prog_alloc_id() has published the prog -* to the userspace and the userspace may -* have refcnt-ed it through BPF_PROG_GET_FD_BY_ID. -*/ +if (err <0 )bpf_prog_put (prog); -return err; - } - -bpf_prog_kallsyms_add (prog);return err; free_used_maps:
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 80/106 cxgb4:Fix out-of-bounds MSI-X info array access
In reply to Greg Kroah-HartmanFrom: Vishal Kulkarni <[email protected]>
[ Upstream commit 6b517374f4ea5a3c6e307e1219ec5f35d42e6d00 ]
When fetching free MSI-X vectors for ULDs, check for the error code before accessing MSI-X info array. Otherwise, an out-of-bounds access is attempted, which results in kernel panic.
--- drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c +6 -3
@@ -137,13 +137,12 @@ static int uldrx_handler(struct sge_rspqstatic int alloc_uld_rxqs (struct adapter *adap,struct sge_uld_rxq_info *rxq_info,bool lro) { -struct sge *s = &adap->sge;unsigned int nq = rxq_info->nrxq + rxq_info->nciq; +int i, err, msi_idx, que_idx =0 , bmap_idx =0 ;struct sge_ofld_rxq *q = rxq_info->uldrxq;unsigned short *ids = rxq_info->rspq_id; -unsigned int bmap_idx =0 ; +struct sge *s = &adap->sge;unsigned int per_chan; -int i, err, msi_idx, que_idx =0 ; per_chan = rxq_info->nrxq / adap->params.nports;
@@ -161,6 +160,10 @@ static int alloc_uld_rxqs(struct adapterif (msi_idx >=0 ) { bmap_idx =get_msix_idx_from_bmap (adap); +if (bmap_idx <0 ) { + err = -ENOSPC ; + goto freeout; + } msi_idx = adap->msix_info_ulds[bmap_idx].idx; } err = t4_sge_alloc_rxq(adap, &q->rspq, false,
Greg Kroah-Hartman
maintainerPATCH 81/106 erspan: remove the incorrect mtu limit for erspan
In reply to Greg Kroah-HartmanFrom: Haishuang Yan <[email protected]>
[ Upstream commit 0e141f757b2c78c983df893e9993313e2dc21e38 ]
erspan driver calls ether_setup(), after commit 61e84623ace3 ("net: centralize net_device min/max MTU checking"), the range of mtu is [min_mtu, max_mtu], which is [68, 1500] by default.
It causes the dev mtu of the erspan device to not be greater than 1500, this limit value is not correct for ipgre tap device.
Tested:
Before patch:
# ip link set erspan0 mtu 1600
Error: mtu greater than device maximum.
After patch:
# ip link set erspan0 mtu 1600
# ip -d link show erspan0
21: erspan0@NONE: <BROADCAST,MULTICAST> mtu 1600 qdisc noop state DOWN
mode DEFAULT group default qlen 1000
link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff promiscuity 0 minmtu 68 maxmtu 0--- net/ipv4/ip_gre.c | 1 + 1 file changed, 1 insertion(+)
net/ipv4/ip_gre.c +1 -0
@@ -1531,6 +1531,7 @@ static void erspan_setup(struct net_devistruct ip_tunnel *t =netdev_priv (dev);ether_setup (dev); + dev->max_mtu =0 ; dev->netdev_ops = &erspan_netdev_ops; dev->priv_flags &= ~IFF_TX_SKB_SHARING ; dev->priv_flags |=IFF_LIVE_ADDR_CHANGE ;
Greg Kroah-Hartman
maintainerPATCH 82/106 hso: fix NULL-deref on tty open
In reply to Greg Kroah-HartmanFrom: Johan Hovold <[email protected]>
[ Upstream commit 8353da9fa69722b54cba82b2ec740afd3d438748 ]
Fix NULL-pointer dereference on tty open due to a failure to handle a missing interrupt-in endpoint when probing modem ports:
BUG: kernel NULL pointer dereference, address: 0000000000000006 ... RIP: 0010:tiocmget_submit_urb+0x1c/0xe0 [hso] ... Call Trace: hso_start_serial_device+0xdc/0x140 [hso] hso_serial_open+0x118/0x1b0 [hso] tty_open+0xf1/0x490
--- drivers/net/usb/hso.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
drivers/net/usb/hso.c +8 -4
@@ -2634,14 +2634,18 @@ static struct hso_device *hso_create_bul*/ if (serial->tiocmget) { tiocmget = serial->tiocmget; + tiocmget->endp =hso_get_ep (interface, +USB_ENDPOINT_XFER_INT , +USB_DIR_IN ); +if (!tiocmget->endp) { +dev_err (&interface->dev,"Failed to find INT IN ep\n" ); + goto exit; + } + tiocmget->urb =usb_alloc_urb (0 ,GFP_KERNEL );if (tiocmget->urb) {mutex_init (&tiocmget->mutex);init_waitqueue_head (&tiocmget->waitq); - tiocmget->endp =hso_get_ep ( - interface, -USB_ENDPOINT_XFER_INT , -USB_DIR_IN ); }else hso_free_tiomget (serial); }
Greg Kroah-Hartman
maintainerPATCH 83/106 ipv6: drop incoming packets having a v4mapped source address
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit 6af1799aaf3f1bc8defedddfa00df3192445bbf3 ]
This began with a syzbot report. syzkaller was injecting IPv6 TCP SYN packets having a v4mapped source address.
After an unsuccessful 4-tuple lookup, TCP creates a request socket (SYN_RECV) and calls reqsk_queue_hash_req()
reqsk_queue_hash_req() calls sk_ehashfn(sk)
At this point we have AF_INET6 sockets, and the heuristic used by sk_ehashfn() to either hash the IPv4 or IPv6 addresses is to use ipv6_addr_v4mapped(&sk->sk_v6_daddr)
For the particular spoofed packet, we end up hashing V4 addresses which were not initialized by the TCP IPv6 stack, so KMSAN fired a warning.
I first fixed sk_ehashfn() to test both source and destination addresses, but then faced various problems, including user-space programs like packetdrill that had similar assumptions.
Instead of trying to fix the whole ecosystem, it is better to admit that we have a dual stack behavior, and that we can not build linux kernels without V4 stack anyway.
The dual stack API automatically forces the traffic to be IPv4 if v4mapped addresses are used at bind() or connect(), so it makes no sense to allow IPv6 traffic to use the same v4mapped class.
--- net/ipv6/ip6_input.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
net/ipv6/ip6_input.c +10 -0
@@ -220,6 +220,16 @@ static struct sk_buff *ip6_rcv_core(struif (ipv6_addr_is_multicast (&hdr->saddr)) goto err; +/* While RFC4291 is not explicit about v4mapped addresses +* in IPv6 headers, it seems clear linux dual-stack +* model can not deal properly with these. +* Security models could be fooled by ::ffff:127.0.0.1 for example. +* +* https://tools.ietf.org/html/draft-itojun-v6ops-v4mapped-harmful-02 +*/ +if (ipv6_addr_v4mapped (&hdr->saddr)) + goto err; + skb->transport_header = skb->network_header +sizeof (*hdr);IP6CB (skb)->nhoff = offsetof(struct ipv6hdr , nexthdr);
Greg Kroah-Hartman
maintainerPATCH 84/106 ipv6: Handle missing host route in __ipv6_ifa_notify
In reply to Greg Kroah-HartmanFrom: David Ahern <[email protected]>
[ Upstream commit 2d819d250a1393a3e725715425ab70a0e0772a71 ]
Rajendra reported a kernel panic when a link was taken down:
[ 6870.263084] BUG: unable to handle kernel NULL pointer dereference at 00000000000000a8
[ 6870.271856] IP: [<ffffffff8efc5764>] __ipv6_ifa_notify+0x154/0x290 <snip>
[ 6870.570501] Call Trace:
[ 6870.573238] [<ffffffff8efc58c6>] ? ipv6_ifa_notify+0x26/0x40
[ 6870.579665] [<ffffffff8efc98ec>] ? addrconf_dad_completed+0x4c/0x2c0
[ 6870.586869] [<ffffffff8efe70c6>] ? ipv6_dev_mc_inc+0x196/0x260
[ 6870.593491] [<ffffffff8efc9c6a>] ? addrconf_dad_work+0x10a/0x430
[ 6870.600305] [<ffffffff8f01ade4>] ? __switch_to_asm+0x34/0x70
[ 6870.606732] [<ffffffff8ea93a7a>] ? process_one_work+0x18a/0x430
[ 6870.613449] [<ffffffff8ea93d6d>] ? worker_thread+0x4d/0x490
[ 6870.619778] [<ffffffff8ea93d20>] ? process_one_work+0x430/0x430
[ 6870.626495] [<ffffffff8ea99dd9>] ? kthread+0xd9/0xf0
[ 6870.632145] [<ffffffff8f01ade4>] ? __switch_to_asm+0x34/0x70
[ 6870.638573] [<ffffffff8ea99d00>] ? kthread_park+0x60/0x60
[ 6870.644707] [<ffffffff8f01ae77>] ? ret_from_fork+0x57/0x70
[ 6870.650936] Code: 31 c0 31 d2 41 b9 20 00 08 02 b9 09 00 00 0addrconf_dad_work is kicked to be scheduled when a device is brought up. There is a race between addrcond_dad_work getting scheduled and taking the rtnl lock and a process taking the link down (under rtnl). The latter removes the host route from the inet6_addr as part of addrconf_ifdown which is run for NETDEV_DOWN. The former attempts to use the host route in __ipv6_ifa_notify. If the down event removes the host route due to the race to the rtnl, then the BUG listed above occurs.
Since the DAD sequence can not be aborted, add a check for the missing host route in __ipv6_ifa_notify. The only way this should happen is due to the previously mentioned race. The host route is created when the address is added to an interface; it is only removed on a down event where the address is kept. Add a warning if the host route is missing AND the device is up; this is a situation that should never happen.
--- net/ipv6/addrconf.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-)
net/ipv6/addrconf.c +12 -5
@@ -5678,13 +5678,20 @@ static void __ipv6_ifa_notify(int event,switch (event) {case RTM_NEWADDR :/* -* If the address was optimistic -* we inserted the route at the start of -* our DAD process, so we don't need -* to do it again +* If the address was optimistic we inserted the route at the +* start of our DAD process, so we don't need to do it again. +* If the device was taken down in the middle of the DAD +* cycle there is a race where we could get here without a +* host route, so nothing to insert. That will be fixed when +* the device is brought up. */ -if (!rcu_access_pointer (ifp->rt->fib6_node)) +if (ifp->rt && !rcu_access_pointer (ifp->rt->fib6_node)) {ip6_ins_rt (net, ifp->rt); + }else if (!ifp->rt && (ifp->idev->dev->flags &IFF_UP )) { +pr_warn ("BUG: Address %pI6c on device %s is missing its host route.\n" , + &ifp->addr, ifp->idev->dev->name); + } +if (ifp->idev->cnf.forwarding)addrconf_join_anycast (ifp);if (!ipv6_addr_any (&ifp->peer_addr))
Greg Kroah-Hartman
maintainerPATCH 85/106 net: ipv4: avoid mixed n_redirects and rate_tokens usage
In reply to Greg Kroah-HartmanFrom: Paolo Abeni <[email protected]>
[ Upstream commit b406472b5ad79ede8d10077f0c8f05505ace8b6d ]
Since commit c09551c6ff7f ("net: ipv4: use a dedicated counter for icmp_v4 redirect packets") we use 'n_redirects' to account for redirect packets, but we still use 'rate_tokens' to compute the redirect packets exponential backoff.
If the device sent to the relevant peer any ICMP error packet after sending a redirect, it will also update 'rate_token' according to the leaking bucket schema; typically 'rate_token' will raise above BITS_PER_LONG and the redirect packets backoff algorithm will produce undefined behavior.
Fix the issue using 'n_redirects' to compute the exponential backoff in ip_rt_send_redirect().
Note that we still clear rate_tokens after a redirect silence period, to avoid changing an established behaviour.
The root cause predates git history; before the mentioned commit in the critical scenario, the kernel stopped sending redirects, after the mentioned commit the behavior more randomic.
--- net/ipv4/route.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
net/ipv4/route.c +2 -3
@@ -908,16 +908,15 @@ void ip_rt_send_redirect(struct sk_buffif (peer->rate_tokens ==0 ||time_after (jiffies, (peer->rate_last + - (ip_rt_redirect_load << peer->rate_tokens)))) { + (ip_rt_redirect_load << peer->n_redirects)))) {__be32 gw =rt_nexthop (rt,ip_hdr (skb)->daddr);icmp_send (skb,ICMP_REDIRECT ,ICMP_REDIR_HOST , gw); peer->rate_last = jiffies; - ++peer->rate_tokens; ++peer->n_redirects;#ifdef CONFIG_IP_ROUTE_VERBOSE if (log_martians && - peer->rate_tokens == ip_rt_redirect_number) + peer->n_redirects == ip_rt_redirect_number)net_warn_ratelimited ("host %pI4/if%d ignores redirects for %pI4 to %pI4\n" , &ip_hdr (skb)->saddr,inet_iif (skb), &ip_hdr (skb)->daddr, &gw);
Greg Kroah-Hartman
maintainerPATCH 86/106 net: qlogic: Fix memory leak in ql_alloc_large_buffers
In reply to Greg Kroah-HartmanFrom: Navid Emamdoost <[email protected]>
[ Upstream commit 1acb8f2a7a9f10543868ddd737e37424d5c36cf4 ]
In ql_alloc_large_buffers, a new skb is allocated via netdev_alloc_skb. This skb should be released if pci_dma_mapping_error fails.
--- drivers/net/ethernet/qlogic/qla3xxx.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/ethernet/qlogic/qla3xxx.c +1 -0
@@ -2788,6 +2788,7 @@ static int ql_alloc_large_buffers(structnetdev_err (qdev->ndev,"PCI mapping failed with error: %d\n" , err); +dev_kfree_skb_irq (skb);ql_free_large_buffers (qdev);return -ENOMEM ; }
Greg Kroah-Hartman
maintainerPATCH 87/106 net: Unpublish sk from sk_reuseport_cb before call_rcu
In reply to Greg Kroah-HartmanFrom: Martin KaFai Lau <[email protected]>
[ Upstream commit 8c7138b33e5c690c308b2a7085f6313fdcb3f616 ]
The "reuse->sock[]" array is shared by multiple sockets. The going away sk must unpublish itself from "reuse->sock[]" before making call_rcu() call. However, this unpublish-action is currently done after a grace period and it may cause use-after-free.
The fix is to move reuseport_detach_sock() to sk_destruct(). Due to the above reason, any socket with sk_reuseport_cb has to go through the rcu grace period before freeing it.
It is a rather old bug (~3 yrs). The Fixes tag is not necessary the right commit but it is the one that introduced the SOCK_RCU_FREE logic and this fix is depending on it.
--- net/core/sock.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
net/core/sock.c +8 -3
@@ -1563,8 +1563,6 @@ static void __sk_destruct(struct rcu_heask_filter_uncharge (sk, filter);RCU_INIT_POINTER (sk->sk_filter,NULL ); } -if (rcu_access_pointer (sk->sk_reuseport_cb)) -reuseport_detach_sock (sk);sock_disable_timestamp (sk,SK_FLAGS_TIMESTAMP );
@@ -1587,7 +1585,14 @@ static void __sk_destruct(struct rcu_heavoid sk_destruct (struct sock *sk) { -if (sock_flag (sk,SOCK_RCU_FREE )) +bool use_call_rcu =sock_flag (sk,SOCK_RCU_FREE ); + +if (rcu_access_pointer (sk->sk_reuseport_cb)) { +reuseport_detach_sock (sk); + use_call_rcu = true; + } + +if (use_call_rcu)call_rcu (&sk->sk_rcu, __sk_destruct);else __sk_destruct (&sk->sk_rcu);
Greg Kroah-Hartman
maintainerPATCH 88/106 nfc: fix memory leak in llcp_sock_bind()
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit a0c2dc1fe63e2869b74c1c7f6a81d1745c8a695d ]
sysbot reported a memory leak after a bind() has failed.
While we are at it, abort the operation if kmemdup() has failed.
BUG: memory leak
unreferenced object 0xffff888105d83ec0 (size 32):
comm "syz-executor067", pid 7207, jiffies 4294956228 (age 19.430s)
hex dump (first 32 bytes):
00 69 6c 65 20 72 65 61 64 00 6e 65 74 3a 5b 34 .ile read.net:[4
30 32 36 35 33 33 30 39 37 5d 00 00 00 00 00 00 026533097]......
backtrace:
[<0000000036bac473>] kmemleak_alloc_recursive /./include/linux/kmemleak.h:43 [inline]
[<0000000036bac473>] slab_post_alloc_hook /mm/slab.h:522 [inline]
[<0000000036bac473>] slab_alloc /mm/slab.c:3319 [inline]
[<0000000036bac473>] __do_kmalloc /mm/slab.c:3653 [inline]
[<0000000036bac473>] __kmalloc_track_caller+0x169/0x2d0 /mm/slab.c:3670
[<000000000cd39d07>] kmemdup+0x27/0x60 /mm/util.c:120
[<000000008e57e5fc>] kmemdup /./include/linux/string.h:432 [inline]
[<000000008e57e5fc>] llcp_sock_bind+0x1b3/0x230 /net/nfc/llcp_sock.c:107
[<000000009cb0b5d3>] __sys_bind+0x11c/0x140 /net/socket.c:1647
[<00000000492c3bbc>] __do_sys_bind /net/socket.c:1658 [inline]
[<00000000492c3bbc>] __se_sys_bind /net/socket.c:1656 [inline]
[<00000000492c3bbc>] __x64_sys_bind+0x1e/0x30 /net/socket.c:1656
[<0000000008704b2a>] do_syscall_64+0x76/0x1a0 /arch/x86/entry/common.c:296
[<000000009f4c57a4>] entry_SYSCALL_64_after_hwframe+0x44/0xa9--- net/nfc/llcp_sock.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
net/nfc/llcp_sock.c +6 -1
@@ -119,9 +119,14 @@ static int llcp_sock_bind(struct socket llcp_sock->service_name =kmemdup (llcp_addr.service_name, llcp_sock->service_name_len,GFP_KERNEL ); - +if (!llcp_sock->service_name) { + ret = -ENOMEM ; + goto put_dev; + } llcp_sock->ssap =nfc_llcp_get_sdp_ssap (local, llcp_sock);if (llcp_sock->ssap ==LLCP_SAP_MAX ) { +kfree (llcp_sock->service_name); + llcp_sock->service_name =NULL ; ret = -EADDRINUSE ; goto put_dev; }
Greg Kroah-Hartman
maintainerPATCH 89/106 qmi_wwan: add support for Cinterion CLS8 devices
In reply to Greg Kroah-HartmanFrom: Reinhard Speyerer <[email protected]>
[ Upstream commit cf74ac6db25d4002089e85cc623ad149ecc25614 ]
Add support for Cinterion CLS8 devices.
Use QMI_QUIRK_SET_DTR as required for Qualcomm MDM9x07 chipsets.
T: Bus=01 Lev=03 Prnt=05 Port=01 Cnt=02 Dev#= 25 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=1e2d ProdID=00b0 Rev= 3.18 S: Manufacturer=GEMALTO S: Product=USB Modem C:* #Ifs= 5 Cfg#= 1 Atr=80 MxPwr=500mA I:* If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=(none) E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=83(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=85(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=87(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qmi_wwan E: Ad=89(I) Atr=03(Int.) MxPS= 8 Ivl=32ms E: Ad=88(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
--- drivers/net/usb/qmi_wwan.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/usb/qmi_wwan.c +1 -0
@@ -1286,6 +1286,7 @@ static const struct usb_device_id produc {QMI_FIXED_INTF(0x1e2d, 0x0082, 4)}, /* Cinterion PHxx,PXxx (2 RmNet) */ {QMI_FIXED_INTF(0x1e2d, 0x0082, 5)}, /* Cinterion PHxx,PXxx (2 RmNet) */ {QMI_FIXED_INTF(0x1e2d, 0x0083, 4)}, /* Cinterion PHxx,PXxx (1 RmNet + USB Audio)*/ + {QMI_QUIRK_SET_DTR(0x1e2d, 0x00b0, 4)}, /* Cinterion CLS8 */ {QMI_FIXED_INTF(0x413c, 0x81a2, 8)}, /* Dell Wireless 5806 Gobi(TM) 4G LTE Mobile Broadband Card */ {QMI_FIXED_INTF(0x413c, 0x81a3, 8)}, /* Dell Wireless 5570 HSPA+ (42Mbps) Mobile Broadband Card */ {QMI_FIXED_INTF(0x413c, 0x81a4, 8)}, /* Dell Wireless 5570e HSPA+ (42Mbps) Mobile Broadband Card */
Greg Kroah-Hartman
maintainerPATCH 90/106 rxrpc: Fix rxrpc_recvmsg tracepoint
In reply to Greg Kroah-HartmanFrom: David Howells <[email protected]>
[ Upstream commit db9b2e0af605e7c994784527abfd9276cabd718a ]
Fix the rxrpc_recvmsg tracepoint to handle being called with a NULL call parameter.
--- include/trace/events/rxrpc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/trace/events/rxrpc.h +1 -1
@@ -1073,7 +1073,7 @@ TRACE_EVENT(rxrpc_recvmsg, ), TP_fast_assign( - __entry->call = call->debug_id; + __entry->call = call ? call->debug_id : 0; __entry->why = why; __entry->seq = seq; __entry->offset = offset;
Greg Kroah-Hartman
maintainerPATCH 91/106 sch_dsmark: fix potential NULL deref in dsmark_init()
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit 474f0813a3002cb299bb73a5a93aa1f537a80ca8 ]
Make sure TCA_DSMARK_INDICES was provided by the user.
syzbot reported :
kasan: CONFIG_KASAN_INLINE enabled
kasan: GPF could be caused by NULL-ptr deref or user memory access
general protection fault: 0000 [#1] PREEMPT SMP KASAN CPU: 1 PID: 8799 Comm: syz-executor235 Not tainted 5.3.0+ #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 RIP: 0010:nla_get_u16 include/net/netlink.h:1501 [inline] RIP: 0010:dsmark_init net/sched/sch_dsmark.c:364 [inline] RIP: 0010:dsmark_init+0x193/0x640 net/sched/sch_dsmark.c:339 Code: 85 db 58 0f 88 7d 03 00 00 e8 e9 1a ac fb 48 8b 9d 70 ff ff ff 48 b8 00 00 00 00 00 fc ff df 48 8d 7b 04 48 89 fa 48 c1 ea 03 <0f> b6 14 02 48 89 f8 83 e0 07 83 c0 01 38 d0 7c 08 84 d2 0f 85 ca RSP: 0018:ffff88809426f3b8 EFLAGS: 00010247 RAX: dffffc0000000000 RBX: 0000000000000000 RCX: ffffffff85c6eb09 RDX: 0000000000000000 RSI: ffffffff85c6eb17 RDI: 0000000000000004 RBP: ffff88809426f4b0 R08: ffff88808c4085c0 R09: ffffed1015d26159 R10: ffffed1015d26158 R11: ffff8880ae930ac7 R12: ffff8880a7e96940 R13: dffffc0000000000 R14: ffff88809426f8c0 R15: 0000000000000000 FS: 0000000001292880(0000) GS:ffff8880ae900000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000020000080 CR3: 000000008ca1b000 CR4: 00000000001406e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: qdisc_create+0x4ee/0x1210 net/sched/sch_api.c:1237 tc_modify_qdisc+0x524/0x1c50 net/sched/sch_api.c:1653 rtnetlink_rcv_msg+0x463/0xb00 net/core/rtnetlink.c:5223 netlink_rcv_skb+0x177/0x450 net/netlink/af_netlink.c:2477 rtnetlink_rcv+0x1d/0x30 net/core/rtnetlink.c:5241 netlink_unicast_kernel net/netlink/af_netlink.c:1302 [inline] netlink_unicast+0x531/0x710 net/netlink/af_netlink.c:1328 netlink_sendmsg+0x8a5/0xd60 net/netlink/af_netlink.c:1917 sock_sendmsg_nosec net/socket.c:637 [inline] sock_sendmsg+0xd7/0x130 net/socket.c:657 ___sys_sendmsg+0x803/0x920 net/socket.c:2311 __sys_sendmsg+0x105/0x1d0 net/socket.c:2356 __do_sys_sendmsg net/socket.c:2365 [inline] __se_sys_sendmsg net/socket.c:2363 [inline] __x64_sys_sendmsg+0x78/0xb0 net/socket.c:2363 do_syscall_64+0xfa/0x760 arch/x86/entry/common.c:290 entry_SYSCALL_64_after_hwframe+0x49/0xbe RIP: 0033:0x440369
--- net/sched/sch_dsmark.c | 2 ++ 1 file changed, 2 insertions(+)
net/sched/sch_dsmark.c +2 -0
@@ -357,6 +357,8 @@ static int dsmark_init(struct Qdisc *sch goto errout; err = -EINVAL ; +if (!tb[TCA_DSMARK_INDICES ]) + goto errout; indices =nla_get_u16 (tb[TCA_DSMARK_INDICES ]);if (hweight32 (indices) !=1 )
Greg Kroah-Hartman
maintainerPATCH 92/106 udp: fix gso_segs calculations
In reply to Greg Kroah-HartmanFrom: Josh Hunt <[email protected]>
[ Upstream commit 44b321e5020d782ad6e8ae8183f09b163be6e6e2 ]
Commit dfec0ee22c0a ("udp: Record gso_segs when supporting UDP segmentation offload") added gso_segs calculation, but incorrectly got sizeof() the pointer and not the underlying data type. In addition let's fix the v6 case.
--- net/ipv4/udp.c | 2 +- net/ipv6/udp.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-)
net/ipv4/udp.c +1 -1
@@ -810,7 +810,7 @@ static int udp_send_skb(struct sk_buff *skb_shinfo (skb)->gso_size = cork->gso_size;skb_shinfo (skb)->gso_type =SKB_GSO_UDP_L4 ; -skb_shinfo (skb)->gso_segs =DIV_ROUND_UP (len -sizeof (uh), +skb_shinfo (skb)->gso_segs =DIV_ROUND_UP (len -sizeof (*uh), cork->gso_size); goto csum_partial; }
net/ipv6/udp.c +2 -0
@@ -1081,6 +1081,8 @@ static int udp_v6_send_skb(struct sk_bufskb_shinfo (skb)->gso_size = cork->gso_size;skb_shinfo (skb)->gso_type =SKB_GSO_UDP_L4 ; +skb_shinfo (skb)->gso_segs =DIV_ROUND_UP (len -sizeof (*uh), + cork->gso_size); goto csum_partial; }
Greg Kroah-Hartman
maintainerPATCH 93/106 vsock: Fix a lockdep warning in __vsock_release()
In reply to Greg Kroah-HartmanFrom: Dexuan Cui <[email protected]>
[ Upstream commit 0d9138ffac24cf8b75366ede3a68c951e6dcc575 ]
Lockdep is unhappy if two locks from the same class are held.
Fix the below warning for hyperv and virtio sockets (vmci socket code doesn't have the issue) by using lock_sock_nested() when __vsock_release() is called recursively:
============================================
WARNING: possible recursive locking detected
5.3.0+ #1 Not tainted
--------------------------------------------
server/1795 is trying to acquire lock:ffff8880c5158990 (sk_lock-AF_VSOCK){+.+.}, at: hvs_release+0x10/0x120 [hv_sock]
but task is already holding lock:ffff8880c5158150 (sk_lock-AF_VSOCK){+.+.}, at: __vsock_release+0x2e/0xf0 [vsock]
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0
---- lock(sk_lock-AF_VSOCK);
lock(sk_lock-AF_VSOCK);
*** DEADLOCK ***
May be due to missing lock nesting notation
2 locks held by server/1795:
#0: ffff8880c5d05ff8 (&sb->s_type->i_mutex_key#10){+.+.}, at: __sock_release+0x2d/0xa0 #1: ffff8880c5158150 (sk_lock-AF_VSOCK){+.+.}, at: __vsock_release+0x2e/0xf0 [vsock]
stack backtrace: CPU: 5 PID: 1795 Comm: server Not tainted 5.3.0+ #1 Call Trace: dump_stack+0x67/0x90 __lock_acquire.cold.67+0xd2/0x20b lock_acquire+0xb5/0x1c0 lock_sock_nested+0x6d/0x90 hvs_release+0x10/0x120 [hv_sock] __vsock_release+0x24/0xf0 [vsock] __vsock_release+0xa0/0xf0 [vsock] vsock_release+0x12/0x30 [vsock] __sock_release+0x37/0xa0 sock_close+0x14/0x20 __fput+0xc1/0x250 task_work_run+0x98/0xc0 do_exit+0x344/0xc60 do_group_exit+0x47/0xb0 get_signal+0x15c/0xc50 do_signal+0x30/0x720 exit_to_usermode_loop+0x50/0xa0 do_syscall_64+0x24e/0x270 entry_SYSCALL_64_after_hwframe+0x49/0xbe RIP: 0033:0x7f4184e85f31
--- net/vmw_vsock/af_vsock.c | 16 ++++++++++++---- net/vmw_vsock/hyperv_transport.c | 2 +- net/vmw_vsock/virtio_transport_common.c | 2 +- 3 files changed, 14 insertions(+), 6 deletions(-)
net/vmw_vsock/af_vsock.c +12 -4
@@ -641,7 +641,7 @@ struct sock *__vsock_create(struct net * }EXPORT_SYMBOL_GPL (__vsock_create); -static void __vsock_release (struct sock *sk) +static void __vsock_release (struct sock *sk,int level) {if (sk) {struct sk_buff *skb;
@@ -651,9 +651,17 @@ static void __vsock_release(struct sock vsk =vsock_sk (sk); pending =NULL ;/* Compiler warning. */ +/* The release call is supposed to use lock_sock_nested() +* rather than lock_sock(), if a sock lock should be acquired. +*/ transport->release (vsk); -lock_sock (sk); +/* When "level" is SINGLE_DEPTH_NESTING, use the nested +* version to avoid the warning "possible recursive locking +* detected". When "level" is 0, lock_sock_nested(sk, level) +* is the same as lock_sock(sk). +*/ +lock_sock_nested (sk, level);sock_orphan (sk); sk->sk_shutdown =SHUTDOWN_MASK ;
@@ -662,7 +670,7 @@ static void __vsock_release(struct sock/* Clean up any sockets that never were accepted. */ while ((pending =vsock_dequeue_accept (sk)) !=NULL ) { -__vsock_release (pending); +__vsock_release (pending,SINGLE_DEPTH_NESTING );sock_put (pending); }
@@ -711,7 +719,7 @@ EXPORT_SYMBOL_GPL(vsock_stream_has_spacestatic int vsock_release (struct socket *sock) { -__vsock_release (sock->sk); +__vsock_release (sock->sk,0 ); sock->sk =NULL ; sock->state =SS_FREE ;
net/vmw_vsock/hyperv_transport.c +1 -1
@@ -538,7 +538,7 @@ static void hvs_release(struct vsock_socstruct sock *sk =sk_vsock (vsk);bool remove_sock; -lock_sock (sk); +lock_sock_nested (sk,SINGLE_DEPTH_NESTING ); remove_sock =hvs_close_lock_held (vsk);release_sock (sk);if (remove_sock)
net/vmw_vsock/virtio_transport_common.c +1 -1
@@ -791,7 +791,7 @@ void virtio_transport_release(struct vsostruct sock *sk = &vsk->sk;bool remove_sock = true; -lock_sock (sk); +lock_sock_nested (sk,SINGLE_DEPTH_NESTING );if (sk->sk_type ==SOCK_STREAM ) remove_sock =virtio_transport_close (vsk);
Greg Kroah-Hartman
maintainerPATCH 94/106 net: dsa: rtl8366: Check VLAN ID and not ports
In reply to Greg Kroah-HartmanFrom: Linus Walleij <[email protected]>
[ Upstream commit e8521e53cca584ddf8ec4584d3c550a6c65f88c4 ]
There has been some confusion between the port number and the VLAN ID in this driver. What we need to check for validity is the VLAN ID, nothing else.
The current confusion came from assigning a few default VLANs for default routing and we need to rewrite that properly.
Instead of checking if the port number is a valid VLAN ID, check the actual VLAN IDs passed in to the callback one by one as expected.
--- drivers/net/dsa/rtl8366.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
drivers/net/dsa/rtl8366.c +7 -4
@@ -339,10 +339,12 @@ int rtl8366_vlan_prepare(struct dsa_swit const struct switchdev_obj_port_vlan *vlan) {struct realtek_smi *smi = ds->priv; +u16 vid;int ret; -if (!smi->ops->is_vlan_valid (smi, port)) -return -EINVAL ; +for (vid = vlan->vid_begin; vid < vlan->vid_end; vid++) +if (!smi->ops->is_vlan_valid (smi, vid)) +return -EINVAL ;dev_info (smi->dev,"prepare VLANs %04x..%04x\n" , vlan->vid_begin, vlan->vid_end);
@@ -370,8 +372,9 @@ void rtl8366_vlan_add(struct dsa_switchu16 vid;int ret; -if (!smi->ops->is_vlan_valid (smi, port)) -return ; +for (vid = vlan->vid_begin; vid < vlan->vid_end; vid++) +if (!smi->ops->is_vlan_valid (smi, vid)) +return ; dev_info(smi->dev, "add VLAN on port %d, %s, %s\n", port,
Greg Kroah-Hartman
maintainerPATCH 95/106 udp: only do GSO if # of segs > 1
In reply to Greg Kroah-HartmanFrom: Josh Hunt <[email protected]>
[ Upstream commit 4094871db1d65810acab3d57f6089aa39ef7f648 ]
Prior to this change an application sending <= 1MSS worth of data and enabling UDP GSO would fail if the system had SW GSO enabled, but the same send would succeed if HW GSO offload is enabled. In addition to this inconsistency the error in the SW GSO case does not get back to the application if sending out of a real device so the user is unaware of this failure.
With this change we only perform GSO if the # of segments is > 1 even if the application has enabled segmentation. I've also updated the relevant udpgso selftests.
--- net/ipv4/udp.c | 11 +++++++---- net/ipv6/udp.c | 11 +++++++---- tools/testing/selftests/net/udpgso.c | 16 ++++------------ 3 files changed, 18 insertions(+), 20 deletions(-)
net/ipv4/udp.c +7 -4
@@ -775,6 +775,7 @@ static int udp_send_skb(struct sk_buff *int is_udplite =IS_UDPLITE (sk);int offset =skb_transport_offset (skb);int len = skb->len - offset; +int datalen = len -sizeof (*uh);__wsum csum =0 ;/*
@@ -808,10 +809,12 @@ static int udp_send_skb(struct sk_buff *return -EIO ; } -skb_shinfo (skb)->gso_size = cork->gso_size; -skb_shinfo (skb)->gso_type =SKB_GSO_UDP_L4 ; -skb_shinfo (skb)->gso_segs =DIV_ROUND_UP (len -sizeof (*uh), - cork->gso_size); +if (datalen > cork->gso_size) { +skb_shinfo (skb)->gso_size = cork->gso_size; +skb_shinfo (skb)->gso_type =SKB_GSO_UDP_L4 ; +skb_shinfo (skb)->gso_segs =DIV_ROUND_UP (datalen, + cork->gso_size); + } goto csum_partial; }
net/ipv6/udp.c +7 -4
@@ -1047,6 +1047,7 @@ static int udp_v6_send_skb(struct sk_buf__wsum csum =0 ;int offset =skb_transport_offset (skb);int len = skb->len - offset; +int datalen = len -sizeof (*uh);/* * Create a UDP header
@@ -1079,10 +1080,12 @@ static int udp_v6_send_skb(struct sk_bufreturn -EIO ; } -skb_shinfo (skb)->gso_size = cork->gso_size; -skb_shinfo (skb)->gso_type =SKB_GSO_UDP_L4 ; -skb_shinfo (skb)->gso_segs =DIV_ROUND_UP (len -sizeof (*uh), - cork->gso_size); +if (datalen > cork->gso_size) { +skb_shinfo (skb)->gso_size = cork->gso_size; +skb_shinfo (skb)->gso_type =SKB_GSO_UDP_L4 ; +skb_shinfo (skb)->gso_segs =DIV_ROUND_UP (datalen, + cork->gso_size); + } goto csum_partial; }
tools/testing/selftests/net/udpgso.c +4 -12
@@ -90,12 +90,9 @@ struct testcase testcases_v4[] = { .tfail = true, }, { -/* send a single MSS: will fail with GSO, because the segment -* logic in udp4_ufo_fragment demands a gso skb to be > MTU -*/ +/* send a single MSS: will fall back to no GSO */ .tlen = CONST_MSS_V4, .gso_len = CONST_MSS_V4, - .tfail = true, .r_num_mss = 1, }, {
@@ -140,10 +137,9 @@ struct testcase testcases_v4[] = { .tfail = true, }, { -/* send a single 1B MSS: will fail, see single MSS above */ +/* send a single 1B MSS: will fall back to no GSO */ .tlen = 1, .gso_len = 1, - .tfail = true, .r_num_mss = 1, }, {
@@ -197,12 +193,9 @@ struct testcase testcases_v6[] = { .tfail = true, }, { -/* send a single MSS: will fail with GSO, because the segment -* logic in udp4_ufo_fragment demands a gso skb to be > MTU -*/ +/* send a single MSS: will fall back to no GSO */ .tlen = CONST_MSS_V6, .gso_len = CONST_MSS_V6, - .tfail = true, .r_num_mss = 1, }, {
@@ -247,10 +240,9 @@ struct testcase testcases_v6[] = { .tfail = true, }, { -/* send a single 1B MSS: will fail, see single MSS above */ +/* send a single 1B MSS: will fall back to no GSO */ .tlen = 1, .gso_len = 1, - .tfail = true, .r_num_mss = 1, }, {
Greg Kroah-Hartman
maintainerPATCH 96/106 net/rds: Fix error handling in rds_ib_add_one()
In reply to Greg Kroah-HartmanFrom: Dotan Barak <[email protected]>
[ Upstream commit d64bf89a75b65f83f06be9fb8f978e60d53752db ]
rds_ibdev:ipaddr_list and rds_ibdev:conn_list are initialized after allocation some resources such as protection domain. If allocation of such resources fail, then these uninitialized variables are accessed in rds_ib_dev_free() in failure path. This can potentially crash the system. The code has been updated to initialize these variables very early in the function.
--- net/rds/ib.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
net/rds/ib.c +3 -3
@@ -143,6 +143,9 @@ static void rds_ib_add_one(struct ib_devrefcount_set (&rds_ibdev->refcount,1 );INIT_WORK (&rds_ibdev->free_work, rds_ib_dev_free); +INIT_LIST_HEAD (&rds_ibdev->ipaddr_list); +INIT_LIST_HEAD (&rds_ibdev->conn_list); + rds_ibdev->max_wrs = device->attrs.max_qp_wr; rds_ibdev->max_sge =min (device->attrs.max_send_sge,RDS_IB_MAX_SGE );
@@ -203,9 +206,6 @@ static void rds_ib_add_one(struct ib_dev device->name, rds_ibdev->use_fastreg ? "FRMR" : "FMR"); -INIT_LIST_HEAD (&rds_ibdev->ipaddr_list); -INIT_LIST_HEAD (&rds_ibdev->conn_list); -down_write (&rds_ib_devices_lock);list_add_tail_rcu (&rds_ibdev->list, &rds_ib_devices);up_write (&rds_ib_devices_lock);
Greg Kroah-Hartman
maintainerPATCH 97/106 xen-netfront: do not use ~0U as error return value for xennet_fill_frags()
In reply to Greg Kroah-HartmanFrom: Dongli Zhang <[email protected]>
[ Upstream commit a761129e3625688310aecf26e1be9e98e85f8eb5 ]
xennet_fill_frags() uses ~0U as return value when the sk_buff is not able to cache extra fragments. This is incorrect because the return type of xennet_fill_frags() is RING_IDX and 0xffffffff is an expected value for ring buffer index.
In the situation when the rsp_cons is approaching 0xffffffff, the return value of xennet_fill_frags() may become 0xffffffff which xennet_poll() (the caller) would regard as error. As a result, queue->rx.rsp_cons is set incorrectly because it is updated only when there is error. If there is no error, xennet_poll() would be responsible to update queue->rx.rsp_cons. Finally, queue->rx.rsp_cons would point to the rx ring buffer entries whose queue->rx_skbs[i] and queue->grant_rx_ref[i] are already cleared to NULL. This leads to NULL pointer access in the next iteration to process rx ring buffer entries.
The symptom is similar to the one fixed in
commit 00b368502d18 ("xen-netfront: do not assume sk_buff_head list is empty in error handling").
This patch changes the return type of xennet_fill_frags() to indicate whether it is successful or failed. The queue->rx.rsp_cons will be always updated inside this function.
--- drivers/net/xen-netfront.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-)
drivers/net/xen-netfront.c +9 -8
@@ -890,9 +890,9 @@ static int xennet_set_skb_gso(struct sk_return 0 ; } -static RING_IDX xennet_fill_frags (struct netfront_queue *queue, -struct sk_buff *skb, -struct sk_buff_head *list) +static int xennet_fill_frags (struct netfront_queue *queue, +struct sk_buff *skb, +struct sk_buff_head *list) {RING_IDX cons = queue->rx.rsp_cons;struct sk_buff *nskb;
@@ -911,7 +911,7 @@ static RING_IDX xennet_fill_frags(structif (unlikely (skb_shinfo (skb)->nr_frags >=MAX_SKB_FRAGS )) { queue->rx.rsp_cons = ++cons +skb_queue_len (list);kfree_skb (nskb); -return ~0U ; +return -ENOENT ; } skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
@@ -922,7 +922,9 @@ static RING_IDX xennet_fill_frags(structkfree_skb (nskb); } -return cons; + queue->rx.rsp_cons = cons; + +return 0 ; }static int checksum_setup (struct net_device *dev,struct sk_buff *skb)
@@ -1048,8 +1050,7 @@ err: skb->data_len = rx->status; skb->len += rx->status; - i =xennet_fill_frags (queue, skb, &tmpq); -if (unlikely (i == ~0U )) +if (unlikely (xennet_fill_frags (queue, skb, &tmpq))) goto err;if (rx->flags & XEN_NETRXF_csum_blank)
@@ -1059,7 +1060,7 @@ err:__skb_queue_tail (&rxq, skb); - queue->rx.rsp_cons = ++i; + i = ++queue->rx.rsp_cons; work_done++; }
Greg Kroah-Hartman
maintainerPATCH 98/106 tipc: fix unlimited bundling of small messages
In reply to Greg Kroah-HartmanFrom: Tuong Lien <[email protected]>
[ Upstream commit e95584a889e1902fdf1ded9712e2c3c3083baf96 ]
We have identified a problem with the "oversubscription" policy in the link transmission code.
When small messages are transmitted, and the sending link has reached the transmit window limit, those messages will be bundled and put into the link backlog queue. However, bundles of data messages are counted at the 'CRITICAL' level, so that the counter for that level, instead of the counter for the real, bundled message's level is the one being increased.
Subsequent, to-be-bundled data messages at non-CRITICAL levels continue to be tested against the unchanged counter for their own level, while contributing to an unrestrained increase at the CRITICAL backlog level.
This leaves a gap in congestion control algorithm for small messages that can result in starvation for other users or a "real" CRITICAL user. Even that eventually can lead to buffer exhaustion & link reset.
We fix this by keeping a 'target_bskb' buffer pointer at each levels, then when bundling, we only bundle messages at the same importance level only. This way, we know exactly how many slots a certain level have occupied in the queue, so can manage level congestion accurately.
By bundling messages at the same level, we even have more benefits. Let consider this:
- One socket sends 64-byte messages at the 'CRITICAL' level;
- Another sends 4096-byte messages at the 'LOW' level;
When a 64-byte message comes and is bundled the first time, we put the overhead of message bundle to it (+ 40-byte header, data copy, etc.) for later use, but the next message can be a 4096-byte one that cannot be bundled to the previous one. This means the last bundle carries only one payload message which is totally inefficient, as for the receiver also! Later on, another 64-byte message comes, now we make a new bundle and the same story repeats...
With the new bundling algorithm, this will not happen, the 64-byte messages will be bundled together even when the 4096-byte message(s) comes in between. However, if the 4096-byte messages are sent at the same level i.e. 'CRITICAL', the bundling algorithm will again cause the same overhead.
Also, the same will happen even with only one socket sending small messages at a rate close to the link transmit's one, so that, when one message is bundled, it's transmitted shortly. Then, another message comes, a new bundle is created and so on...
We will solve this issue radically by another patch.
--- net/tipc/link.c | 29 ++++++++++++++++++----------- net/tipc/msg.c | 5 +---- 2 files changed, 19 insertions(+), 15 deletions(-)
net/tipc/link.c +18 -11
@@ -161,6 +161,7 @@ struct tipc_link {struct {u16 len;u16 limit; +struct sk_buff *target_bskb; } backlog[5 ];u16 snd_nxt;u16 last_retransm;
@@ -846,6 +847,7 @@ static void link_prepare_wakeup(struct tvoid tipc_link_reset (struct tipc_link *l) {struct sk_buff_head list; +u32 imp;__skb_queue_head_init (&list);
@@ -864,11 +866,10 @@ void tipc_link_reset(struct tipc_link *l__skb_queue_purge (&l->transmq);__skb_queue_purge (&l->deferdq);__skb_queue_purge (&l->backlogq); - l->backlog[TIPC_LOW_IMPORTANCE ].len =0 ; - l->backlog[TIPC_MEDIUM_IMPORTANCE ].len =0 ; - l->backlog[TIPC_HIGH_IMPORTANCE ].len =0 ; - l->backlog[TIPC_CRITICAL_IMPORTANCE ].len =0 ; - l->backlog[TIPC_SYSTEM_IMPORTANCE ].len =0 ; +for (imp =0 ; imp <=TIPC_SYSTEM_IMPORTANCE ; imp++) { + l->backlog[imp].len =0 ; + l->backlog[imp].target_bskb =NULL ; + }kfree_skb (l->reasm_buf);kfree_skb (l->failover_reasm_skb); l->reasm_buf =NULL ;
@@ -909,7 +910,7 @@ int tipc_link_xmit(struct tipc_link *l,u16 bc_ack = l->bc_rcvlink->rcv_nxt -1 ;struct sk_buff_head *transmq = &l->transmq;struct sk_buff_head *backlogq = &l->backlogq; -struct sk_buff *skb, *_skb, *bskb; +struct sk_buff *skb, *_skb, **tskb;int pkt_cnt =skb_queue_len (list);int rc =0 ;
@@ -955,19 +956,21 @@ int tipc_link_xmit(struct tipc_link *l, seqno++;continue ; } -if (tipc_msg_bundle (skb_peek_tail (backlogq), hdr, mtu)) { + tskb = &l->backlog[imp].target_bskb; +if (tipc_msg_bundle (*tskb, hdr, mtu)) {kfree_skb (__skb_dequeue (list)); l->stats.sent_bundled++;continue ; } -if (tipc_msg_make_bundle (&bskb, hdr, mtu, l->addr)) { +if (tipc_msg_make_bundle (tskb, hdr, mtu, l->addr)) {kfree_skb (__skb_dequeue (list)); -__skb_queue_tail (backlogq, bskb); - l->backlog[msg_importance (buf_msg (bskb))].len++; +__skb_queue_tail (backlogq, *tskb); + l->backlog[imp].len++; l->stats.sent_bundled++; l->stats.sent_bundles++;continue ; } + l->backlog[imp].target_bskb =NULL ; l->backlog[imp].len +=skb_queue_len (list);skb_queue_splice_tail_init (list, backlogq); }
@@ -983,6 +986,7 @@ static void tipc_link_advance_backlog(stu16 seqno = l->snd_nxt;u16 ack = l->rcv_nxt -1 ;u16 bc_ack = l->bc_rcvlink->rcv_nxt -1 ; +u32 imp;while (skb_queue_len (&l->transmq) < l->window) { skb =skb_peek (&l->backlogq);
@@ -993,7 +997,10 @@ static void tipc_link_advance_backlog(stbreak ;__skb_dequeue (&l->backlogq); hdr =buf_msg (skb); - l->backlog[msg_importance (hdr)].len--; + imp =msg_importance (hdr); + l->backlog[imp].len--; +if (unlikely (skb == l->backlog[imp].target_bskb)) + l->backlog[imp].target_bskb =NULL ;__skb_queue_tail (&l->transmq, skb);__skb_queue_tail (xmitq, _skb);TIPC_SKB_CB (skb)->ackers = l->ackers;
net/tipc/msg.c +1 -4
@@ -484,10 +484,7 @@ bool tipc_msg_make_bundle(struct sk_buff bmsg =buf_msg (_skb);tipc_msg_init (msg_prevnode (msg), bmsg,MSG_BUNDLER ,0 ,INT_H_SIZE , dnode); -if (msg_isdata (msg)) -msg_set_importance (bmsg,TIPC_CRITICAL_IMPORTANCE ); -else -msg_set_importance (bmsg,TIPC_SYSTEM_IMPORTANCE ); +msg_set_importance (bmsg,msg_importance (msg));msg_set_seqno (bmsg,msg_seqno (msg));msg_set_ack (bmsg,msg_ack (msg));msg_set_bcast_ack (bmsg,msg_bcast_ack (msg));
Greg Kroah-Hartman
maintainerPATCH 99/106 sch_cbq: validate TCA_CBQ_WRROPT to avoid crash
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit e9789c7cc182484fc031fd88097eb14cb26c4596 ]
syzbot reported a crash in cbq_normalize_quanta() caused by an out of range cl->priority.
iproute2 enforces this check, but malicious users do not.
kasan: CONFIG_KASAN_INLINE enabled
kasan: GPF could be caused by NULL-ptr deref or user memory access
general protection fault: 0000 [#1] SMP KASAN PTI Modules linked in: CPU: 1 PID: 26447 Comm: syz-executor.1 Not tainted 5.3+ #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 RIP: 0010:cbq_normalize_quanta.part.0+0x1fd/0x430 net/sched/sch_cbq.c:902 RSP: 0018:ffff8801a5c333b0 EFLAGS: 00010206 RAX: 0000000020000003 RBX: 00000000fffffff8 RCX: ffffc9000712f000 RDX: 00000000000043bf RSI: ffffffff83be8962 RDI: 0000000100000018 RBP: ffff8801a5c33420 R08: 000000000000003a R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000000 R12: 00000000000002ef R13: ffff88018da95188 R14: dffffc0000000000 R15: 0000000000000015 FS: 00007f37d26b1700(0000) GS:ffff8801dad00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00000000004c7cec CR3: 00000001bcd0a006 CR4: 00000000001626f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: [<ffffffff83be9d57>] cbq_normalize_quanta include/net/pkt_sched.h:27 [inline] [<ffffffff83be9d57>] cbq_addprio net/sched/sch_cbq.c:1097 [inline] [<ffffffff83be9d57>] cbq_set_wrr+0x2d7/0x450 net/sched/sch_cbq.c:1115 [<ffffffff83bee8a7>] cbq_change_class+0x987/0x225b net/sched/sch_cbq.c:1537 [<ffffffff83b96985>] tc_ctl_tclass+0x555/0xcd0 net/sched/sch_api.c:2329 [<ffffffff83a84655>] rtnetlink_rcv_msg+0x485/0xc10 net/core/rtnetlink.c:5248 [<ffffffff83cadf0a>] netlink_rcv_skb+0x17a/0x460 net/netlink/af_netlink.c:2510 [<ffffffff83a7db6d>] rtnetlink_rcv+0x1d/0x30 net/core/rtnetlink.c:5266 [<ffffffff83cac2c6>] netlink_unicast_kernel net/netlink/af_netlink.c:1324 [inline] [<ffffffff83cac2c6>] netlink_unicast+0x536/0x720 net/netlink/af_netlink.c:1350 [<ffffffff83cacd4a>] netlink_sendmsg+0x89a/0xd50 net/netlink/af_netlink.c:1939 [<ffffffff8399d46e>] sock_sendmsg_nosec net/socket.c:673 [inline] [<ffffffff8399d46e>] sock_sendmsg+0x12e/0x170 net/socket.c:684 [<ffffffff8399f1fd>] ___sys_sendmsg+0x81d/0x960 net/socket.c:2359 [<ffffffff839a2d05>] __sys_sendmsg+0x105/0x1d0 net/socket.c:2397 [<ffffffff839a2df9>] SYSC_sendmsg net/socket.c:2406 [inline] [<ffffffff839a2df9>] SyS_sendmsg+0x29/0x30 net/socket.c:2404 [<ffffffff8101ccc8>] do_syscall_64+0x528/0x770 arch/x86/entry/common.c:305 [<ffffffff84400091>] entry_SYSCALL_64_after_hwframe+0x42/0xb7
--- net/sched/sch_cbq.c | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-)
net/sched/sch_cbq.c +28 -12
@@ -1132,6 +1132,32 @@ static const struct nla_policy cbq_polic [TCA_CBQ_POLICE] = { .len = sizeof(struct tc_cbq_police) }, }; +static int cbq_opt_parse (struct nlattr *tb[TCA_CBQ_MAX +1 ], +struct nlattr *opt, +struct netlink_ext_ack *extack) +{ +int err; + +if (!opt) { +NL_SET_ERR_MSG (extack,"CBQ options are required for this operation" ); +return -EINVAL ; + } + + err =nla_parse_nested (tb,TCA_CBQ_MAX , opt, cbq_policy, extack); +if (err <0 ) +return err; + +if (tb[TCA_CBQ_WRROPT ]) { +const struct tc_cbq_wrropt *wrr =nla_data (tb[TCA_CBQ_WRROPT ]); + +if (wrr->priority >TC_CBQ_MAXPRIO ) { +NL_SET_ERR_MSG (extack,"priority is bigger than TC_CBQ_MAXPRIO" ); + err = -EINVAL ; + } + } +return err; +} +static int cbq_init (struct Qdisc *sch,struct nlattr *opt,struct netlink_ext_ack *extack) {
@@ -1144,12 +1170,7 @@ static int cbq_init(struct Qdisc *sch, shrtimer_init (&q->delay_timer,CLOCK_MONOTONIC ,HRTIMER_MODE_ABS_PINNED ); q->delay_timer.function = cbq_undelay; -if (!opt) { -NL_SET_ERR_MSG (extack,"CBQ options are required for this operation" ); -return -EINVAL ; - } - - err =nla_parse_nested (tb,TCA_CBQ_MAX , opt, cbq_policy, extack); + err =cbq_opt_parse (tb, opt, extack);if (err <0 )return err;
@@ -1466,12 +1487,7 @@ cbq_change_class(struct Qdisc *sch, u32struct cbq_class *parent;struct qdisc_rate_table *rtab =NULL ; -if (!opt) { -NL_SET_ERR_MSG (extack,"Mandatory qdisc options missing" ); -return -EINVAL ; - } - - err =nla_parse_nested (tb,TCA_CBQ_MAX , opt, cbq_policy, extack); + err =cbq_opt_parse (tb, opt, extack);if (err <0 )return err;
Greg Kroah-Hartman
maintainerPATCH 100/106 soundwire: Kconfig: fix help format
In reply to Greg Kroah-HartmanFrom: Pierre-Louis Bossart <[email protected]>
[ Upstream commit 9d7cd9d500826a14fc68fb6994db375432866c6a ]
Move to the regular help format, --help-- is no longer recommended.
--- drivers/soundwire/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/soundwire/Kconfig +1 -1
@@ -4,7 +4,7 @@ menuconfig SOUNDWIRE bool "SoundWire support" - ---help--- + help SoundWire is a 2-Pin interface with data and clock line ratified by the MIPI Alliance. SoundWire is used for transporting data typically related to audio functions. SoundWire interface is
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 101/106 soundwire: fix regmap dependencies and align with other serial links
In reply to Greg Kroah-HartmanFrom: Pierre-Louis Bossart <[email protected]>
[ Upstream commit 8676b3ca4673517650fd509d7fa586aff87b3c28 ]
The existing code has a mixed select/depend usage which makes no sense.
config SOUNDWIRE_BUS
tristate
select REGMAP_SOUNDWIRE
config REGMAP_SOUNDWIRE
tristate
depends on SOUNDWIRE_BUS
Let's remove one layer of Kconfig definitions and align with the solutions used by all other serial links.
--- drivers/base/regmap/Kconfig | 2 +- drivers/soundwire/Kconfig | 7 +------ drivers/soundwire/Makefile | 2 +- 3 files changed, 3 insertions(+), 8 deletions(-)
drivers/base/regmap/Kconfig +1 -1
@@ -44,7 +44,7 @@ config REGMAP_IRQ config REGMAP_SOUNDWIRE tristate - depends on SOUNDWIRE_BUS + depends on SOUNDWIRE config REGMAP_SCCB tristate
drivers/soundwire/Kconfig +1 -6
@@ -3,7 +3,7 @@ # menuconfig SOUNDWIRE - bool "SoundWire support" + tristate "SoundWire support" help SoundWire is a 2-Pin interface with data and clock line ratified by the MIPI Alliance. SoundWire is used for transporting data
@@ -16,17 +16,12 @@ if SOUNDWIRE comment "SoundWire Devices" -config SOUNDWIRE_BUS - tristate - select REGMAP_SOUNDWIRE - config SOUNDWIRE_CADENCE tristate config SOUNDWIRE_INTEL tristate "Intel SoundWire Master driver" select SOUNDWIRE_CADENCE - select SOUNDWIRE_BUS depends on X86 && ACPI && SND_SOC ---help--- SoundWire Intel Master driver.
drivers/soundwire/Makefile +1 -1
@@ -4,7 +4,7 @@ #Bus Objs soundwire-bus-objs := bus_type.o bus.o slave.o mipi_disco.o stream.o -obj-$(CONFIG_SOUNDWIRE_BUS) += soundwire-bus.o +obj-$(CONFIG_SOUNDWIRE) += soundwire-bus.o #Cadence Objs soundwire-cadence-objs := cadence_master.o
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 102/106 Smack: Dont ignore other bprm->unsafe flags if LSM_UNSAFE_PTRACE is set
In reply to Greg Kroah-HartmanFrom: Jann Horn <[email protected]>
commit 3675f052b43ba51b99b85b073c7070e083f3e6fb upstream.
There is a logic bug in the current smack_bprm_set_creds():
If LSM_UNSAFE_PTRACE is set, but the ptrace state is deemed to be acceptable (e.g. because the ptracer detached in the meantime), the other ->unsafe flags aren't checked. As far as I can tell, this means that something like the following could work (but I haven't tested it):
- task A: create task B with fork()
- task B: set NO_NEW_PRIVS
- task B: install a seccomp filter that makes open() return 0 under some conditions
- task B: replace fd 0 with a malicious library
- task A: attach to task B with PTRACE_ATTACH
- task B: execve() a file with an SMACK64EXEC extended attribute
- task A: while task B is still in the middle of execve(), exit (which destroys the ptrace relationship)
Make sure that if any flags other than LSM_UNSAFE_PTRACE are set in bprm->unsafe, we reject the execve().
--- security/smack/smack_lsm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
security/smack/smack_lsm.c +2 -1
@@ -947,7 +947,8 @@ static int smack_bprm_set_creds(struct lif (rc !=0 )return rc; - }else if (bprm->unsafe) + } +if (bprm->unsafe & ~LSM_UNSAFE_PTRACE )return -EPERM ; bsp->smk_task = isp->smk_task;
Greg Kroah-Hartman
maintainerPATCH 103/106 smack: use GFP_NOFS while holding inode_smack::smk_lock
In reply to Greg Kroah-HartmanFrom: Eric Biggers <[email protected]>
commit e5bfad3d7acc5702f32aafeb388362994f4d7bd0 upstream.
inode_smack::smk_lock is taken during smack_d_instantiate(), which is called during a filesystem transaction when creating a file on ext4. Therefore to avoid a deadlock, all code that takes this lock must use GFP_NOFS, to prevent memory reclaim from waiting for the filesystem transaction to complete.
--- security/smack/smack_access.c | 6 +++--- security/smack/smack_lsm.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-)
security/smack/smack_access.c +3 -3
@@ -469,7 +469,7 @@ char *smk_parse_smack(const char *stringif (i ==0 || i >=SMK_LONGLABEL )return ERR_PTR (-EINVAL ); - smack =kzalloc (i +1 ,GFP_KERNEL ); + smack =kzalloc (i +1 ,GFP_NOFS );if (smack ==NULL )return ERR_PTR (-ENOMEM );
@@ -504,7 +504,7 @@ int smk_netlbl_mls(int level, char *catsif ((m & *cp) ==0 )continue ; rc =netlbl_catmap_setbit (&sap->attr.mls.cat, - cat,GFP_KERNEL ); + cat,GFP_NOFS );if (rc <0 ) {netlbl_catmap_free (sap->attr.mls.cat);return rc;
@@ -540,7 +540,7 @@ struct smack_known *smk_import_entry(conif (skp !=NULL ) goto freeout; - skp =kzalloc (sizeof (*skp),GFP_KERNEL ); + skp =kzalloc (sizeof (*skp),GFP_NOFS );if (skp ==NULL ) { skp =ERR_PTR (-ENOMEM ); goto freeout;
security/smack/smack_lsm.c +1 -1
@@ -270,7 +270,7 @@ static struct smack_known *smk_fetch(conif (!(ip->i_opflags &IOP_XATTR ))return ERR_PTR (-EOPNOTSUPP ); - buffer =kzalloc (SMK_LONGLABEL ,GFP_KERNEL ); + buffer =kzalloc (SMK_LONGLABEL ,GFP_NOFS );if (buffer ==NULL )return ERR_PTR (-ENOMEM );
Greg Kroah-Hartman
maintainerPATCH 104/106 NFC: fix attrs checks in netlink interface
In reply to Greg Kroah-HartmanFrom: Andrey Konovalov <[email protected]>
commit 18917d51472fe3b126a3a8f756c6b18085eb8130 upstream.
nfc_genl_deactivate_target() relies on the NFC_ATTR_TARGET_INDEX attribute being present, but doesn't check whether it is actually provided by the user. Same goes for nfc_genl_fw_download() and NFC_ATTR_FIRMWARE_NAME.
This patch adds appropriate checks.
Found with syzkaller.
--- net/nfc/netlink.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
net/nfc/netlink.c +4 -2
@@ -981,7 +981,8 @@ static int nfc_genl_dep_link_down(structint rc;u32 idx; -if (!info->attrs[NFC_ATTR_DEVICE_INDEX ]) +if (!info->attrs[NFC_ATTR_DEVICE_INDEX ] || + !info->attrs[NFC_ATTR_TARGET_INDEX ])return -EINVAL ; idx =nla_get_u32 (info->attrs[NFC_ATTR_DEVICE_INDEX ]);
@@ -1029,7 +1030,8 @@ static int nfc_genl_llc_get_params(strucstruct sk_buff *msg =NULL ;u32 idx; -if (!info->attrs[NFC_ATTR_DEVICE_INDEX ]) +if (!info->attrs[NFC_ATTR_DEVICE_INDEX ] || + !info->attrs[NFC_ATTR_FIRMWARE_NAME ])return -EINVAL ; idx =nla_get_u32 (info->attrs[NFC_ATTR_DEVICE_INDEX ]);
Greg Kroah-Hartman
maintainerPATCH 105/106 kexec: bail out upon SIGKILL when allocating memory.
In reply to Greg Kroah-HartmanFrom: Tetsuo Handa <[email protected]>
commit 7c3a6aedcd6aae0a32a527e68669f7dd667492d1 upstream.
syzbot found that a thread can stall for minutes inside kexec_load() after that thread was killed by SIGKILL [1]. It turned out that the reproducer was trying to allocate 2408MB of memory using kimage_alloc_page() from kimage_load_normal_segment(). Let's check for SIGKILL before doing memory allocation.
[1] https://syzkaller.appspot.com/bug?id=a0e3436829698d5824231251fad9d8e998f94f5e
--- kernel/kexec_core.c | 2 ++ 1 file changed, 2 insertions(+)
kernel/kexec_core.c +2 -0
@@ -301,6 +301,8 @@ static struct page *kimage_alloc_pages(g {struct page *pages; +if (fatal_signal_pending (current)) +return NULL ; pages =alloc_pages (gfp_mask & ~__GFP_ZERO, order);if (pages) {unsigned int count, i;
Greg Kroah-Hartman
maintainerPATCH 106/106 9p/cache.c: Fix memory leak in v9fs_cache_session_get_cookie
In reply to Greg Kroah-HartmanFrom: Bharath Vedartham <[email protected]>
commit 962a991c5de18452d6c429d99f3039387cf5cbb0 upstream.
v9fs_cache_session_get_cookie assigns a random cachetag to v9ses->cachetag, if the cachetag is not assigned previously.
v9fs_random_cachetag allocates memory to v9ses->cachetag with kmalloc and uses scnprintf to fill it up with a cachetag.
But if scnprintf fails, v9ses->cachetag is not freed in the current code causing a memory leak.
Fix this by freeing v9ses->cachetag it v9fs_random_cachetag fails.
This was reported by syzbot, the link to the report is below:
https://syzkaller.appspot.com/bug?id=f012bdf297a7a4c860c38a88b44fbee43fd9bbf3
--- fs/9p/cache.c | 2 ++ 1 file changed, 2 insertions(+)
fs/9p/cache.c +2 -0
@@ -66,6 +66,8 @@ void v9fs_cache_session_get_cookie(strucif (!v9ses->cachetag) {if (v9fs_random_cachetag (v9ses) <0 ) { v9ses->fscache =NULL ; +kfree (v9ses->cachetag); + v9ses->cachetag =NULL ;return ; } }
stable-rc/linux-4.19.y boot: 56 boots: 0 failed, 56 passed (v4.19.77-107-g61e72e79b84d)
stable-rc/linux-4.19.y boot: 56 boots: 0 failed, 56 passed (v4.19.77-107-g61e72e79b84d)
Full Boot Summary: https://kernelci.org/boot/all/job/stable-rc/branch/linux-4.19.y/kernel/v4.19.77-107-g61e72e79b84d/
Full Build Summary: https://kernelci.org/build/stable-rc/branch/linux-4.19.y/kernel/v4.19.77-107-g61e72e79b84d/
Tree: stable-rc
Branch: linux-4.19.y
Git Describe: v4.19.77-107-g61e72e79b84d
Git Commit: 61e72e79b84d3a2519ad88c10964d7e4fa11ef1d
Git URL: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
Tested: 39 unique boards, 16 SoC families, 12 builds out of 206
---
For more info write to <[email protected]>
Jon Hunter
maintainerQuoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.19.78 release. There are 106 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 Tue 08 Oct 2019 05:07:10 PM UTC. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.19.78-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-4.19.y
and the diffstat can be found below.thanks,
greg k-h
All tests are passing for Tegra ...
Test results for stable-v4.19:
12 builds: 12 pass, 0 fail
22 boots: 22 pass, 0 fail
32 tests: 32 pass, 0 failLinux version: 4.19.78-rc1-g61e72e79b84d
Boards tested: tegra124-jetson-tk1, tegra186-p2771-0000,
tegra194-p2972-0000, tegra20-ventana,
tegra210-p2371-2180, tegra30-cardhu-a04Cheers
Jon
Signature · 1 line
nvpublic
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.19.78 release. There are 106 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 Tue 08 Oct 2019 05:07:10 PM UTC. Anything received after that time might be too late.
Build results:
total: 156 pass: 156 fail: 0 Qemu test results: total: 390 pass: 390 fail: 0
Guenter
Hello!
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.19.78 release. There are 106 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 Tue 08 Oct 2019 05:07:10 PM UTC. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.19.78-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-4.19.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.
Patch "udp: only do GSO if # of segs > 1" updated net/ipv[46]/udp.c and the kselftest that goes with it. The system detected a failure in net/udpgso.sh this time as we are running kselftests 5.3.1, which currently includes a now-outdated version of this test. As soon as 5.3.5 is released, we'll upgrade kselftests and this test will pass again.
Because there's no regression (i.e. it passes with the updated test), there is nothing to worry about here. The same can be said of the 5.2 and 5.3 release candidates.
Summary
------------------------------------------------------------------------
kernel: 4.19.78-rc1
git repo: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
git branch: linux-4.19.y
git commit: 61e72e79b84d3a2519ad88c10964d7e4fa11ef1d
git describe: v4.19.77-107-g61e72e79b84d
Test details: https://qa-reports.linaro.org/lkft/linux-stable-rc-4.19-oe/build/v4.19.77-107-g61e72e79b84d
No regressions (compared to build v4.19.77)
No fixes (compared to build v4.19.77)
Ran 21962 total tests in the following environments and test suites.
Environments
--------------
- dragonboard-410c - arm64
- hi6220-hikey - arm64
- i386
- juno-r2 - arm64
- qemu_arm
- qemu_arm64
- qemu_i386
- qemu_x86_64
- x15 - arm
- x86_64
Test Suites
-----------
* build
* install-android-platform-tools-r2600
* kselftest
* libhugetlbfs
* 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
* perf
* spectre-meltdown-checker-test
* v4l2-compliance
* ltp-fs-tests
* network-basic-tests
* ltp-open-posix-tests
* kvm-unit-tests
* ssuite
* kselftest-vsyscall-mode-native
* kselftest-vsyscall-mode-none
Greetings!
Daniel Díaz
[email protected]
Signature · 2 lines
Linaro LKFT https://lkft.linaro.org