5.4.27-rc1 review
Subsystems (2)
Greg Kroah-Hartman
maintainercover 5.4.27-rc1 review
This is the start of the stable review cycle for the 5.4.27 release. There are 60 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 Sat, 21 Mar 2020 12:37:04 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.4.27-rc1.gz
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.4.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 5.4.27-rc1
Matteo Croce <[email protected]>
ipv4: ensure rcu_read_lock() in cipso_v4_error()
Ard Biesheuvel <[email protected]>
ARM: 8961/2: Fix Kbuild issue caused by per-task stack protector GCC plugin
Tony Fischetti <[email protected]>
HID: add ALWAYS_POLL quirk to lenovo pixart mouse
Chen-Tsung Hsieh <[email protected]>
HID: google: add moonball USB id
Jann Horn <[email protected]>
mm: slub: add missing TID bump in kmem_cache_alloc_bulk()
Kees Cook <[email protected]>
ARM: 8958/1: rename missed uaccess .fixup section
Florian Fainelli <[email protected]>
ARM: 8957/1: VDSO: Match ARMv8 timer in cntvct_functional()
Carl Huang <[email protected]>
net: qrtr: fix len of skb_put_padto in qrtr_node_enqueue
Ming Lei <[email protected]>
blk-mq: insert flush request to the front of dispatch queue
Qian Cai <[email protected]>
jbd2: fix data races at struct journal_head
Alex Maftei (amaftei) <[email protected]>
sfc: fix timestamp reconstruction at 16-bit rollover points
Taehee Yoo <[email protected]>
net: rmnet: fix packet forwarding in rmnet bridge mode
Taehee Yoo <[email protected]>
net: rmnet: fix bridge mode bugs
Taehee Yoo <[email protected]>
net: rmnet: use upper/lower device infrastructure
Taehee Yoo <[email protected]>
net: rmnet: do not allow to change mux id if mux id is duplicated
Taehee Yoo <[email protected]>
net: rmnet: remove rcu_read_lock in rmnet_force_unassociate_device()
Taehee Yoo <[email protected]>
net: rmnet: fix suspicious RCU usage
Taehee Yoo <[email protected]>
net: rmnet: fix NULL pointer dereference in rmnet_changelink()
Taehee Yoo <[email protected]>
net: rmnet: fix NULL pointer dereference in rmnet_newlink()
Luo bin <[email protected]>
hinic: fix a bug of rss configuration
Luo bin <[email protected]>
hinic: fix a bug of setting hw_ioctxt
Luo bin <[email protected]>
hinic: fix a irq affinity bug
Antoine Tenart <[email protected]>
net: phy: mscc: fix firmware paths
yangerkun <[email protected]>
slip: not call free_netdev before rtnl_unlock in slip_open
Linus Torvalds <[email protected]>
signal: avoid double atomic counter increments for user accounting
Masahiro Yamada <[email protected]>
kbuild: add dt_binding_check to PHONY in a correct place
Masahiro Yamada <[email protected]>
kbuild: add dtbs_check to PHONY
Monk Liu <[email protected]>
drm/amdgpu: fix memory leak during TDR test(v2)
Ming Lei <[email protected]>
blk-mq: insert passthrough request into hctx->dispatch directly
Esben Haabendal <[email protected]>
net: ll_temac: Handle DMA halt condition caused by buffer underrun
Esben Haabendal <[email protected]>
net: ll_temac: Fix RX buffer descriptor handling on GFP_ATOMIC pressure
Esben Haabendal <[email protected]>
net: ll_temac: Add more error handling of dma_map_single() calls
Esben Haabendal <[email protected]>
net: ll_temac: Fix race condition causing TX hang
Madhuparna Bhowmik <[email protected]>
mac80211: rx: avoid RCU list traversal under mutex
Marek Vasut <[email protected]>
net: ks8851-ml: Fix IRQ handling and locking
Daniele Palmas <[email protected]>
net: usb: qmi_wwan: restore mtu min/max values after raw_ip switch
Igor Druzhinin <[email protected]>
scsi: libfc: free response frame from GPN_ID
Johannes Berg <[email protected]>
cfg80211: check reg_rule for NULL in handle_channel_custom()
Tom Zanussi <[email protected]>
tracing: Fix number printing bug in print_synth_event()
Michael Ellerman <[email protected]>
selftests/rseq: Fix out-of-tree compilation
Nathan Chancellor <[email protected]>
MIPS: vdso: Wrap -mexplicit-relocs in cc-option
Hanno Zulla <[email protected]>
HID: hid-bigbenff: fix race condition for scheduled work during removal
Hanno Zulla <[email protected]>
HID: hid-bigbenff: call hid_hw_stop() in case of error
Hanno Zulla <[email protected]>
HID: hid-bigbenff: fix general protection fault caused by double kfree
Victor Kamensky <[email protected]>
mips: vdso: add build time check that no 'jalr t9' calls left
Paul Burton <[email protected]>
MIPS: Disable VDSO time functionality on microMIPS
Victor Kamensky <[email protected]>
mips: vdso: fix 'jalr t9' crash in vdso code
Kai-Heng Feng <[email protected]>
HID: i2c-hid: add Trekstor Surfbook E11B to descriptor override
Mika Westerberg <[email protected]>
ACPI: watchdog: Set default timeout in probe
Mansour Behabadi <[email protected]>
HID: apple: Add support for recent firmware on Magic Keyboards
Jean Delvare <[email protected]>
ACPI: watchdog: Allow disabling WDAT at boot
Ulf Hansson <[email protected]>
mmc: core: Respect MMC_CAP_NEED_RSP_BUSY for erase/trim/discard
Ulf Hansson <[email protected]>
mmc: core: Respect MMC_CAP_NEED_RSP_BUSY for eMMC sleep command
Ulf Hansson <[email protected]>
mmc: sdhci-omap: Fix busy detection by enabling MMC_CAP_NEED_RSP_BUSY
Ulf Hansson <[email protected]>
mmc: sdhci-tegra: Fix busy detection by enabling MMC_CAP_NEED_RSP_BUSY
Ulf Hansson <[email protected]>
mmc: core: Allow host controllers to require R1B for CMD6
Ulf Hansson <[email protected]>
mmc: core: Default to generic_cmd6_time as timeout in __mmc_switch()
Felix Kuehling <[email protected]>
drm/amdgpu: Fix TLB invalidation request when using semaphore
Cong Wang <[email protected]>
netfilter: xt_hashlimit: unregister proc file before releasing mutex
Florian Westphal <[email protected]>
netfilter: hashlimit: do not use indirect calls during gc
-------------
Diffstat:
Documentation/admin-guide/kernel-parameters.txt | 4 + Makefile | 7 +- arch/arm/Makefile | 4 +- arch/arm/boot/compressed/Makefile | 4 +- arch/arm/kernel/vdso.c | 2 + arch/arm/lib/copy_from_user.S | 2 +- arch/mips/vdso/Makefile | 28 ++- block/blk-flush.c | 2 +- block/blk-mq-sched.c | 44 ++++- block/blk-mq.c | 18 +- block/blk-mq.h | 3 +- drivers/acpi/acpi_watchdog.c | 12 +- drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c | 5 +- drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 8 +- drivers/gpu/drm/amd/powerplay/smu_v11_0.c | 6 +- drivers/hid/hid-apple.c | 3 +- drivers/hid/hid-bigbenff.c | 31 ++- drivers/hid/hid-google-hammer.c | 2 + drivers/hid/hid-ids.h | 2 + drivers/hid/hid-quirks.c | 1 + drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c | 8 + drivers/mmc/core/core.c | 5 +- drivers/mmc/core/mmc.c | 7 +- drivers/mmc/core/mmc_ops.c | 27 ++- drivers/mmc/host/sdhci-omap.c | 3 + drivers/mmc/host/sdhci-tegra.c | 3 + drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c | 1 + drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h | 2 +- drivers/net/ethernet/huawei/hinic/hinic_hw_if.h | 1 + drivers/net/ethernet/huawei/hinic/hinic_hw_qp.h | 1 + drivers/net/ethernet/huawei/hinic/hinic_main.c | 3 +- drivers/net/ethernet/huawei/hinic/hinic_rx.c | 5 +- drivers/net/ethernet/micrel/ks8851_mll.c | 14 +- drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c | 186 +++++++++--------- drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h | 3 +- .../net/ethernet/qualcomm/rmnet/rmnet_handlers.c | 7 +- drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c | 8 - drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.h | 1 - drivers/net/ethernet/sfc/ptp.c | 38 +++- drivers/net/ethernet/xilinx/ll_temac.h | 4 + drivers/net/ethernet/xilinx/ll_temac_main.c | 209 +++++++++++++++++---- drivers/net/phy/mscc.c | 4 +- drivers/net/slip/slip.c | 3 + drivers/net/usb/qmi_wwan.c | 3 + drivers/scsi/libfc/fc_disc.c | 2 + drivers/watchdog/wdat_wdt.c | 23 +++ fs/jbd2/transaction.c | 8 +- include/linux/mmc/host.h | 1 + kernel/signal.c | 23 ++- kernel/trace/trace_events_hist.c | 32 +++- mm/slub.c | 9 + net/ipv4/cipso_ipv4.c | 7 +- net/mac80211/rx.c | 2 +- net/netfilter/xt_hashlimit.c | 36 +--- net/qrtr/qrtr.c | 2 +- net/wireless/reg.c | 2 +- tools/testing/selftests/rseq/Makefile | 2 +- 57 files changed, 615 insertions(+), 268 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/60 netfilter: hashlimit: do not use indirect calls during gc
From: Florian Westphal <[email protected]>
[ Upstream commit 28b3a4270c0fc064557e409111f2a678e64b6fa7 ]
no need, just use a simple boolean to indicate we want to reap all entries.
--- net/netfilter/xt_hashlimit.c | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-)
net/netfilter/xt_hashlimit.c +4 -18
@@ -358,21 +358,7 @@ static int htable_create(struct net *net, struct hashlimit_cfg3 *cfg,return 0 ; } -static bool select_all (const struct xt_hashlimit_htable *ht, -const struct dsthash_ent *he) -{ -return true; -} - -static bool select_gc (const struct xt_hashlimit_htable *ht, -const struct dsthash_ent *he) -{ -return time_after_eq (jiffies, he->expires); -} - -static void htable_selective_cleanup (struct xt_hashlimit_htable *ht, -bool (*select)(const struct xt_hashlimit_htable *ht, -const struct dsthash_ent *he)) +static void htable_selective_cleanup (struct xt_hashlimit_htable *ht,bool select_all) {unsigned int i;
@@ -382,7 +368,7 @@ static void htable_selective_cleanup(struct xt_hashlimit_htable *ht,spin_lock_bh (&ht->lock);hlist_for_each_entry_safe (dh, n, &ht->hash[i], node) { -if ((*select)(ht, dh)) +if (time_after_eq (jiffies, dh->expires) || select_all)dsthash_free (ht, dh); }spin_unlock_bh (&ht->lock);
@@ -396,7 +382,7 @@ static void htable_gc(struct work_struct *work) ht = container_of(work, struct xt_hashlimit_htable, gc_work.work); -htable_selective_cleanup (ht, select_gc); +htable_selective_cleanup (ht, false);queue_delayed_work (system_power_efficient_wq, &ht->gc_work,msecs_to_jiffies (ht->cfg.gc_interval));
@@ -420,7 +406,7 @@ static void htable_destroy(struct xt_hashlimit_htable *hinfo) {cancel_delayed_work_sync (&hinfo->gc_work);htable_remove_proc_entry (hinfo); -htable_selective_cleanup (hinfo, select_all); +htable_selective_cleanup (hinfo, true);kfree (hinfo->name);vfree (hinfo); }
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 2/60 netfilter: xt_hashlimit: unregister proc file before releasing mutex
In reply to Greg Kroah-HartmanFrom: Cong Wang <[email protected]>
[ Upstream commit 99b79c3900d4627672c85d9f344b5b0f06bc2a4d ]
Before releasing the global mutex, we only unlink the hashtable from the hash list, its proc file is still not unregistered at this point. So syzbot could trigger a race condition where a parallel htable_create() could register the same file immediately after the mutex is released.
Move htable_remove_proc_entry() back to mutex protection to fix this. And, fold htable_destroy() into htable_put() to make the code slightly easier to understand.
--- net/netfilter/xt_hashlimit.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-)
net/netfilter/xt_hashlimit.c +6 -10
@@ -402,15 +402,6 @@ static void htable_remove_proc_entry(struct xt_hashlimit_htable *hinfo)remove_proc_entry (hinfo->name, parent); } -static void htable_destroy (struct xt_hashlimit_htable *hinfo) -{ -cancel_delayed_work_sync (&hinfo->gc_work); -htable_remove_proc_entry (hinfo); -htable_selective_cleanup (hinfo, true); -kfree (hinfo->name); -vfree (hinfo); -} -static struct xt_hashlimit_htable *htable_find_get (struct net *net,const char *name,u_int8_t family)
@@ -432,8 +423,13 @@ static void htable_put(struct xt_hashlimit_htable *hinfo) {if (refcount_dec_and_mutex_lock (&hinfo->use, &hashlimit_mutex)) {hlist_del (&hinfo->node); +htable_remove_proc_entry (hinfo);mutex_unlock (&hashlimit_mutex); -htable_destroy (hinfo); + +cancel_delayed_work_sync (&hinfo->gc_work); +htable_selective_cleanup (hinfo, true); +kfree (hinfo->name); +vfree (hinfo); } }
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 3/60 drm/amdgpu: Fix TLB invalidation request when using semaphore
In reply to Greg Kroah-HartmanFrom: Felix Kuehling <[email protected]>
[ Upstream commit 37c58ddf57364d1a636850bb8ba6acbe1e16195e ]
Use a more meaningful variable name for the invalidation request that is distinct from the tmp variable that gets overwritten when acquiring the invalidation semaphore.
--- drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c | 5 +++-- drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 8 ++++---- 2 files changed, 7 insertions(+), 6 deletions(-)
drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c +3 -2
@@ -230,7 +230,8 @@ static void gmc_v10_0_flush_vm_hub(struct amdgpu_device *adev, uint32_t vmid, unsigned int vmhub, uint32_t flush_type) {struct amdgpu_vmhub *hub = &adev->vmhub[vmhub]; -u32 tmp =gmc_v10_0_get_invalidate_req (vmid, flush_type); +u32 inv_req =gmc_v10_0_get_invalidate_req (vmid, flush_type); +u32 tmp;/* Use register 17 for GART */ const unsigned eng =17 ;unsigned int i;
@@ -258,7 +259,7 @@ static void gmc_v10_0_flush_vm_hub(struct amdgpu_device *adev, uint32_t vmid,DRM_ERROR ("Timeout waiting for sem acquire in VM flush!\n" ); } -WREG32_NO_KIQ (hub->vm_inv_eng0_req + eng, tmp); +WREG32_NO_KIQ (hub->vm_inv_eng0_req + eng, inv_req);/* * Issue a dummy read to wait for the ACK register to be cleared
drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +4 -4
@@ -487,13 +487,13 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid, {bool use_semaphore =gmc_v9_0_use_invalidate_semaphore (adev, vmhub);const unsigned eng =17 ; -u32 j, tmp; +u32 j, inv_req, tmp;struct amdgpu_vmhub *hub;BUG_ON (vmhub >= adev->num_vmhubs); hub = &adev->vmhub[vmhub]; - tmp =gmc_v9_0_get_invalidate_req (vmid, flush_type); + inv_req =gmc_v9_0_get_invalidate_req (vmid, flush_type);/* This is necessary for a HW workaround under SRIOV as well * as GFXOFF under bare metal
@@ -504,7 +504,7 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,uint32_t req = hub->vm_inv_eng0_req + eng;uint32_t ack = hub->vm_inv_eng0_ack + eng; -amdgpu_virt_kiq_reg_write_reg_wait (adev, req, ack, tmp, +amdgpu_virt_kiq_reg_write_reg_wait (adev, req, ack, inv_req,1 << vmid);return ; }
@@ -532,7 +532,7 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,DRM_ERROR ("Timeout waiting for sem acquire in VM flush!\n" ); } -WREG32_NO_KIQ (hub->vm_inv_eng0_req + eng, tmp); +WREG32_NO_KIQ (hub->vm_inv_eng0_req + eng, inv_req);/* * Issue a dummy read to wait for the ACK register to be cleared
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 4/60 mmc: core: Default to generic_cmd6_time as timeout in __mmc_switch()
In reply to Greg Kroah-HartmanFrom: Ulf Hansson <[email protected]>
[ Upstream commit 533a6cfe08f96a7b5c65e06d20916d552c11b256 ]
All callers of __mmc_switch() should now be specifying a valid timeout for the CMD6 command. However, just to be sure, let's print a warning and default to use the generic_cmd6_time in case the provided timeout_ms argument is zero.
In this context, let's also simplify some of the corresponding code and clarify some related comments.
--- drivers/mmc/core/mmc_ops.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-)
drivers/mmc/core/mmc_ops.c +11 -14
@@ -458,10 +458,6 @@ static int mmc_poll_for_busy(struct mmc_card *card, unsigned int timeout_ms,bool expired = false;bool busy = false; -/* We have an unspecified cmd timeout, use the fallback value. */ -if (!timeout_ms) - timeout_ms =MMC_OPS_TIMEOUT_MS ; -/* * In cases when not allowed to poll by using CMD13 or because we aren't * capable of polling by using ->card_busy(), then rely on waiting the
@@ -534,14 +530,19 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,mmc_retune_hold (host); +if (!timeout_ms) { +pr_warn ("%s: unspecified timeout for CMD6 - use generic\n" , +mmc_hostname (host)); + timeout_ms = card->ext_csd.generic_cmd6_time; + } +/* -* If the cmd timeout and the max_busy_timeout of the host are both -* specified, let's validate them. A failure means we need to prevent -* the host from doing hw busy detection, which is done by converting -* to a R1 response instead of a R1B. +* If the max_busy_timeout of the host is specified, make sure it's +* enough to fit the used timeout_ms. In case it's not, let's instruct +* the host to avoid HW busy detection, by converting to a R1 response +* instead of a R1B. */ -if (timeout_ms && host->max_busy_timeout && - (timeout_ms > host->max_busy_timeout)) +if (host->max_busy_timeout && (timeout_ms > host->max_busy_timeout)) use_r1b_resp = false; cmd.opcode =MMC_SWITCH ;
@@ -552,10 +553,6 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, cmd.flags =MMC_CMD_AC ;if (use_r1b_resp) { cmd.flags |=MMC_RSP_SPI_R1B |MMC_RSP_R1B ; -/* -* A busy_timeout of zero means the host can decide to use -* whatever value it finds suitable. -*/ cmd.busy_timeout = timeout_ms; }else { cmd.flags |=MMC_RSP_SPI_R1 |MMC_RSP_R1 ;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 5/60 mmc: core: Allow host controllers to require R1B for CMD6
In reply to Greg Kroah-HartmanFrom: Ulf Hansson <[email protected]>
[ Upstream commit 1292e3efb149ee21d8d33d725eeed4e6b1ade963 ]
It has turned out that some host controllers can't use R1B for CMD6 and other commands that have R1B associated with them. Therefore invent a new host cap, MMC_CAP_NEED_RSP_BUSY to let them specify this.
In __mmc_switch(), let's check the flag and use it to prevent R1B responses from being converted into R1. Note that, this also means that the host are on its own, when it comes to manage the busy timeout.
--- drivers/mmc/core/mmc_ops.c | 6 ++++-- include/linux/mmc/host.h | 1 + 2 files changed, 5 insertions(+), 2 deletions(-)
drivers/mmc/core/mmc_ops.c +4 -2
@@ -540,9 +540,11 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,* If the max_busy_timeout of the host is specified, make sure it's * enough to fit the used timeout_ms. In case it's not, let's instruct * the host to avoid HW busy detection, by converting to a R1 response -* instead of a R1B. +* instead of a R1B. Note, some hosts requires R1B, which also means +* they are on their own when it comes to deal with the busy timeout. */ -if (host->max_busy_timeout && (timeout_ms > host->max_busy_timeout)) +if (!(host->caps &MMC_CAP_NEED_RSP_BUSY ) && host->max_busy_timeout && + (timeout_ms > host->max_busy_timeout)) use_r1b_resp = false; cmd.opcode =MMC_SWITCH ;
include/linux/mmc/host.h +1 -0
@@ -333,6 +333,7 @@ struct mmc_host { MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | \ MMC_CAP_UHS_DDR50)#define MMC_CAP_SYNC_RUNTIME_PM (1 << 21)/* Synced runtime PM suspends. */ +#define MMC_CAP_NEED_RSP_BUSY (1 << 22)/* Commands with R1B can't use R1. */ #define MMC_CAP_DRIVER_TYPE_A (1 << 23)/* Host supports Driver Type A */ #define MMC_CAP_DRIVER_TYPE_C (1 << 24)/* Host supports Driver Type C */ #define MMC_CAP_DRIVER_TYPE_D (1 << 25)/* Host supports Driver Type D */
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 6/60 mmc: sdhci-tegra: Fix busy detection by enabling MMC_CAP_NEED_RSP_BUSY
In reply to Greg Kroah-HartmanFrom: Ulf Hansson <[email protected]>
[ Upstream commit d2f8bfa4bff5028bc40ed56b4497c32e05b0178f ]
It has turned out that the sdhci-tegra controller requires the R1B response, for commands that has this response associated with them. So, converting from an R1B to an R1 response for a CMD6 for example, leads to problems with the HW busy detection support.
Fix this by informing the mmc core about the requirement, via setting the host cap, MMC_CAP_NEED_RSP_BUSY.
--- drivers/mmc/host/sdhci-tegra.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/mmc/host/sdhci-tegra.c +3 -0
@@ -1552,6 +1552,9 @@ static int sdhci_tegra_probe(struct platform_device *pdev)if (tegra_host->soc_data->nvquirks &NVQUIRK_ENABLE_DDR50 ) host->mmc->caps |=MMC_CAP_1_8V_DDR ; +/* R1B responses is required to properly manage HW busy detection. */ + host->mmc->caps |=MMC_CAP_NEED_RSP_BUSY ; +tegra_sdhci_parse_dt (host); tegra_host->power_gpio = devm_gpiod_get_optional(&pdev->dev, "power",
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 7/60 mmc: sdhci-omap: Fix busy detection by enabling MMC_CAP_NEED_RSP_BUSY
In reply to Greg Kroah-HartmanFrom: Ulf Hansson <[email protected]>
[ Upstream commit 055e04830d4544c57f2a5192a26c9e25915c29c0 ]
It has turned out that the sdhci-omap controller requires the R1B response, for commands that has this response associated with them. So, converting from an R1B to an R1 response for a CMD6 for example, leads to problems with the HW busy detection support.
Fix this by informing the mmc core about the requirement, via setting the host cap, MMC_CAP_NEED_RSP_BUSY.
--- drivers/mmc/host/sdhci-omap.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/mmc/host/sdhci-omap.c +3 -0
@@ -1134,6 +1134,9 @@ static int sdhci_omap_probe(struct platform_device *pdev) host->mmc_host_ops.execute_tuning = sdhci_omap_execute_tuning; host->mmc_host_ops.enable_sdio_irq = sdhci_omap_enable_sdio_irq; +/* R1B responses is required to properly manage HW busy detection. */ + mmc->caps |=MMC_CAP_NEED_RSP_BUSY ; + ret =sdhci_setup_host (host);if (ret) goto err_put_sync;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 8/60 mmc: core: Respect MMC_CAP_NEED_RSP_BUSY for eMMC sleep command
In reply to Greg Kroah-HartmanFrom: Ulf Hansson <[email protected]>
[ Upstream commit 18d200460cd73636d4f20674085c39e32b4e0097 ]
The busy timeout for the CMD5 to put the eMMC into sleep state, is specific to the card. Potentially the timeout may exceed the host->max_busy_timeout. If that becomes the case, mmc_sleep() converts from using an R1B response to an R1 response, as to prevent the host from doing HW busy detection.
However, it has turned out that some hosts requires an R1B response no matter what, so let's respect that via checking MMC_CAP_NEED_RSP_BUSY. Note that, if the R1B gets enforced, the host becomes fully responsible of managing the needed busy timeout, in one way or the other.
--- drivers/mmc/core/mmc.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/mmc/core/mmc.c +5 -2
@@ -1911,9 +1911,12 @@ static int mmc_sleep(struct mmc_host *host)* If the max_busy_timeout of the host is specified, validate it against * the sleep cmd timeout. A failure means we need to prevent the host * from doing hw busy detection, which is done by converting to a R1 -* response instead of a R1B. +* response instead of a R1B. Note, some hosts requires R1B, which also +* means they are on their own when it comes to deal with the busy +* timeout. */ -if (host->max_busy_timeout && (timeout_ms > host->max_busy_timeout)) { +if (!(host->caps &MMC_CAP_NEED_RSP_BUSY ) && host->max_busy_timeout && + (timeout_ms > host->max_busy_timeout)) { cmd.flags =MMC_RSP_R1 |MMC_CMD_AC ; }else { cmd.flags =MMC_RSP_R1B |MMC_CMD_AC ;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 9/60 mmc: core: Respect MMC_CAP_NEED_RSP_BUSY for erase/trim/discard
In reply to Greg Kroah-HartmanFrom: Ulf Hansson <[email protected]>
[ Upstream commit 43cc64e5221cc6741252b64bc4531dd1eefb733d ]
The busy timeout that is computed for each erase/trim/discard operation, can become quite long and may thus exceed the host->max_busy_timeout. If that becomes the case, mmc_do_erase() converts from using an R1B response to an R1 response, as to prevent the host from doing HW busy detection.
However, it has turned out that some hosts requires an R1B response no matter what, so let's respect that via checking MMC_CAP_NEED_RSP_BUSY. Note that, if the R1B gets enforced, the host becomes fully responsible of managing the needed busy timeout, in one way or the other.
--- drivers/mmc/core/core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/mmc/core/core.c +4 -1
@@ -1732,8 +1732,11 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from,* the erase operation does not exceed the max_busy_timeout, we should * use R1B response. Or we need to prevent the host from doing hw busy * detection, which is done by converting to a R1 response instead. +* Note, some hosts requires R1B, which also means they are on their own +* when it comes to deal with the busy timeout. */ -if (card->host->max_busy_timeout && +if (!(card->host->caps &MMC_CAP_NEED_RSP_BUSY ) && + card->host->max_busy_timeout && busy_timeout > card->host->max_busy_timeout) { cmd.flags =MMC_RSP_SPI_R1 |MMC_RSP_R1 |MMC_CMD_AC ; }else {
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 10/60 ACPI: watchdog: Allow disabling WDAT at boot
In reply to Greg Kroah-HartmanFrom: Jean Delvare <[email protected]>
[ Upstream commit 3f9e12e0df012c4a9a7fd7eb0d3ae69b459d6b2c ]
In case the WDAT interface is broken, give the user an option to ignore it to let a native driver bind to the watchdog device instead.
--- Documentation/admin-guide/kernel-parameters.txt | 4 ++++ drivers/acpi/acpi_watchdog.c | 12 +++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-)
Documentation/admin-guide/kernel-parameters.txt +4 -0
@@ -136,6 +136,10 @@ dynamic table installation which will install SSDT tables to /sys/firmware/acpi/tables/dynamic. + acpi_no_watchdog [HW,ACPI,WDT] + Ignore the ACPI-based watchdog interface (WDAT) and let + a native driver control the watchdog device instead. + acpi_rsdp= [ACPI,EFI,KEXEC] Pass the RSDP address to the kernel, mostly used on machines running EFI runtime service to boot the
drivers/acpi/acpi_watchdog.c +11 -1
@@ -55,12 +55,14 @@ static bool acpi_watchdog_uses_rtc(const struct acpi_table_wdat *wdat) }#endif +static bool acpi_no_watchdog; +static const struct acpi_table_wdat *acpi_watchdog_get_wdat (void ) {const struct acpi_table_wdat *wdat =NULL ;acpi_status status; -if (acpi_disabled) +if (acpi_disabled || acpi_no_watchdog)return NULL ; status = acpi_get_table(ACPI_SIG_WDAT, 0,
@@ -88,6 +90,14 @@ bool acpi_has_watchdog(void) }EXPORT_SYMBOL_GPL (acpi_has_watchdog); +/* ACPI watchdog can be disabled on boot command line */ +static int __init disable_acpi_watchdog (char *str) +{ + acpi_no_watchdog = true; +return 1 ; +} +__setup ("acpi_no_watchdog" , disable_acpi_watchdog); +void __init acpi_watchdog_init (void ) {const struct acpi_wdat_entry *entries;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 11/60 HID: apple: Add support for recent firmware on Magic Keyboards
In reply to Greg Kroah-HartmanFrom: Mansour Behabadi <[email protected]>
[ Upstream commit e433be929e63265b7412478eb7ff271467aee2d7 ]
Magic Keyboards with more recent firmware (0x0100) report Fn key differently. Without this patch, Fn key may not behave as expected and may not be configurable via hid_apple fnmode module parameter.
--- drivers/hid/hid-apple.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/hid/hid-apple.c +2 -1
@@ -340,7 +340,8 @@ static int apple_input_mapping(struct hid_device *hdev, struct hid_input *hi, unsigned long **bit, int *max) {if (usage->hid == (HID_UP_CUSTOM |0x0003 ) || - usage->hid == (HID_UP_MSVENDOR |0x0003 )) { + usage->hid == (HID_UP_MSVENDOR |0x0003 ) || + usage->hid == (HID_UP_HPVENDOR2 |0x0003 )) {/* The fn key on Apple USB keyboards */ set_bit (EV_REP , hi->input->evbit);hid_map_usage_clear (hi, usage, bit, max,EV_KEY ,KEY_FN );
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 12/60 ACPI: watchdog: Set default timeout in probe
In reply to Greg Kroah-HartmanFrom: Mika Westerberg <[email protected]>
[ Upstream commit cabe17d0173ab04bd3f87b8199ae75f43f1ea473 ]
If the BIOS default timeout for the watchdog is too small userspace may not have enough time to configure new timeout after opening the device before the system is already reset. For this reason program default timeout of 30 seconds in the driver probe and allow userspace to change this from command line or through module parameter (wdat_wdt.timeout).
--- drivers/watchdog/wdat_wdt.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
drivers/watchdog/wdat_wdt.c +23 -0
@@ -54,6 +54,13 @@ module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); +#define WDAT_DEFAULT_TIMEOUT 30 + +static int timeout =WDAT_DEFAULT_TIMEOUT ; +module_param (timeout, int,0 ); +MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds (default=" + __MODULE_STRING(WDAT_DEFAULT_TIMEOUT) ")"); +static int wdat_wdt_read (struct wdat_wdt *wdat,const struct wdat_instruction *instr,u32 *value) {
@@ -438,6 +445,22 @@ static int wdat_wdt_probe(struct platform_device *pdev)platform_set_drvdata (pdev, wdat); +/* +* Set initial timeout so that userspace has time to configure the +* watchdog properly after it has opened the device. In some cases +* the BIOS default is too short and causes immediate reboot. +*/ +if (timeout *1000 < wdat->wdd.min_hw_heartbeat_ms || + timeout *1000 > wdat->wdd.max_hw_heartbeat_ms) { +dev_warn (dev,"Invalid timeout %d given, using %d\n" , + timeout,WDAT_DEFAULT_TIMEOUT ); + timeout =WDAT_DEFAULT_TIMEOUT ; + } + + ret =wdat_wdt_set_timeout (&wdat->wdd, timeout); +if (ret) +return ret; +watchdog_set_nowayout (&wdat->wdd, nowayout);return devm_watchdog_register_device (dev, &wdat->wdd); }
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 13/60 HID: i2c-hid: add Trekstor Surfbook E11B to descriptor override
In reply to Greg Kroah-HartmanFrom: Kai-Heng Feng <[email protected]>
[ Upstream commit be0aba826c4a6ba5929def1962a90d6127871969 ]
The Surfbook E11B uses the SIPODEV SP1064 touchpad, which does not supply descriptors, so it has to be added to the override list.
--- drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c +8 -0
@@ -341,6 +341,14 @@ static const struct dmi_system_id i2c_hid_dmi_desc_override_table[] = { }, .driver_data = (void *)&sipodev_desc }, + { + .ident = "Trekstor SURFBOOK E11B", + .matches = { +DMI_EXACT_MATCH (DMI_SYS_VENDOR ,"TREKSTOR" ), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SURFBOOK E11B"), + }, + .driver_data = (void *)&sipodev_desc + }, { .ident ="Direkt-Tek DTLAPY116-2" , .matches = {
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 14/60 mips: vdso: fix jalr t9 crash in vdso code
In reply to Greg Kroah-HartmanFrom: Victor Kamensky <[email protected]>
[ Upstream commit d3f703c4359ff06619b2322b91f69710453e6b6d ]
Observed that when kernel is built with Yocto mips64-poky-linux-gcc, and mips64-poky-linux-gnun32-gcc toolchain, resulting vdso contains 'jalr t9' instructions in its code and since in vdso case nobody sets GOT table code crashes when instruction reached. On other hand observed that when kernel is built mips-poky-linux-gcc toolchain, the same 'jalr t9' instruction are replaced with PC relative function calls using 'bal' instructions.
The difference boils down to -mrelax-pic-calls and -mexplicit-relocs gcc options that gets different default values depending on gcc target triplets and corresponding binutils. -mrelax-pic-calls got enabled by default only in mips-poky-linux-gcc case. MIPS binutils ld relies on R_MIPS_JALR relocation to convert 'jalr t9' into 'bal' and such relocation is generated only if -mrelax-pic-calls option is on.
Please note 'jalr t9' conversion to 'bal' can happen only to static functions. These static PIC calls use mips local GOT entries that are supposed to be filled with start of DSO value by run-time linker (missing in VDSO case) and they do not have dynamic relocations. Global mips GOT entries must have dynamic relocations and they should be prevented by cmd_vdso_check Makefile rule.
Solution call out -mrelax-pic-calls and -mexplicit-relocs options explicitly while compiling MIPS vdso code. That would get correct and consistent between different toolchains behaviour.
--- arch/mips/vdso/Makefile | 1 + 1 file changed, 1 insertion(+)
arch/mips/vdso/Makefile +1 -0
@@ -29,6 +29,7 @@ endif cflags-vdso := $(ccflags-vdso) \ $(filter -W%,$(filter-out -Wa$(comma)%,$(KBUILD_CFLAGS))) \ -O3 -g -fPIC -fno-strict-aliasing -fno-common -fno-builtin -G 0 \ + -mrelax-pic-calls -mexplicit-relocs \ -fno-stack-protector -fno-jump-tables -DDISABLE_BRANCH_PROFILING \ $(call cc-option, -fno-asynchronous-unwind-tables) \ $(call cc-option, -fno-stack-protector)
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 15/60 MIPS: Disable VDSO time functionality on microMIPS
In reply to Greg Kroah-HartmanFrom: Paul Burton <[email protected]>
[ Upstream commit 07015d7a103c4420b69a287b8ef4d2535c0f4106 ]
A check we're about to add to pick up on function calls that depend on bogus use of the GOT in the VDSO picked up on instances of such function calls in microMIPS builds. Since the code appears genuinely problematic, and given the relatively small amount of use & testing that microMIPS sees, go ahead & disable the VDSO for microMIPS builds.
--- arch/mips/vdso/Makefile | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-)
arch/mips/vdso/Makefile +17 -2
@@ -48,6 +48,8 @@ endif CFLAGS_REMOVE_vgettimeofday.o = -pg +DISABLE_VDSO := n + # # For the pre-R6 code in arch/mips/vdso/vdso.h for locating # the base address of VDSO, the linker will emit a R_MIPS_PC32
@@ -61,11 +63,24 @@ CFLAGS_REMOVE_vgettimeofday.o = -pg ifndef CONFIG_CPU_MIPSR6 ifeq ($(call ld-ifversion, -lt, 225000000, y),y) $(warning MIPS VDSO requires binutils >= 2.25) - obj-vdso-y := $(filter-out vgettimeofday.o, $(obj-vdso-y)) - ccflags-vdso += -DDISABLE_MIPS_VDSO + DISABLE_VDSO := y endif endif +# +# GCC (at least up to version 9.2) appears to emit function calls that make use +# of the GOT when targeting microMIPS, which we can't use in the VDSO due to +# the lack of relocations. As such, we disable the VDSO for microMIPS builds. +# +ifdef CONFIG_CPU_MICROMIPS + DISABLE_VDSO := y +endif + +ifeq ($(DISABLE_VDSO),y) + obj-vdso-y := $(filter-out vgettimeofday.o, $(obj-vdso-y)) + ccflags-vdso += -DDISABLE_MIPS_VDSO +endif + # VDSO linker flags. VDSO_LDFLAGS := \ -Wl,-Bsymbolic -Wl,--no-undefined -Wl,-soname=linux-vdso.so.1 \
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 16/60 mips: vdso: add build time check that no jalr t9 calls left
In reply to Greg Kroah-HartmanFrom: Victor Kamensky <[email protected]>
[ Upstream commit 976c23af3ee5bd3447a7bfb6c356ceb4acf264a6 ]
vdso shared object cannot have GOT based PIC 'jalr t9' calls because nobody set GOT table in vdso. Contributing into vdso .o files are compiled in PIC mode and as result for internal static functions calls compiler will generate 'jalr t9' instructions. Those are supposed to be converted into PC relative 'bal' calls by linker when relocation are processed.
Mips global GOT entries do have dynamic relocations and they will be caught by cmd_vdso_check Makefile rule. Static PIC calls go through mips local GOT entries that do not have dynamic relocations. For those 'jalr t9' calls could be present but without dynamic relocations and they need to be converted to 'bal' calls by linker.
Add additional build time check to make sure that no 'jalr t9' slip through because of some toolchain misconfiguration that prevents 'jalr t9' to 'bal' conversion.
--- arch/mips/vdso/Makefile | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
arch/mips/vdso/Makefile +7 -1
@@ -92,12 +92,18 @@ CFLAGS_REMOVE_vdso.o = -pg GCOV_PROFILE := n UBSAN_SANITIZE := n +# Check that we don't have PIC 'jalr t9' calls left +quiet_cmd_vdso_mips_check = VDSOCHK $@ + cmd_vdso_mips_check = if $(OBJDUMP) --disassemble $@ | egrep -h "jalr.*t9" > /dev/null; \ + then (echo >&2 "$@: PIC 'jalr t9' calls are not supported"; \ + rm -f $@; /bin/false); fi + # # Shared build commands. # quiet_cmd_vdsold_and_vdso_check = LD $@ - cmd_vdsold_and_vdso_check = $(cmd_vdsold); $(cmd_vdso_check) + cmd_vdsold_and_vdso_check = $(cmd_vdsold); $(cmd_vdso_check); $(cmd_vdso_mips_check) quiet_cmd_vdsold = VDSO $@ cmd_vdsold = $(CC) $(c_flags) $(VDSO_LDFLAGS) \
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 17/60 HID: hid-bigbenff: fix general protection fault caused by double kfree
In reply to Greg Kroah-HartmanFrom: Hanno Zulla <[email protected]>
[ Upstream commit 789a2c250340666220fa74bc6c8f58497e3863b3 ]
The struct *bigben was allocated via devm_kzalloc() and then used as a parameter in input_ff_create_memless(). This caused a double kfree during removal of the device, since both the managed resource API and ml_ff_destroy() in drivers/input/ff-memless.c would call kfree() on it.
--- drivers/hid/hid-bigbenff.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
drivers/hid/hid-bigbenff.c +8 -2
@@ -220,10 +220,16 @@ static void bigben_worker(struct work_struct *work)static int hid_bigben_play_effect (struct input_dev *dev,void *data,struct ff_effect *effect) { -struct bigben_device *bigben = data; +struct hid_device *hid =input_get_drvdata (dev); +struct bigben_device *bigben =hid_get_drvdata (hid);u8 right_motor_on;u8 left_motor_force; +if (!bigben) { +hid_err (hid,"no device data\n" ); +return 0 ; + } +if (effect->type !=FF_RUMBLE )return 0 ;
@@ -341,7 +347,7 @@ static int bigben_probe(struct hid_device *hid,INIT_WORK (&bigben->worker, bigben_worker); - error =input_ff_create_memless (hidinput->input, bigben, + error =input_ff_create_memless (hidinput->input,NULL , hid_bigben_play_effect);if (error)return error;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 18/60 HID: hid-bigbenff: call hid_hw_stop() in case of error
In reply to Greg Kroah-HartmanFrom: Hanno Zulla <[email protected]>
[ Upstream commit 976a54d0f4202cb412a3b1fc7f117e1d97db35f3 ]
It's required to call hid_hw_stop() once hid_hw_start() was called previously, so error cases need to handle this. Also, hid_hw_close() is not necessary during removal.
--- drivers/hid/hid-bigbenff.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
drivers/hid/hid-bigbenff.c +10 -5
@@ -305,7 +305,6 @@ static void bigben_remove(struct hid_device *hid)struct bigben_device *bigben =hid_get_drvdata (hid);cancel_work_sync (&bigben->worker); -hid_hw_close (hid);hid_hw_stop (hid); }
@@ -350,7 +349,7 @@ static int bigben_probe(struct hid_device *hid, error =input_ff_create_memless (hidinput->input,NULL , hid_bigben_play_effect);if (error) -return error; + goto error_hw_stop; name_sz =strlen (dev_name (&hid->dev)) +strlen (":red:bigben#" ) +1 ;
@@ -360,8 +359,10 @@ static int bigben_probe(struct hid_device *hid,sizeof (struct led_classdev ) + name_sz,GFP_KERNEL ); -if (!led) -return -ENOMEM ; +if (!led) { + error = -ENOMEM ; + goto error_hw_stop; + } name = (void *)(&led[1 ]); snprintf(name, name_sz, "%s:red:bigben%d",
@@ -375,7 +376,7 @@ static int bigben_probe(struct hid_device *hid, bigben->leds[n] = led; error =devm_led_classdev_register (&hid->dev, led);if (error) -return error; + goto error_hw_stop; }/* initial state: LED1 is on, no rumble effect */
@@ -389,6 +390,10 @@ static int bigben_probe(struct hid_device *hid,hid_info (hid,"LED and force feedback support for BigBen gamepad\n" );return 0 ; + +error_hw_stop: +hid_hw_stop (hid); +return error; } static __u8 *bigben_report_fixup(struct hid_device *hid, __u8 *rdesc,
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 19/60 HID: hid-bigbenff: fix race condition for scheduled work during removal
In reply to Greg Kroah-HartmanFrom: Hanno Zulla <[email protected]>
[ Upstream commit 4eb1b01de5b9d8596d6c103efcf1a15cfc1bedf7 ]
It's possible that there is scheduled work left while the device is already being removed, which can cause a kernel crash. Adding a flag will avoid this.
--- drivers/hid/hid-bigbenff.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/hid/hid-bigbenff.c +6 -0
@@ -174,6 +174,7 @@ static __u8 pid0902_rdesc_fixed[] = {struct bigben_device {struct hid_device *hid;struct hid_report *report; +bool removed;u8 led_state;/* LED1 = 1 .. LED4 = 8 */ u8 right_motor_on;/* right motor off/on 0/1 */ u8 left_motor_force;/* left motor force 0-255 */
@@ -190,6 +191,9 @@ static void bigben_worker(struct work_struct *work) struct bigben_device, worker);struct hid_field *report_field = bigben->report->field[0 ]; +if (bigben->removed) +return ; +if (bigben->work_led) { bigben->work_led = false; report_field->value[0 ] =0x01 ;/* 1 = led message */
@@ -304,6 +308,7 @@ static void bigben_remove(struct hid_device *hid) {struct bigben_device *bigben =hid_get_drvdata (hid); + bigben->removed = true;cancel_work_sync (&bigben->worker);hid_hw_stop (hid); }
@@ -324,6 +329,7 @@ static int bigben_probe(struct hid_device *hid,return -ENOMEM ;hid_set_drvdata (hid, bigben); bigben->hid = hid; + bigben->removed = false; error =hid_parse (hid);if (error) {
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 20/60 MIPS: vdso: Wrap -mexplicit-relocs in cc-option
In reply to Greg Kroah-HartmanFrom: Nathan Chancellor <[email protected]>
[ Upstream commit 72cf3b3df423c1bbd8fa1056fed009d3a260f8a9 ]
Clang does not support this option and errors out:
clang-11: error: unknown argument: '-mexplicit-relocs'
Clang does not appear to need this flag like GCC does because the jalr check that was added in commit 976c23af3ee5 ("mips: vdso: add build time check that no 'jalr t9' calls left") passes just fine with
$ make ARCH=mips CC=clang CROSS_COMPILE=mipsel-linux-gnu- malta_defconfig arch/mips/vdso/
even before commit d3f703c4359f ("mips: vdso: fix 'jalr t9' crash in vdso code").
-mrelax-pic-calls has been supported since clang 9, which is the earliest version that could build a working MIPS kernel, and it is the default for clang so just leave it be.
--- arch/mips/vdso/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/mips/vdso/Makefile +1 -1
@@ -29,7 +29,7 @@ endif cflags-vdso := $(ccflags-vdso) \ $(filter -W%,$(filter-out -Wa$(comma)%,$(KBUILD_CFLAGS))) \ -O3 -g -fPIC -fno-strict-aliasing -fno-common -fno-builtin -G 0 \ - -mrelax-pic-calls -mexplicit-relocs \ + -mrelax-pic-calls $(call cc-option, -mexplicit-relocs) \ -fno-stack-protector -fno-jump-tables -DDISABLE_BRANCH_PROFILING \ $(call cc-option, -fno-asynchronous-unwind-tables) \ $(call cc-option, -fno-stack-protector)
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 21/60 selftests/rseq: Fix out-of-tree compilation
In reply to Greg Kroah-HartmanFrom: Michael Ellerman <[email protected]>
[ Upstream commit ef89d0545132d685f73da6f58b7e7fe002536f91 ]
Currently if you build with O=... the rseq tests don't build:
$ make O=$PWD/output -C tools/testing/selftests/ TARGETS=rseq make: Entering directory '/linux/tools/testing/selftests' ... make[1]: Entering directory '/linux/tools/testing/selftests/rseq' gcc -O2 -Wall -g -I./ -I../../../../usr/include/ -L./ -Wl,-rpath=./ -shared -fPIC rseq.c -lpthread -o /linux/output/rseq/librseq.so gcc -O2 -Wall -g -I./ -I../../../../usr/include/ -L./ -Wl,-rpath=./ basic_test.c -lpthread -lrseq -o /linux/output/rseq/basic_test /usr/bin/ld: cannot find -lrseq collect2: error: ld returned 1 exit status
This is because the library search path points to the source directory, not the output.
We can fix it by changing the library search path to $(OUTPUT).
--- tools/testing/selftests/rseq/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/testing/selftests/rseq/Makefile +1 -1
@@ -4,7 +4,7 @@ ifneq ($(shell $(CC) --version 2>&1 | head -n 1 | grep clang),) CLANG_FLAGS += -no-integrated-as endif -CFLAGS += -O2 -Wall -g -I./ -I../../../../usr/include/ -L./ -Wl,-rpath=./ \ +CFLAGS += -O2 -Wall -g -I./ -I../../../../usr/include/ -L$(OUTPUT) -Wl,-rpath=./ \ $(CLANG_FLAGS) LDLIBS += -lpthread
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 22/60 tracing: Fix number printing bug in print_synth_event()
In reply to Greg Kroah-HartmanFrom: Tom Zanussi <[email protected]>
[ Upstream commit 784bd0847eda032ed2f3522f87250655a18c0190 ]
Fix a varargs-related bug in print_synth_event() which resulted in strange output and oopses on 32-bit x86 systems. The problem is that trace_seq_printf() expects the varargs to match the format string, but print_synth_event() was always passing u64 values regardless. This results in unspecified behavior when unpacking with va_arg() in trace_seq_printf().
Add a function that takes the size into account when calling trace_seq_printf().
Before:
modprobe-1731 [003] .... 919.039758: gen_synth_test: next_pid_field=777(null)next_comm_field=hula hoops ts_ns=1000000 ts_ms=1000 cpu=3(null)my_string_field=thneed my_int_field=598(null)
After:
insmod-1136 [001] .... 36.634590: gen_synth_test: next_pid_field=777 next_comm_field=hula hoops ts_ns=1000000 ts_ms=1000 cpu=1 my_string_field=thneed my_int_field=598
--- kernel/trace/trace_events_hist.c | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-)
kernel/trace/trace_events_hist.c +29 -3
@@ -811,6 +811,29 @@ static const char *synth_field_fmt(char *type)return fmt; } +static void print_synth_event_num_val (struct trace_seq *s, +char *print_fmt,char *name, +int size,u64 val,char *space) +{ +switch (size) { +case 1 : +trace_seq_printf (s, print_fmt, name, (u8 )val, space); +break ; + +case 2 : +trace_seq_printf (s, print_fmt, name, (u16 )val, space); +break ; + +case 4 : +trace_seq_printf (s, print_fmt, name, (u32 )val, space); +break ; + +default : +trace_seq_printf (s, print_fmt, name, val, space); +break ; + } +} +static enum print_line_t print_synth_event (struct trace_iterator *iter,int flags,struct trace_event *event)
@@ -849,10 +872,13 @@ static enum print_line_t print_synth_event(struct trace_iterator *iter, }else {struct trace_print_flags __flags[] = { __def_gfpflag_names, {-1 ,NULL } }; +char *space = (i == se->n_fields -1 ?"" :" " ); -trace_seq_printf (s, print_fmt, se->fields[i]->name, - entry->fields[n_u64], - i == se->n_fields -1 ?"" :" " ); +print_synth_event_num_val (s, print_fmt, + se->fields[i]->name, + se->fields[i]->size, + entry->fields[n_u64], + space);if (strcmp (se->fields[i]->type,"gfp_t" ) ==0 ) {trace_seq_puts (s," (" );
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 23/60 cfg80211: check reg_rule for NULL in handle_channel_custom()
In reply to Greg Kroah-HartmanFrom: Johannes Berg <[email protected]>
[ Upstream commit a7ee7d44b57c9ae174088e53a668852b7f4f452d ]
We may end up with a NULL reg_rule after the loop in handle_channel_custom() if the bandwidth didn't fit, check if this is the case and bail out if so.
--- net/wireless/reg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/wireless/reg.c +1 -1
@@ -2276,7 +2276,7 @@ static void handle_channel_custom(struct wiphy *wiphy,break ; } -if (IS_ERR (reg_rule)) { +if (IS_ERR_OR_NULL (reg_rule)) {pr_debug ("Disabling freq %d MHz as custom regd has no rule that fits it\n" , chan->center_freq);if (wiphy->regulatory_flags ®ULATORY_WIPHY_SELF_MANAGED ) {
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 24/60 scsi: libfc: free response frame from GPN_ID
In reply to Greg Kroah-HartmanFrom: Igor Druzhinin <[email protected]>
[ Upstream commit ff6993bb79b9f99bdac0b5378169052931b65432 ]
fc_disc_gpn_id_resp() should be the last function using it so free it here to avoid memory leak.
--- drivers/scsi/libfc/fc_disc.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/scsi/libfc/fc_disc.c +2 -0
@@ -628,6 +628,8 @@ static void fc_disc_gpn_id_resp(struct fc_seq *sp, struct fc_frame *fp, } out:kref_put (&rdata->kref, fc_rport_destroy); +if (!IS_ERR (fp)) +fc_frame_free (fp); }/**
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 25/60 net: usb: qmi_wwan: restore mtu min/max values after raw_ip switch
In reply to Greg Kroah-HartmanFrom: Daniele Palmas <[email protected]>
[ Upstream commit eae7172f8141eb98e64e6e81acc9e9d5b2add127 ]
usbnet creates network interfaces with min_mtu = 0 and max_mtu = ETH_MAX_MTU.
These values are not modified by qmi_wwan when the network interface is created initially, allowing, for example, to set mtu greater than 1500.
When a raw_ip switch is done (raw_ip set to 'Y', then set to 'N') the mtu values for the network interface are set through ether_setup, with min_mtu = ETH_MIN_MTU and max_mtu = ETH_DATA_LEN, not allowing anymore to set mtu greater than 1500 (error: mtu greater than device maximum).
The patch restores the original min/max mtu values set by usbnet after a raw_ip switch.
--- drivers/net/usb/qmi_wwan.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/usb/qmi_wwan.c +3 -0
@@ -337,6 +337,9 @@ static void qmi_wwan_netdev_setup(struct net_device *net)netdev_dbg (net,"mode: raw IP\n" ); }else if (!net->header_ops) {/* don't bother if already set */ ether_setup (net); +/* Restoring min/max mtu values set originally by usbnet */ + net->min_mtu =0 ; + net->max_mtu =ETH_MAX_MTU ;clear_bit (EVENT_NO_IP_ALIGN , &dev->flags);netdev_dbg (net,"mode: Ethernet\n" ); }
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 26/60 net: ks8851-ml: Fix IRQ handling and locking
In reply to Greg Kroah-HartmanFrom: Marek Vasut <[email protected]>
[ Upstream commit 44343418d0f2f623cb9da6f5000df793131cbe3b ]
The KS8851 requires that packet RX and TX are mutually exclusive. Currently, the driver hopes to achieve this by disabling interrupt from the card by writing the card registers and by disabling the interrupt on the interrupt controller. This however is racy on SMP.
Replace this approach by expanding the spinlock used around the ks_start_xmit() TX path to ks_irq() RX path to assure true mutual exclusion and remove the interrupt enabling/disabling, which is now not needed anymore. Furthermore, disable interrupts also in ks_net_stop(), which was missing before.
Note that a massive improvement here would be to re-use the KS8851 driver approach, which is to move the TX path into a worker thread, interrupt handling to threaded interrupt, and synchronize everything with mutexes, but that would be a much bigger rework, for a separate patch.
--- drivers/net/ethernet/micrel/ks8851_mll.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
drivers/net/ethernet/micrel/ks8851_mll.c +8 -6
@@ -513,14 +513,17 @@ static irqreturn_t ks_irq(int irq, void *pw) {struct net_device *netdev = pw;struct ks_net *ks =netdev_priv (netdev); +unsigned long flags;u16 status; +spin_lock_irqsave (&ks->statelock, flags);/*this should be the first in IRQ handler */ ks_save_cmd_reg (ks); status =ks_rdreg16 (ks,KS_ISR );if (unlikely (!status)) {ks_restore_cmd_reg (ks); +spin_unlock_irqrestore (&ks->statelock, flags);return IRQ_NONE ; }
@@ -546,6 +549,7 @@ static irqreturn_t ks_irq(int irq, void *pw) ks->netdev->stats.rx_over_errors++;/* this should be the last in IRQ handler*/ ks_restore_cmd_reg (ks); +spin_unlock_irqrestore (&ks->statelock, flags);return IRQ_HANDLED ; }
@@ -615,6 +619,7 @@ static int ks_net_stop(struct net_device *netdev)/* shutdown RX/TX QMU */ ks_disable_qmu (ks); +ks_disable_int (ks);/* set powermode to soft power down to save power */ ks_set_powermode (ks,PMECR_PM_SOFTDOWN );
@@ -671,10 +676,9 @@ static netdev_tx_t ks_start_xmit(struct sk_buff *skb, struct net_device *netdev) {netdev_tx_t retv =NETDEV_TX_OK ;struct ks_net *ks =netdev_priv (netdev); +unsigned long flags; -disable_irq (netdev->irq); -ks_disable_int (ks); -spin_lock (&ks->statelock); +spin_lock_irqsave (&ks->statelock, flags);/* Extra space are required: * 4 byte for alignment, 4 for status/length, 4 for CRC
@@ -688,9 +692,7 @@ static netdev_tx_t ks_start_xmit(struct sk_buff *skb, struct net_device *netdev)dev_kfree_skb (skb); }else retv =NETDEV_TX_BUSY ; -spin_unlock (&ks->statelock); -ks_enable_int (ks); -enable_irq (netdev->irq); +spin_unlock_irqrestore (&ks->statelock, flags);return retv; }
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 27/60 mac80211: rx: avoid RCU list traversal under mutex
In reply to Greg Kroah-HartmanFrom: Madhuparna Bhowmik <[email protected]>
[ Upstream commit 253216ffb2a002a682c6f68bd3adff5b98b71de8 ]
local->sta_mtx is held in __ieee80211_check_fast_rx_iface(). No need to use list_for_each_entry_rcu() as it also requires a cond argument to avoid false lockdep warnings when not used in RCU read-side section (with CONFIG_PROVE_RCU_LIST). Therefore use list_for_each_entry();
--- net/mac80211/rx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/mac80211/rx.c +1 -1
@@ -4114,7 +4114,7 @@ void __ieee80211_check_fast_rx_iface(struct ieee80211_sub_if_data *sdata)lockdep_assert_held (&local->sta_mtx); -list_for_each_entry_rcu (sta, &local->sta_list, list) { +list_for_each_entry (sta, &local->sta_list, list) {if (sdata != sta->sdata && (!sta->sdata->bss || sta->sdata->bss != sdata->bss))continue ;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 28/60 net: ll_temac: Fix race condition causing TX hang
In reply to Greg Kroah-HartmanFrom: Esben Haabendal <[email protected]>
[ Upstream commit 84823ff80f7403752b59e00bb198724100dc611c ]
It is possible that the interrupt handler fires and frees up space in the TX ring in between checking for sufficient TX ring space and stopping the TX queue in temac_start_xmit. If this happens, the queue wake from the interrupt handler will occur before the queue is stopped, causing a lost wakeup and the adapter's transmit hanging.
To avoid this, after stopping the queue, check again whether there is sufficient space in the TX ring. If so, wake up the queue again.
This is a port of the similar fix in axienet driver,
commit 7de44285c1f6 ("net: axienet: Fix race condition causing TX hang").
--- drivers/net/ethernet/xilinx/ll_temac_main.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-)
drivers/net/ethernet/xilinx/ll_temac_main.c +16 -3
@@ -788,6 +788,9 @@ static void temac_start_xmit_done(struct net_device *ndev) stat =be32_to_cpu (cur_p->app0); } +/* Matches barrier in temac_start_xmit */ +smp_mb (); +netif_wake_queue (ndev); }
@@ -830,9 +833,19 @@ temac_start_xmit(struct sk_buff *skb, struct net_device *ndev) cur_p = &lp->tx_bd_v[lp->tx_bd_tail];if (temac_check_tx_bd_space (lp, num_frag +1 )) { -if (!netif_queue_stopped (ndev)) -netif_stop_queue (ndev); -return NETDEV_TX_BUSY ; +if (netif_queue_stopped (ndev)) +return NETDEV_TX_BUSY ; + +netif_stop_queue (ndev); + +/* Matches barrier in temac_start_xmit_done */ +smp_mb (); + +/* Space might have just been freed - check again */ +if (temac_check_tx_bd_space (lp, num_frag)) +return NETDEV_TX_BUSY ; + +netif_wake_queue (ndev); } cur_p->app0 =0 ;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 29/60 net: ll_temac: Add more error handling of dma_map_single() calls
In reply to Greg Kroah-HartmanFrom: Esben Haabendal <[email protected]>
[ Upstream commit d07c849cd2b97d6809430dfb7e738ad31088037a ]
This adds error handling to the remaining dma_map_single() calls, so that behavior is well defined if/when we run out of DMA memory.
--- drivers/net/ethernet/xilinx/ll_temac_main.c | 26 +++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-)
drivers/net/ethernet/xilinx/ll_temac_main.c +24 -2
@@ -367,6 +367,8 @@ static int temac_dma_bd_init(struct net_device *ndev) skb_dma_addr =dma_map_single (ndev->dev.parent, skb->data,XTE_MAX_JUMBO_FRAME_SIZE ,DMA_FROM_DEVICE ); +if (dma_mapping_error (ndev->dev.parent, skb_dma_addr)) + goto out; lp->rx_bd_v[i].phys =cpu_to_be32 (skb_dma_addr); lp->rx_bd_v[i].len =cpu_to_be32 (XTE_MAX_JUMBO_FRAME_SIZE ); lp->rx_bd_v[i].app0 =cpu_to_be32 (STS_CTRL_APP0_IRQONEND );
@@ -863,12 +865,13 @@ temac_start_xmit(struct sk_buff *skb, struct net_device *ndev) skb_dma_addr =dma_map_single (ndev->dev.parent, skb->data,skb_headlen (skb),DMA_TO_DEVICE ); cur_p->len =cpu_to_be32 (skb_headlen (skb)); +if (WARN_ON_ONCE (dma_mapping_error (ndev->dev.parent, skb_dma_addr))) +return NETDEV_TX_BUSY ; cur_p->phys =cpu_to_be32 (skb_dma_addr);ptr_to_txbd ((void *)skb, cur_p);for (ii =0 ; ii < num_frag; ii++) { - lp->tx_bd_tail++; -if (lp->tx_bd_tail >=TX_BD_NUM ) +if (++lp->tx_bd_tail >=TX_BD_NUM ) lp->tx_bd_tail =0 ; cur_p = &lp->tx_bd_v[lp->tx_bd_tail];
@@ -876,6 +879,25 @@ temac_start_xmit(struct sk_buff *skb, struct net_device *ndev)skb_frag_address (frag),skb_frag_size (frag), DMA_TO_DEVICE); +if (dma_mapping_error (ndev->dev.parent, skb_dma_addr)) { +if (--lp->tx_bd_tail <0 ) + lp->tx_bd_tail =TX_BD_NUM -1 ; + cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; +while (--ii >=0 ) { + --frag; +dma_unmap_single (ndev->dev.parent, +be32_to_cpu (cur_p->phys), +skb_frag_size (frag), +DMA_TO_DEVICE ); +if (--lp->tx_bd_tail <0 ) + lp->tx_bd_tail =TX_BD_NUM -1 ; + cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; + } +dma_unmap_single (ndev->dev.parent, +be32_to_cpu (cur_p->phys), +skb_headlen (skb),DMA_TO_DEVICE ); +return NETDEV_TX_BUSY ; + } cur_p->phys =cpu_to_be32 (skb_dma_addr); cur_p->len =cpu_to_be32 (skb_frag_size (frag)); cur_p->app0 =0 ;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 30/60 net: ll_temac: Fix RX buffer descriptor handling on GFP_ATOMIC pressure
In reply to Greg Kroah-HartmanFrom: Esben Haabendal <[email protected]>
[ Upstream commit 770d9c67974c4c71af4beb786dc43162ad2a15ba ]
Failures caused by GFP_ATOMIC memory pressure have been observed, and due to the missing error handling, results in kernel crash such as
[1876998.350133] kernel BUG at mm/slub.c:3952! [1876998.350141] invalid opcode: 0000 [#1] PREEMPT SMP PTI [1876998.350147] CPU: 2 PID: 0 Comm: swapper/2 Not tainted 5.3.0-scnxt #1 [1876998.350150] Hardware name: N/A N/A/COMe-bIP2, BIOS CCR2R920 03/01/2017 [1876998.350160] RIP: 0010:kfree+0x1ca/0x220 [1876998.350164] Code: 85 db 74 49 48 8b 95 68 01 00 00 48 31 c2 48 89 10 e9 d7 fe ff ff 49 8b 04 24 a9 00 00 01 00 75 0b 49 8b 44 24 08 a8 01 75 02 <0f> 0b 49 8b 04 24 31 f6 a9 00 00 01 00 74 06 41 0f b6 74 24 5b [1876998.350172] RSP: 0018:ffffc900000f0df0 EFLAGS: 00010246 [1876998.350177] RAX: ffffea00027f0708 RBX: ffff888008d78000 RCX: 0000000000391372 [1876998.350181] RDX: 0000000000000000 RSI: ffffe8ffffd01400 RDI: ffff888008d78000 [1876998.350185] RBP: ffff8881185a5d00 R08: ffffc90000087dd8 R09: 000000000000280a [1876998.350189] R10: 0000000000000002 R11: 0000000000000000 R12: ffffea0000235e00 [1876998.350193] R13: ffff8881185438a0 R14: 0000000000000000 R15: ffff888118543870 [1876998.350198] FS: 0000000000000000(0000) GS:ffff88811f300000(0000) knlGS:0000000000000000 [1876998.350203] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 s#1 Part1 [1876998.350206] CR2: 00007f8dac7b09f0 CR3: 000000011e20a006 CR4: 00000000001606e0 [1876998.350210] Call Trace: [1876998.350215] <IRQ> [1876998.350224] ? __netif_receive_skb_core+0x70a/0x920 [1876998.350229] kfree_skb+0x32/0xb0 [1876998.350234] __netif_receive_skb_core+0x70a/0x920 [1876998.350240] __netif_receive_skb_one_core+0x36/0x80 [1876998.350245] process_backlog+0x8b/0x150 [1876998.350250] net_rx_action+0xf7/0x340 [1876998.350255] __do_softirq+0x10f/0x353 [1876998.350262] irq_exit+0xb2/0xc0 [1876998.350265] do_IRQ+0x77/0xd0 [1876998.350271] common_interrupt+0xf/0xf [1876998.350274] </IRQ>
In order to handle such failures more graceful, this change splits the receive loop into one for consuming the received buffers, and one for allocating new buffers.
When GFP_ATOMIC allocations fail, the receive will continue with the buffers that is still there, and with the expectation that the allocations will succeed in a later call to receive.
--- drivers/net/ethernet/xilinx/ll_temac.h | 1 + drivers/net/ethernet/xilinx/ll_temac_main.c | 112 ++++++++++++++------ 2 files changed, 82 insertions(+), 31 deletions(-)
drivers/net/ethernet/xilinx/ll_temac.h +1 -0
@@ -375,6 +375,7 @@ struct temac_local {int tx_bd_next;int tx_bd_tail;int rx_bd_ci; +int rx_bd_tail;/* DMA channel control setup */ u32 tx_chnl_ctrl;
drivers/net/ethernet/xilinx/ll_temac_main.c +81 -31
159 lines not on this page · raw message
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 31/60 net: ll_temac: Handle DMA halt condition caused by buffer underrun
In reply to Greg Kroah-HartmanFrom: Esben Haabendal <[email protected]>
[ Upstream commit 1d63b8d66d146deaaedbe16c80de105f685ea012 ]
The SDMA engine used by TEMAC halts operation when it has finished processing of the last buffer descriptor in the buffer ring. Unfortunately, no interrupt event is generated when this happens, so we need to setup another mechanism to make sure DMA operation is restarted when enough buffers have been added to the ring.
--- drivers/net/ethernet/xilinx/ll_temac.h | 3 ++ drivers/net/ethernet/xilinx/ll_temac_main.c | 58 +++++++++++++++++++-- 2 files changed, 56 insertions(+), 5 deletions(-)
drivers/net/ethernet/xilinx/ll_temac.h +3 -0
@@ -380,6 +380,9 @@ struct temac_local {/* DMA channel control setup */ u32 tx_chnl_ctrl;u32 rx_chnl_ctrl; +u8 coalesce_count_rx; + +struct delayed_work restart_work; };/* Wrappers for temac_ior()/temac_iow() function pointers above */
drivers/net/ethernet/xilinx/ll_temac_main.c +53 -5
121 lines not on this page · raw message
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 32/60 blk-mq: insert passthrough request into hctx->dispatch directly
In reply to Greg Kroah-HartmanFrom: Ming Lei <[email protected]>
[ Upstream commit 01e99aeca3979600302913cef3f89076786f32c8 ]
For some reason, device may be in one situation which can't handle FS request, so STS_RESOURCE is always returned and the FS request will be added to hctx->dispatch. However passthrough request may be required at that time for fixing the problem. If passthrough request is added to scheduler queue, there isn't any chance for blk-mq to dispatch it given we prioritize requests in hctx->dispatch. Then the FS IO request may never be completed, and IO hang is caused.
So passthrough request has to be added to hctx->dispatch directly for fixing the IO hang.
Fix this issue by inserting passthrough request into hctx->dispatch directly together withing adding FS request to the tail of hctx->dispatch in blk_mq_dispatch_rq_list(). Actually we add FS request to tail of hctx->dispatch at default, see blk_mq_request_bypass_insert().
Then it becomes consistent with original legacy IO request path, in which passthrough request is always added to q->queue_head.
--- block/blk-flush.c | 2 +- block/blk-mq-sched.c | 22 +++++++++++++++------- block/blk-mq.c | 18 +++++++++++------- block/blk-mq.h | 3 ++- 4 files changed, 29 insertions(+), 16 deletions(-)
block/blk-flush.c +1 -1
@@ -399,7 +399,7 @@ void blk_insert_flush(struct request *rq)*/ if ((policy &REQ_FSEQ_DATA ) && !(policy & (REQ_FSEQ_PREFLUSH |REQ_FSEQ_POSTFLUSH ))) { -blk_mq_request_bypass_insert (rq, false); +blk_mq_request_bypass_insert (rq, false, false);return ; }
block/blk-mq-sched.c +15 -7
@@ -361,13 +361,19 @@ static bool blk_mq_sched_bypass_insert(struct blk_mq_hw_ctx *hctx, bool has_sched, struct request *rq) { -/* dispatch flush rq directly */ -if (rq->rq_flags &RQF_FLUSH_SEQ ) { -spin_lock (&hctx->lock); -list_add (&rq->queuelist, &hctx->dispatch); -spin_unlock (&hctx->lock); +/* +* dispatch flush and passthrough rq directly +* +* passthrough request has to be added to hctx->dispatch directly. +* For some reason, device may be in one situation which can't +* handle FS request, so STS_RESOURCE is always returned and the +* FS request will be added to hctx->dispatch. However passthrough +* request may be required at that time for fixing the problem. If +* passthrough request is added to scheduler queue, there isn't any +* chance to dispatch it given we prioritize requests in hctx->dispatch. +*/ +if ((rq->rq_flags &RQF_FLUSH_SEQ ) ||blk_rq_is_passthrough (rq))return true; - }if (has_sched) rq->rq_flags |=RQF_SORTED ;
@@ -391,8 +397,10 @@ void blk_mq_sched_insert_request(struct request *rq, bool at_head,WARN_ON (e && (rq->tag !=-1 )); -if (blk_mq_sched_bypass_insert (hctx, !!e, rq)) +if (blk_mq_sched_bypass_insert (hctx, !!e, rq)) { +blk_mq_request_bypass_insert (rq, at_head, false); goto run; + }if (e && e->type->ops.insert_requests) {LIST_HEAD (list);
block/blk-mq.c +11 -7
@@ -761,7 +761,7 @@ static void blk_mq_requeue_work(struct work_struct *work)* merge. */ if (rq->rq_flags &RQF_DONTPREP ) -blk_mq_request_bypass_insert (rq, false); +blk_mq_request_bypass_insert (rq, false, false);else blk_mq_sched_insert_request (rq, true, false, false); }
@@ -1313,7 +1313,7 @@ bool blk_mq_dispatch_rq_list(struct request_queue *q, struct list_head *list, q->mq_ops->commit_rqs (hctx);spin_lock (&hctx->lock); -list_splice_init (list, &hctx->dispatch); +list_splice_tail_init (list, &hctx->dispatch);spin_unlock (&hctx->lock);/*
@@ -1668,12 +1668,16 @@ void __blk_mq_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq,* Should only be used carefully, when the caller knows we want to * bypass a potential IO scheduler on the target device. */ -void blk_mq_request_bypass_insert (struct request *rq,bool run_queue) +void blk_mq_request_bypass_insert (struct request *rq,bool at_head, +bool run_queue) {struct blk_mq_hw_ctx *hctx = rq->mq_hctx;spin_lock (&hctx->lock); -list_add_tail (&rq->queuelist, &hctx->dispatch); +if (at_head) +list_add (&rq->queuelist, &hctx->dispatch); +else +list_add_tail (&rq->queuelist, &hctx->dispatch);spin_unlock (&hctx->lock);if (run_queue)
@@ -1863,7 +1867,7 @@ static blk_status_t __blk_mq_try_issue_directly(struct blk_mq_hw_ctx *hctx,if (bypass_insert)return BLK_STS_RESOURCE ; -blk_mq_request_bypass_insert (rq, run_queue); +blk_mq_request_bypass_insert (rq, false, run_queue);return BLK_STS_OK ; }
@@ -1879,7 +1883,7 @@ static void blk_mq_try_issue_directly(struct blk_mq_hw_ctx *hctx, ret =__blk_mq_try_issue_directly (hctx, rq, cookie, false, true);if (ret ==BLK_STS_RESOURCE || ret ==BLK_STS_DEV_RESOURCE ) -blk_mq_request_bypass_insert (rq, true); +blk_mq_request_bypass_insert (rq, false, true);else if (ret !=BLK_STS_OK )blk_mq_end_request (rq, ret);
@@ -1913,7 +1917,7 @@ void blk_mq_try_issue_list_directly(struct blk_mq_hw_ctx *hctx,if (ret !=BLK_STS_OK ) {if (ret ==BLK_STS_RESOURCE || ret ==BLK_STS_DEV_RESOURCE ) { -blk_mq_request_bypass_insert (rq, +blk_mq_request_bypass_insert (rq, false,list_empty (list));break ; }
block/blk-mq.h +2 -1
@@ -66,7 +66,8 @@ int blk_mq_alloc_rqs(struct blk_mq_tag_set *set, struct blk_mq_tags *tags,*/ void __blk_mq_insert_request (struct blk_mq_hw_ctx *hctx,struct request *rq,bool at_head); -void blk_mq_request_bypass_insert (struct request *rq,bool run_queue); +void blk_mq_request_bypass_insert (struct request *rq,bool at_head, +bool run_queue);void blk_mq_insert_requests (struct blk_mq_hw_ctx *hctx,struct blk_mq_ctx *ctx,struct list_head *list);
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 33/60 drm/amdgpu: fix memory leak during TDR test(v2)
In reply to Greg Kroah-HartmanFrom: Monk Liu <[email protected]>
[ Upstream commit 4829f89855f1d3a3d8014e74cceab51b421503db ]
fix system memory leak
v2:
fix coding style
--- drivers/gpu/drm/amd/powerplay/smu_v11_0.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/powerplay/smu_v11_0.c +5 -1
@@ -988,8 +988,12 @@ static int smu_v11_0_init_max_sustainable_clocks(struct smu_context *smu)struct smu_11_0_max_sustainable_clocks *max_sustainable_clocks;int ret =0 ; - max_sustainable_clocks =kzalloc (sizeof (struct smu_11_0_max_sustainable_clocks ), +if (!smu->smu_table.max_sustainable_clocks) + max_sustainable_clocks =kzalloc (sizeof (struct smu_11_0_max_sustainable_clocks ),GFP_KERNEL ); +else + max_sustainable_clocks = smu->smu_table.max_sustainable_clocks; + smu->smu_table.max_sustainable_clocks = (void *)max_sustainable_clocks; max_sustainable_clocks->uclock = smu->smu_table.boot_values.uclk /100 ;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 34/60 kbuild: add dtbs_check to PHONY
In reply to Greg Kroah-HartmanFrom: Masahiro Yamada <[email protected]>
[ Upstream commit 964a596db8db8c77c9903dd05655696696e6b3ad ]
The dtbs_check should be a phony target, but currently it is not specified so.
'make dtbs_check' works even if a file named 'dtbs_check' exists because it depends on another phony target, scripts_dtc, but we should not rely on it.
Add dtbs_check to PHONY.
--- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Makefile +1 -1
@@ -1237,7 +1237,7 @@ ifneq ($(dtstree),) %.dtb: include/config/kernel.release scripts_dtc $(Q)$(MAKE) $(build)=$(dtstree) $(dtstree)/$@ -PHONY += dtbs dtbs_install dt_binding_check +PHONY += dtbs dtbs_install dtbs_check dt_binding_check dtbs dtbs_check: include/config/kernel.release scripts_dtc $(Q)$(MAKE) $(build)=$(dtstree)
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 35/60 kbuild: add dt_binding_check to PHONY in a correct place
In reply to Greg Kroah-HartmanFrom: Masahiro Yamada <[email protected]>
[ Upstream commit c473a8d03ea8e03ca9d649b0b6d72fbcf6212c05 ]
The dt_binding_check is added to PHONY, but it is invisible when $(dtstree) is empty. So, it is not specified as phony for ARCH=x86 etc.
Add it to PHONY outside the ifneq ... endif block.
--- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
Makefile +2 -1
@@ -1237,7 +1237,7 @@ ifneq ($(dtstree),) %.dtb: include/config/kernel.release scripts_dtc $(Q)$(MAKE) $(build)=$(dtstree) $(dtstree)/$@ -PHONY += dtbs dtbs_install dtbs_check dt_binding_check +PHONY += dtbs dtbs_install dtbs_check dtbs dtbs_check: include/config/kernel.release scripts_dtc $(Q)$(MAKE) $(build)=$(dtstree)
@@ -1257,6 +1257,7 @@ PHONY += scripts_dtc scripts_dtc: scripts_basic $(Q)$(MAKE) $(build)=scripts/dtc +PHONY += dt_binding_check dt_binding_check: scripts_dtc $(Q)$(MAKE) $(build)=Documentation/devicetree/bindings
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 36/60 signal: avoid double atomic counter increments for user accounting
In reply to Greg Kroah-HartmanFrom: Linus Torvalds <[email protected]>
[ Upstream commit fda31c50292a5062332fa0343c084bd9f46604d9 ]
When queueing a signal, we increment both the users count of pending signals (for RLIMIT_SIGPENDING tracking) and we increment the refcount of the user struct itself (because we keep a reference to the user in the signal structure in order to correctly account for it when freeing).
That turns out to be fairly expensive, because both of them are atomic updates, and particularly under extreme signal handling pressure on big machines, you can get a lot of cache contention on the user struct. That can then cause horrid cacheline ping-pong when you do these multiple accesses.
So change the reference counting to only pin the user for the _first_ pending signal, and to unpin it when the last pending signal is dequeued. That means that when a user sees a lot of concurrent signal queuing - which is the only situation when this matters - the only atomic access needed is generally the 'sigpending' count update.
This was noticed because of a particularly odd timing artifact on a dual-socket 96C/192T Cascade Lake platform: when you get into bad contention, on that machine for some reason seems to be much worse when the contention happens in the upper 32-byte half of the cacheline.
As a result, the kernel test robot will-it-scale 'signal1' benchmark had an odd performance regression simply due to random alignment of the 'struct user_struct' (and pointed to a completely unrelated and apparently nonsensical commit for the regression).
Avoiding the double increments (and decrements on the dequeueing side, of course) makes for much less contention and hugely improved performance on that will-it-scale microbenchmark.
Quoting Feng Tang:
"It makes a big difference, that the performance score is tripled! bump
from original 17000 to 54000. Also the gap between 5.0-rc6 and 5.0-rc6+Jiri's patch is reduced to around 2%"
[ The "2% gap" is the odd cacheline placement difference on that
platform: under the extreme contention case, the effect of which half of the cacheline was hot was 5%, so with the reduced contention the odd timing artifact is reduced too ]
It does help in the non-contended case too, but is not nearly as noticeable.
--- kernel/signal.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-)
kernel/signal.c +14 -9
@@ -413,27 +413,32 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t flags, int override_rlimi {struct sigqueue *q =NULL ;struct user_struct *user; +int sigpending;/* * Protect access to @t credentials. This can go away when all * callers hold rcu read lock. +* +* NOTE! A pending signal will hold on to the user refcount, +* and we get/put the refcount only when the sigpending count +* changes from/to zero. */ rcu_read_lock (); - user =get_uid (__task_cred (t)->user); -atomic_inc (&user->sigpending); + user =__task_cred (t)->user; + sigpending =atomic_inc_return (&user->sigpending); +if (sigpending ==1 ) +get_uid (user);rcu_read_unlock (); -if (override_rlimit || -atomic_read (&user->sigpending) <= -task_rlimit (t,RLIMIT_SIGPENDING )) { +if (override_rlimit ||likely (sigpending <=task_rlimit (t,RLIMIT_SIGPENDING ))) { q =kmem_cache_alloc (sigqueue_cachep, flags); }else {print_dropped_signal (sig); }if (unlikely (q ==NULL )) { -atomic_dec (&user->sigpending); -free_uid (user); +if (atomic_dec_and_test (&user->sigpending)) +free_uid (user); }else {INIT_LIST_HEAD (&q->list); q->flags =0 ;
@@ -447,8 +452,8 @@ static void __sigqueue_free(struct sigqueue *q) {if (q->flags &SIGQUEUE_PREALLOC )return ; -atomic_dec (&q->user->sigpending); -free_uid (q->user); +if (atomic_dec_and_test (&q->user->sigpending)) +free_uid (q->user);kmem_cache_free (sigqueue_cachep, q); }
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 37/60 slip: not call free_netdev before rtnl_unlock in slip_open
In reply to Greg Kroah-HartmanFrom: yangerkun <[email protected]>
[ Upstream commit f596c87005f7b1baeb7d62d9a9e25d68c3dfae10 ]
As the description before netdev_run_todo, we cannot call free_netdev before rtnl_unlock, fix it by reorder the code.
--- drivers/net/slip/slip.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/slip/slip.c +3 -0
@@ -863,7 +863,10 @@ static int slip_open(struct tty_struct *tty) tty->disc_data =NULL ;clear_bit (SLF_INUSE , &sl->flags);sl_free_netdev (sl->dev); +/* do not call free_netdev before rtnl_unlock */ +rtnl_unlock ();free_netdev (sl->dev); +return err; err_exit:rtnl_unlock ();
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 38/60 net: phy: mscc: fix firmware paths
In reply to Greg Kroah-HartmanFrom: Antoine Tenart <[email protected]>
[ Upstream commit c87a9d6fc6d555e4981f2ded77d9a8cce950743e ]
The firmware paths for the VSC8584 PHYs not not contain the leading 'microchip/' directory, as used in linux-firmware, resulting in an error when probing the driver. This patch fixes it.
--- drivers/net/phy/mscc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/phy/mscc.c +2 -2
@@ -302,11 +302,11 @@ enum rgmii_rx_clock_delay { BIT(VSC8531_FORCE_LED_OFF) | \ BIT(VSC8531_FORCE_LED_ON)) -#define MSCC_VSC8584_REVB_INT8051_FW "mscc_vsc8584_revb_int8051_fb48.bin" +#define MSCC_VSC8584_REVB_INT8051_FW "microchip/mscc_vsc8584_revb_int8051_fb48.bin"#define MSCC_VSC8584_REVB_INT8051_FW_START_ADDR 0xe800#define MSCC_VSC8584_REVB_INT8051_FW_CRC 0xfb48 -#define MSCC_VSC8574_REVB_INT8051_FW "mscc_vsc8574_revb_int8051_29e8.bin" +#define MSCC_VSC8574_REVB_INT8051_FW "microchip/mscc_vsc8574_revb_int8051_29e8.bin"#define MSCC_VSC8574_REVB_INT8051_FW_START_ADDR 0x4000#define MSCC_VSC8574_REVB_INT8051_FW_CRC 0x29e8
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 39/60 hinic: fix a irq affinity bug
In reply to Greg Kroah-HartmanFrom: Luo bin <[email protected]>
[ Upstream commit 0bff777bd0cba73ad4cd0145696ad284d7e6a99f ]
can not use a local variable as an input parameter of irq_set_affinity_hint
--- drivers/net/ethernet/huawei/hinic/hinic_hw_qp.h | 1 + drivers/net/ethernet/huawei/hinic/hinic_rx.c | 5 ++--- 2 files changed, 3 insertions(+), 3 deletions(-)
drivers/net/ethernet/huawei/hinic/hinic_hw_qp.h +1 -0
@@ -94,6 +94,7 @@ struct hinic_rq {struct hinic_wq *wq; +struct cpumask affinity_mask;u32 irq;u16 msix_entry;
drivers/net/ethernet/huawei/hinic/hinic_rx.c +2 -3
@@ -475,7 +475,6 @@ static int rx_request_irq(struct hinic_rxq *rxq)struct hinic_hwdev *hwdev = nic_dev->hwdev;struct hinic_rq *rq = rxq->rq;struct hinic_qp *qp; -struct cpumask mask;int err;rx_add_napi (rxq);
@@ -492,8 +491,8 @@ static int rx_request_irq(struct hinic_rxq *rxq) } qp = container_of(rq, struct hinic_qp, rq); -cpumask_set_cpu (qp->q_id %num_online_cpus (), &mask); -return irq_set_affinity_hint (rq->irq, &mask); +cpumask_set_cpu (qp->q_id %num_online_cpus (), &rq->affinity_mask); +return irq_set_affinity_hint (rq->irq, &rq->affinity_mask); }static void rx_free_irq (struct hinic_rxq *rxq)
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 40/60 hinic: fix a bug of setting hw_ioctxt
In reply to Greg Kroah-HartmanFrom: Luo bin <[email protected]>
[ Upstream commit d2ed69ce9ed3477e2a9527e6b89fe4689d99510e ]
a reserved field is used to signify prime physical function index in the latest firmware version, so we must assign a value to it correctly
--- drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c | 1 + drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h | 2 +- drivers/net/ethernet/huawei/hinic/hinic_hw_if.h | 1 + 3 files changed, 3 insertions(+), 1 deletion(-)
drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c +1 -0
@@ -297,6 +297,7 @@ static int set_hw_ioctxt(struct hinic_hwdev *hwdev, unsigned int rq_depth, } hw_ioctxt.func_idx =HINIC_HWIF_FUNC_IDX (hwif); + hw_ioctxt.ppf_idx =HINIC_HWIF_PPF_IDX (hwif); hw_ioctxt.set_cmdq_depth =HW_IOCTXT_SET_CMDQ_DEPTH_DEFAULT ; hw_ioctxt.cmdq_depth =0 ;
drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h +1 -1
@@ -151,8 +151,8 @@ struct hinic_cmd_hw_ioctxt {u8 lro_en;u8 rsvd3; +u8 ppf_idx;u8 rsvd4; -u8 rsvd5;u16 rq_depth;u16 rx_buf_sz_idx;
drivers/net/ethernet/huawei/hinic/hinic_hw_if.h +1 -0
@@ -137,6 +137,7 @@#define HINIC_HWIF_FUNC_IDX (hwif) ((hwif)->attr.func_idx)#define HINIC_HWIF_PCI_INTF (hwif) ((hwif)->attr.pci_intf_idx)#define HINIC_HWIF_PF_IDX (hwif) ((hwif)->attr.pf_idx) +#define HINIC_HWIF_PPF_IDX (hwif) ((hwif)->attr.ppf_idx)#define HINIC_FUNC_TYPE (hwif) ((hwif)->attr.func_type)#define HINIC_IS_PF (hwif) (HINIC_FUNC_TYPE(hwif) == HINIC_PF)
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 41/60 hinic: fix a bug of rss configuration
In reply to Greg Kroah-HartmanFrom: Luo bin <[email protected]>
[ Upstream commit 386d4716fd91869e07c731657f2cde5a33086516 ]
should use real receive queue number to configure hw rss indirect table rather than maximal queue number
--- drivers/net/ethernet/huawei/hinic/hinic_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/ethernet/huawei/hinic/hinic_main.c +2 -1
@@ -356,7 +356,8 @@ static void hinic_enable_rss(struct hinic_dev *nic_dev)if (!num_cpus) num_cpus =num_online_cpus (); - nic_dev->num_qps =min_t (u16, nic_dev->max_qps, num_cpus); + nic_dev->num_qps =hinic_hwdev_num_qps (hwdev); + nic_dev->num_qps =min_t (u16, nic_dev->num_qps, num_cpus); nic_dev->rss_limit = nic_dev->num_qps; nic_dev->num_rss = nic_dev->num_qps;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 42/60 net: rmnet: fix NULL pointer dereference in rmnet_newlink()
In reply to Greg Kroah-HartmanFrom: Taehee Yoo <[email protected]>
[ Upstream commit 93b5cbfa9636d385126f211dca9efa7e3f683202 ]
rmnet registers IFLA_LINK interface as a lower interface. But, IFLA_LINK could be NULL.
In the current code, rmnet doesn't check IFLA_LINK. So, panic would occur.
Test commands:
modprobe rmnet
ip link add rmnet0 type rmnet mux_id 1
Splat looks like:
[ 36.826109][ T1115] general protection fault, probably for non-canonical address 0xdffffc0000000000I [ 36.838817][ T1115] KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007] [ 36.839908][ T1115] CPU: 1 PID: 1115 Comm: ip Not tainted 5.6.0-rc1+ #447 [ 36.840569][ T1115] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006 [ 36.841408][ T1115] RIP: 0010:rmnet_newlink+0x54/0x510 [rmnet] [ 36.841986][ T1115] Code: 83 ec 18 48 c1 e9 03 80 3c 01 00 0f 85 d4 03 00 00 48 8b 6a 28 48 b8 00 00 00 00 00 c [ 36.843923][ T1115] RSP: 0018:ffff8880b7e0f1c0 EFLAGS: 00010247 [ 36.844756][ T1115] RAX: dffffc0000000000 RBX: ffff8880d14cca00 RCX: 1ffff11016fc1e99 [ 36.845859][ T1115] RDX: 0000000000000000 RSI: ffff8880c3d04000 RDI: 0000000000000004 [ 36.846961][ T1115] RBP: 0000000000000000 R08: ffff8880b7e0f8b0 R09: ffff8880b6ac2d90 [ 36.848020][ T1115] R10: ffffffffc0589a40 R11: ffffed1016d585b7 R12: ffffffff88ceaf80 [ 36.848788][ T1115] R13: ffff8880c3d04000 R14: ffff8880b7e0f8b0 R15: ffff8880c3d04000 [ 36.849546][ T1115] FS: 00007f50ab3360c0(0000) GS:ffff8880da000000(0000) knlGS:0000000000000000 [ 36.851784][ T1115] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 36.852422][ T1115] CR2: 000055871afe5ab0 CR3: 00000000ae246001 CR4: 00000000000606e0 [ 36.853181][ T1115] Call Trace: [ 36.853514][ T1115] __rtnl_newlink+0xbdb/0x1270 [ 36.853967][ T1115] ? lock_downgrade+0x6e0/0x6e0 [ 36.854420][ T1115] ? rtnl_link_unregister+0x220/0x220 [ 36.854936][ T1115] ? lock_acquire+0x164/0x3b0 [ 36.855376][ T1115] ? is_bpf_image_address+0xff/0x1d0 [ 36.855884][ T1115] ? rtnl_newlink+0x4c/0x90 [ 36.856304][ T1115] ? kernel_text_address+0x111/0x140 [ 36.856857][ T1115] ? __kernel_text_address+0xe/0x30 [ 36.857440][ T1115] ? unwind_get_return_address+0x5f/0xa0 [ 36.858063][ T1115] ? create_prof_cpu_mask+0x20/0x20 [ 36.858644][ T1115] ? arch_stack_walk+0x83/0xb0 [ 36.859171][ T1115] ? stack_trace_save+0x82/0xb0 [ 36.859710][ T1115] ? stack_trace_consume_entry+0x160/0x160 [ 36.860357][ T1115] ? deactivate_slab.isra.78+0x2c5/0x800 [ 36.860928][ T1115] ? kasan_unpoison_shadow+0x30/0x40 [ 36.861520][ T1115] ? kmem_cache_alloc_trace+0x135/0x350 [ 36.862125][ T1115] ? rtnl_newlink+0x4c/0x90 [ 36.864073][ T1115] rtnl_newlink+0x65/0x90
[ ... ]
--- drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c +5 -0
@@ -135,6 +135,11 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev,int err =0 ;u16 mux_id; +if (!tb[IFLA_LINK ]) { +NL_SET_ERR_MSG_MOD (extack,"link not specified" ); +return -EINVAL ; + } + real_dev =__dev_get_by_index (src_net,nla_get_u32 (tb[IFLA_LINK ]));if (!real_dev || !dev)return -ENODEV ;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 43/60 net: rmnet: fix NULL pointer dereference in rmnet_changelink()
In reply to Greg Kroah-HartmanFrom: Taehee Yoo <[email protected]>
[ Upstream commit 1eb1f43a6e37282348a41e3d68f5e9a6a4359212 ]
In the rmnet_changelink(), it uses IFLA_LINK without checking NULL pointer.
tb[IFLA_LINK] could be NULL pointer.
So, NULL-ptr-deref could occur.
rmnet already has a lower interface (real_dev).
So, after this patch, rmnet_changelink() does not use IFLA_LINK anymore.
Test commands:
modprobe rmnet
ip link add dummy0 type dummy
ip link add rmnet0 link dummy0 type rmnet mux_id 1 ip link set rmnet0 type rmnet mux_id 2
Splat looks like:
[ 90.578726][ T1131] general protection fault, probably for non-canonical address 0xdffffc0000000000I [ 90.581121][ T1131] KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007] [ 90.582380][ T1131] CPU: 2 PID: 1131 Comm: ip Not tainted 5.6.0-rc1+ #447 [ 90.584285][ T1131] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006 [ 90.587506][ T1131] RIP: 0010:rmnet_changelink+0x5a/0x8a0 [rmnet] [ 90.588546][ T1131] Code: 83 ec 20 48 c1 ea 03 80 3c 02 00 0f 85 6f 07 00 00 48 8b 5e 28 48 b8 00 00 00 00 00 0 [ 90.591447][ T1131] RSP: 0018:ffff8880ce78f1b8 EFLAGS: 00010247 [ 90.592329][ T1131] RAX: dffffc0000000000 RBX: 0000000000000000 RCX: ffff8880ce78f8b0 [ 90.593253][ T1131] RDX: 0000000000000000 RSI: ffff8880ce78f4a0 RDI: 0000000000000004 [ 90.594058][ T1131] RBP: ffff8880cf543e00 R08: 0000000000000002 R09: 0000000000000002 [ 90.594859][ T1131] R10: ffffffffc0586a40 R11: 0000000000000000 R12: ffff8880ca47c000 [ 90.595690][ T1131] R13: ffff8880ca47c000 R14: ffff8880cf545000 R15: 0000000000000000 [ 90.596553][ T1131] FS: 00007f21f6c7e0c0(0000) GS:ffff8880da400000(0000) knlGS:0000000000000000 [ 90.597504][ T1131] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 90.599418][ T1131] CR2: 0000556e413db458 CR3: 00000000c917a002 CR4: 00000000000606e0 [ 90.600289][ T1131] Call Trace: [ 90.600631][ T1131] __rtnl_newlink+0x922/0x1270 [ 90.601194][ T1131] ? lock_downgrade+0x6e0/0x6e0 [ 90.601724][ T1131] ? rtnl_link_unregister+0x220/0x220 [ 90.602309][ T1131] ? lock_acquire+0x164/0x3b0 [ 90.602784][ T1131] ? is_bpf_image_address+0xff/0x1d0 [ 90.603331][ T1131] ? rtnl_newlink+0x4c/0x90 [ 90.603810][ T1131] ? kernel_text_address+0x111/0x140 [ 90.604419][ T1131] ? __kernel_text_address+0xe/0x30 [ 90.604981][ T1131] ? unwind_get_return_address+0x5f/0xa0 [ 90.605616][ T1131] ? create_prof_cpu_mask+0x20/0x20 [ 90.606304][ T1131] ? arch_stack_walk+0x83/0xb0 [ 90.606985][ T1131] ? stack_trace_save+0x82/0xb0 [ 90.607656][ T1131] ? stack_trace_consume_entry+0x160/0x160 [ 90.608503][ T1131] ? deactivate_slab.isra.78+0x2c5/0x800 [ 90.609336][ T1131] ? kasan_unpoison_shadow+0x30/0x40 [ 90.610096][ T1131] ? kmem_cache_alloc_trace+0x135/0x350 [ 90.610889][ T1131] ? rtnl_newlink+0x4c/0x90 [ 90.611512][ T1131] rtnl_newlink+0x65/0x90
[ ... ]
--- drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c +2 -4
@@ -300,10 +300,8 @@ static int rmnet_changelink(struct net_device *dev, struct nlattr *tb[],if (!dev)return -ENODEV ; - real_dev =__dev_get_by_index (dev_net (dev), -nla_get_u32 (tb[IFLA_LINK ])); - -if (!real_dev || !rmnet_is_real_dev_registered (real_dev)) + real_dev = priv->real_dev; +if (!rmnet_is_real_dev_registered (real_dev))return -ENODEV ; port =rmnet_get_port_rtnl (real_dev);
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 44/60 net: rmnet: fix suspicious RCU usage
In reply to Greg Kroah-HartmanFrom: Taehee Yoo <[email protected]>
[ Upstream commit 102210f7664442d8c0ce332c006ea90626df745b ]
rmnet_get_port() internally calls rcu_dereference_rtnl(), which checks RTNL.
But rmnet_get_port() could be called by packet path. The packet path is not protected by RTNL.
So, the suspicious RCU usage problem occurs.
Test commands:
modprobe rmnet
ip netns add nst
ip link add veth0 type veth peer name veth1
ip link set veth1 netns nst
ip link add rmnet0 link veth0 type rmnet mux_id 1
ip netns exec nst ip link add rmnet1 link veth1 type rmnet mux_id 1 ip netns exec nst ip link set veth1 up
ip netns exec nst ip link set rmnet1 up
ip netns exec nst ip a a 192.168.100.2/24 dev rmnet1
ip link set veth0 up
ip link set rmnet0 up
ip a a 192.168.100.1/24 dev rmnet0
ping 192.168.100.2
Splat looks like:
[ 146.630958][ T1174] WARNING: suspicious RCU usage
[ 146.631735][ T1174] 5.6.0-rc1+ #447 Not tainted
[ 146.632387][ T1174] -----------------------------
[ 146.633151][ T1174] drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c:386 suspicious rcu_dereference_check() !
[ 146.634742][ T1174]
[ 146.634742][ T1174] other info that might help us debug this:
[ 146.634742][ T1174]
[ 146.645992][ T1174]
[ 146.645992][ T1174] rcu_scheduler_active = 2, debug_locks = 1
[ 146.646937][ T1174] 5 locks held by ping/1174:
[ 146.647609][ T1174] #0: ffff8880c31dea70 (sk_lock-AF_INET){+.+.}, at: raw_sendmsg+0xab8/0x2980
[ 146.662463][ T1174] #1: ffffffff93925660 (rcu_read_lock_bh){....}, at: ip_finish_output2+0x243/0x2150
[ 146.671696][ T1174] #2: ffffffff93925660 (rcu_read_lock_bh){....}, at: __dev_queue_xmit+0x213/0x2940
[ 146.673064][ T1174] #3: ffff8880c19ecd58 (&dev->qdisc_running_key#7){+...}, at: ip_finish_output2+0x714/0x2150
[ 146.690358][ T1174] #4: ffff8880c5796898 (&dev->qdisc_xmit_lock_key#3){+.-.}, at: sch_direct_xmit+0x1e2/0x1020
[ 146.699875][ T1174]
[ 146.699875][ T1174] stack backtrace:
[ 146.701091][ T1174] CPU: 0 PID: 1174 Comm: ping Not tainted 5.6.0-rc1+ #447
[ 146.705215][ T1174] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
[ 146.706565][ T1174] Call Trace:
[ 146.707102][ T1174] dump_stack+0x96/0xdb
[ 146.708007][ T1174] rmnet_get_port.part.9+0x76/0x80 [rmnet]
[ 146.709233][ T1174] rmnet_egress_handler+0x107/0x420 [rmnet]
[ 146.710492][ T1174] ? sch_direct_xmit+0x1e2/0x1020
[ 146.716193][ T1174] rmnet_vnd_start_xmit+0x3d/0xa0 [rmnet]
[ 146.717012][ T1174] dev_hard_start_xmit+0x160/0x740
[ 146.717854][ T1174] sch_direct_xmit+0x265/0x1020
[ 146.718577][ T1174] ? register_lock_class+0x14d0/0x14d0
[ 146.719429][ T1174] ? dev_watchdog+0xac0/0xac0
[ 146.723738][ T1174] ? __dev_queue_xmit+0x15fd/0x2940
[ 146.724469][ T1174] ? lock_acquire+0x164/0x3b0
[ 146.725172][ T1174] __dev_queue_xmit+0x20c7/0x2940[ ... ]
--- drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c | 13 ++++++------- drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h | 2 +- .../net/ethernet/qualcomm/rmnet/rmnet_handlers.c | 4 ++-- 3 files changed, 9 insertions(+), 10 deletions(-)
drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c +6 -7
@@ -382,11 +382,10 @@ struct rtnl_link_ops rmnet_link_ops __read_mostly = { .fill_info = rmnet_fill_info, }; -/* Needs either rcu_read_lock() or rtnl lock */ -struct rmnet_port *rmnet_get_port (struct net_device *real_dev) +struct rmnet_port *rmnet_get_port_rcu (struct net_device *real_dev) {if (rmnet_is_real_dev_registered (real_dev)) -return rcu_dereference_rtnl (real_dev->rx_handler_data); +return rcu_dereference_bh (real_dev->rx_handler_data);else return NULL ; }
@@ -412,7 +411,7 @@ int rmnet_add_bridge(struct net_device *rmnet_dev,struct rmnet_port *port, *slave_port;int err; - port =rmnet_get_port (real_dev); + port =rmnet_get_port_rtnl (real_dev);/* If there is more than one rmnet dev attached, its probably being * used for muxing. Skip the briding in that case
@@ -427,7 +426,7 @@ int rmnet_add_bridge(struct net_device *rmnet_dev,if (err)return -EBUSY ; - slave_port =rmnet_get_port (slave_dev); + slave_port =rmnet_get_port_rtnl (slave_dev); slave_port->rmnet_mode =RMNET_EPMODE_BRIDGE ; slave_port->bridge_ep = real_dev;
@@ -445,11 +444,11 @@ int rmnet_del_bridge(struct net_device *rmnet_dev,struct net_device *real_dev = priv->real_dev;struct rmnet_port *port, *slave_port; - port =rmnet_get_port (real_dev); + port =rmnet_get_port_rtnl (real_dev); port->rmnet_mode =RMNET_EPMODE_VND ; port->bridge_ep =NULL ; - slave_port =rmnet_get_port (slave_dev); + slave_port =rmnet_get_port_rtnl (slave_dev);rmnet_unregister_real_device (slave_dev, slave_port);netdev_dbg (slave_dev,"removed from rmnet as slave\n" );
drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h +1 -1
@@ -65,7 +65,7 @@ struct rmnet_priv {struct rmnet_priv_stats stats; }; -struct rmnet_port *rmnet_get_port (struct net_device *real_dev); +struct rmnet_port *rmnet_get_port_rcu (struct net_device *real_dev);struct rmnet_endpoint *rmnet_get_endpoint (struct rmnet_port *port,u8 mux_id); int rmnet_add_bridge(struct net_device *rmnet_dev, struct net_device *slave_dev,
drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c +2 -2
@@ -184,7 +184,7 @@ rx_handler_result_t rmnet_rx_handler(struct sk_buff **pskb)return RX_HANDLER_PASS ; dev = skb->dev; - port =rmnet_get_port (dev); + port =rmnet_get_port_rcu (dev);switch (port->rmnet_mode) {case RMNET_EPMODE_VND :
@@ -217,7 +217,7 @@ void rmnet_egress_handler(struct sk_buff *skb) skb->dev = priv->real_dev; mux_id = priv->mux_id; - port =rmnet_get_port (skb->dev); + port =rmnet_get_port_rcu (skb->dev);if (!port) goto drop;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 45/60 net: rmnet: remove rcu_read_lock in rmnet_force_unassociate_device()
In reply to Greg Kroah-HartmanFrom: Taehee Yoo <[email protected]>
[ Upstream commit c026d970102e9af9958edefb4a015702c6aab636 ]
The notifier_call() of the slave interface removes rmnet interface with unregister_netdevice_queue().
But, before calling unregister_netdevice_queue(), it acquires rcu readlock.
In the RCU critical section, sleeping isn't be allowed.
But, unregister_netdevice_queue() internally calls synchronize_net(), which would sleep.
So, suspicious RCU usage warning occurs.
Test commands:
modprobe rmnet
ip link add dummy0 type dummy
ip link add dummy1 type dummy
ip link add rmnet0 link dummy0 type rmnet mux_id 1 ip link set dummy1 master rmnet0
ip link del dummy0
Splat looks like:
[ 79.639245][ T1195] =============================
[ 79.640134][ T1195] WARNING: suspicious RCU usage
[ 79.640852][ T1195] 5.6.0-rc1+ #447 Not tainted
[ 79.641657][ T1195] -----------------------------
[ 79.642472][ T1195] ./include/linux/rcupdate.h:273 Illegal context switch in RCU read-side critical section!
[ 79.644043][ T1195]
[ 79.644043][ T1195] other info that might help us debug this:
[ 79.644043][ T1195]
[ 79.645682][ T1195]
[ 79.645682][ T1195] rcu_scheduler_active = 2, debug_locks = 1
[ 79.646980][ T1195] 2 locks held by ip/1195:
[ 79.647629][ T1195] #0: ffffffffa3cf64f0 (rtnl_mutex){+.+.}, at: rtnetlink_rcv_msg+0x457/0x890
[ 79.649312][ T1195] #1: ffffffffa39256c0 (rcu_read_lock){....}, at: rmnet_config_notify_cb+0xf0/0x590 [rmnet]
[ 79.651717][ T1195]
[ 79.651717][ T1195] stack backtrace:
[ 79.652650][ T1195] CPU: 3 PID: 1195 Comm: ip Not tainted 5.6.0-rc1+ #447
[ 79.653702][ T1195] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
[ 79.655037][ T1195] Call Trace:
[ 79.655560][ T1195] dump_stack+0x96/0xdb
[ 79.656252][ T1195] ___might_sleep+0x345/0x440
[ 79.656994][ T1195] synchronize_net+0x18/0x30
[ 79.661132][ T1195] netdev_rx_handler_unregister+0x40/0xb0
[ 79.666266][ T1195] rmnet_unregister_real_device+0x42/0xb0 [rmnet]
[ 79.667211][ T1195] rmnet_config_notify_cb+0x1f7/0x590 [rmnet]
[ 79.668121][ T1195] ? rmnet_unregister_bridge.isra.6+0xf0/0xf0 [rmnet]
[ 79.669166][ T1195] ? rmnet_unregister_bridge.isra.6+0xf0/0xf0 [rmnet]
[ 79.670286][ T1195] ? __module_text_address+0x13/0x140
[ 79.671139][ T1195] notifier_call_chain+0x90/0x160
[ 79.671973][ T1195] rollback_registered_many+0x660/0xcf0
[ 79.672893][ T1195] ? netif_set_real_num_tx_queues+0x780/0x780
[ 79.675091][ T1195] ? __lock_acquire+0xdfe/0x3de0
[ 79.675825][ T1195] ? memset+0x1f/0x40
[ 79.676367][ T1195] ? __nla_validate_parse+0x98/0x1ab0
[ 79.677290][ T1195] unregister_netdevice_many.part.133+0x13/0x1b0
[ 79.678163][ T1195] rtnl_delete_link+0xbc/0x100[ ... ]
--- drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c | 2 -- 1 file changed, 2 deletions(-)
drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c +0 -2
@@ -230,7 +230,6 @@ static void rmnet_force_unassociate_device(struct net_device *dev) port =rmnet_get_port_rtnl (dev); -rcu_read_lock ();rmnet_unregister_bridge (dev, port);hash_for_each_safe (port->muxed_ep, bkt_ep, tmp_ep, ep, hlnode) {
@@ -241,7 +240,6 @@ static void rmnet_force_unassociate_device(struct net_device *dev)kfree (ep); } -rcu_read_unlock ();unregister_netdevice_many (&list);rmnet_unregister_real_device (real_dev, port);
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 46/60 net: rmnet: do not allow to change mux id if mux id is duplicated
In reply to Greg Kroah-HartmanFrom: Taehee Yoo <[email protected]>
[ Upstream commit 1dc49e9d164cd7e11c81279c83db84a147e14740 ]
Basically, duplicate mux id isn't be allowed.
So, the creation of rmnet will be failed if there is duplicate mux id is existing.
But, changelink routine doesn't check duplicate mux id.
Test commands:
modprobe rmnet
ip link add dummy0 type dummy
ip link add rmnet0 link dummy0 type rmnet mux_id 1 ip link add rmnet1 link dummy0 type rmnet mux_id 2 ip link set rmnet1 type rmnet mux_id 1
--- drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c +4 -0
@@ -306,6 +306,10 @@ static int rmnet_changelink(struct net_device *dev, struct nlattr *tb[],if (data[IFLA_RMNET_MUX_ID ]) { mux_id =nla_get_u16 (data[IFLA_RMNET_MUX_ID ]); +if (rmnet_get_endpoint (port, mux_id)) { +NL_SET_ERR_MSG_MOD (extack,"MUX ID already exists" ); +return -EINVAL ; + } ep =rmnet_get_endpoint (port, priv->mux_id);if (!ep)return -ENODEV ;
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 47/60 net: rmnet: use upper/lower device infrastructure
In reply to Greg Kroah-HartmanFrom: Taehee Yoo <[email protected]>
[ Upstream commit 037f9cdf72fb8a7ff9ec2b5dd05336ec1492bdf1 ]
netdev_upper_dev_link() is useful to manage lower/upper interfaces. And this function internally validates looping, maximum depth. All or most virtual interfaces that could have a real interface (e.g. macsec, macvlan, ipvlan etc.) use lower/upper infrastructure.
Test commands:
modprobe rmnet
ip link add dummy0 type dummy
ip link add rmnet1 link dummy0 type rmnet mux_id 1 for i in {2..100}
do
let A=$i-1
ip link add rmnet$i link rmnet$A type rmnet mux_id $i
done
ip link del dummy0
The purpose of the test commands is to make stack overflow.
Splat looks like:
[ 52.411438][ T1395] BUG: KASAN: slab-out-of-bounds in find_busiest_group+0x27e/0x2c00 [ 52.413218][ T1395] Write of size 64 at addr ffff8880c774bde0 by task ip/1395 [ 52.414841][ T1395] [ 52.430720][ T1395] CPU: 1 PID: 1395 Comm: ip Not tainted 5.6.0-rc1+ #447 [ 52.496511][ T1395] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006 [ 52.513597][ T1395] Call Trace: [ 52.546516][ T1395] [ 52.558773][ T1395] Allocated by task 3171537984: [ 52.588290][ T1395] BUG: unable to handle page fault for address: ffffffffb999e260 [ 52.589311][ T1395] #PF: supervisor read access in kernel mode [ 52.590529][ T1395] #PF: error_code(0x0000) - not-present page [ 52.591374][ T1395] PGD d6818067 P4D d6818067 PUD d6819063 PMD 0 [ 52.592288][ T1395] Thread overran stack, or stack corrupted [ 52.604980][ T1395] Oops: 0000 [#1] SMP DEBUG_PAGEALLOC KASAN PTI [ 52.605856][ T1395] CPU: 1 PID: 1395 Comm: ip Not tainted 5.6.0-rc1+ #447 [ 52.611764][ T1395] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006 [ 52.621520][ T1395] RIP: 0010:stack_depot_fetch+0x10/0x30 [ 52.622296][ T1395] Code: ff e9 f9 fe ff ff 48 89 df e8 9c 1d 91 ff e9 ca fe ff ff cc cc cc cc cc cc cc 89 f8 0 [ 52.627887][ T1395] RSP: 0018:ffff8880c774bb60 EFLAGS: 00010006 [ 52.628735][ T1395] RAX: 00000000001f8880 RBX: ffff8880c774d140 RCX: 0000000000000000 [ 52.631773][ T1395] RDX: 000000000000001d RSI: ffff8880c774bb68 RDI: 0000000000003ff0 [ 52.649584][ T1395] RBP: ffffea00031dd200 R08: ffffed101b43e403 R09: ffffed101b43e403 [ 52.674857][ T1395] R10: 0000000000000001 R11: ffffed101b43e402 R12: ffff8880d900e5c0 [ 52.678257][ T1395] R13: ffff8880c774c000 R14: 0000000000000000 R15: dffffc0000000000 [ 52.694541][ T1395] FS: 00007fe867f6e0c0(0000) GS:ffff8880da000000(0000) knlGS:0000000000000000 [ 52.764039][ T1395] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 52.815008][ T1395] CR2: ffffffffb999e260 CR3: 00000000c26aa005 CR4: 00000000000606e0 [ 52.862312][ T1395] Call Trace: [ 52.887133][ T1395] Modules linked in: dummy rmnet veth openvswitch nsh nf_conncount nf_nat nf_conntrack nf_dex [ 52.936749][ T1395] CR2: ffffffffb999e260 [ 52.965695][ T1395] ---[ end trace 7e32ca99482dbb31 ]--- [ 52.966556][ T1395] RIP: 0010:stack_depot_fetch+0x10/0x30 [ 52.971083][ T1395] Code: ff e9 f9 fe ff ff 48 89 df e8 9c 1d 91 ff e9 ca fe ff ff cc cc cc cc cc cc cc 89 f8 0 [ 53.003650][ T1395] RSP: 0018:ffff8880c774bb60 EFLAGS: 00010006 [ 53.043183][ T1395] RAX: 00000000001f8880 RBX: ffff8880c774d140 RCX: 0000000000000000 [ 53.076480][ T1395] RDX: 000000000000001d RSI: ffff8880c774bb68 RDI: 0000000000003ff0 [ 53.093858][ T1395] RBP: ffffea00031dd200 R08: ffffed101b43e403 R09: ffffed101b43e403 [ 53.112795][ T1395] R10: 0000000000000001 R11: ffffed101b43e402 R12: ffff8880d900e5c0 [ 53.139837][ T1395] R13: ffff8880c774c000 R14: 0000000000000000 R15: dffffc0000000000 [ 53.141500][ T1395] FS: 00007fe867f6e0c0(0000) GS:ffff8880da000000(0000) knlGS:0000000000000000 [ 53.143343][ T1395] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 53.152007][ T1395] CR2: ffffffffb999e260 CR3: 00000000c26aa005 CR4: 00000000000606e0 [ 53.156459][ T1395] Kernel panic - not syncing: Fatal exception [ 54.213570][ T1395] Shutting down cpus with NMI [ 54.354112][ T1395] Kernel Offset: 0x33000000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0x) [ 54.355687][ T1395] Rebooting in 5 seconds..
--- .../ethernet/qualcomm/rmnet/rmnet_config.c | 35 +++++++++---------- 1 file changed, 16 insertions(+), 19 deletions(-)
drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c +16 -19
@@ -61,9 +61,6 @@ static int rmnet_unregister_real_device(struct net_device *real_dev,kfree (port); -/* release reference on real_dev */ -dev_put (real_dev); -netdev_dbg (real_dev,"Removed from rmnet\n" );return 0 ; }
@@ -89,9 +86,6 @@ static int rmnet_register_real_device(struct net_device *real_dev)return -EBUSY ; } -/* hold on to real dev for MAP data */ -dev_hold (real_dev); -for (entry =0 ; entry <RMNET_MAX_LOGICAL_EP ; entry++)INIT_HLIST_HEAD (&port->muxed_ep[entry]);
@@ -162,6 +156,10 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev,if (err) goto err1; + err =netdev_upper_dev_link (real_dev, dev, extack); +if (err <0 ) + goto err2; + port->rmnet_mode = mode;hlist_add_head_rcu (&ep->hlnode, &port->muxed_ep[mux_id]);
@@ -178,6 +176,8 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev,return 0 ; +err2: +unregister_netdevice (dev); err1:rmnet_unregister_real_device (real_dev, port); err0:
@@ -209,33 +209,30 @@ static void rmnet_dellink(struct net_device *dev, struct list_head *head)rmnet_vnd_dellink (mux_id, port, ep);kfree (ep); } +netdev_upper_dev_unlink (real_dev, dev);rmnet_unregister_real_device (real_dev, port);unregister_netdevice_queue (dev, head); } -static void rmnet_force_unassociate_device (struct net_device *dev) +static void rmnet_force_unassociate_device (struct net_device *real_dev) { -struct net_device *real_dev = dev;struct hlist_node *tmp_ep;struct rmnet_endpoint *ep;struct rmnet_port *port;unsigned long bkt_ep;LIST_HEAD (list); -if (!rmnet_is_real_dev_registered (real_dev)) -return ; -ASSERT_RTNL (); - port =rmnet_get_port_rtnl (dev); + port =rmnet_get_port_rtnl (real_dev); -rmnet_unregister_bridge (dev, port); +rmnet_unregister_bridge (real_dev, port);hash_for_each_safe (port->muxed_ep, bkt_ep, tmp_ep, ep, hlnode) { +netdev_upper_dev_unlink (real_dev, ep->egress_dev);unregister_netdevice_queue (ep->egress_dev, &list);rmnet_vnd_dellink (ep->mux_id, port, ep); -hlist_del_init_rcu (&ep->hlnode);kfree (ep); }
@@ -248,15 +245,15 @@ static void rmnet_force_unassociate_device(struct net_device *dev)static int rmnet_config_notify_cb (struct notifier_block *nb,unsigned long event,void *data) { -struct net_device *dev =netdev_notifier_info_to_dev (data); +struct net_device *real_dev =netdev_notifier_info_to_dev (data); -if (!dev) +if (!rmnet_is_real_dev_registered (real_dev))return NOTIFY_DONE ;switch (event) {case NETDEV_UNREGISTER : -netdev_dbg (dev,"Kernel unregister\n" ); -rmnet_force_unassociate_device (dev); +netdev_dbg (real_dev,"Kernel unregister\n" ); +rmnet_force_unassociate_device (real_dev);break ;default :
@@ -477,8 +474,8 @@ static int __init rmnet_init(void) static void __exit rmnet_exit(void) { -unregister_netdevice_notifier (&rmnet_dev_notifier);rtnl_link_unregister (&rmnet_link_ops); +unregister_netdevice_notifier (&rmnet_dev_notifier); }module_init (rmnet_init)
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 48/60 net: rmnet: fix bridge mode bugs
In reply to Greg Kroah-HartmanFrom: Taehee Yoo <[email protected]>
[ Upstream commit d939b6d30bea1a2322bc536b12be0a7c4c2bccd7 ]
In order to attach a bridge interface to the rmnet interface, "master" operation is used.
(e.g. ip link set dummy1 master rmnet0)
But, in the rmnet_add_bridge(), which is a callback of ->ndo_add_slave() doesn't register lower interface.
So, ->ndo_del_slave() doesn't work.
There are other problems too.
1. It couldn't detect circular upper/lower interface relationship.
2. It couldn't prevent stack overflow because of too deep depth of upper/lower interface
3. It doesn't check the number of lower interfaces.
4. Panics because of several reasons.
The root problem of these issues is actually the same. So, in this patch, these all problems will be fixed.
Test commands:
modprobe rmnet
ip link add dummy0 type dummy
ip link add rmnet0 link dummy0 type rmnet mux_id 1 ip link add dummy1 master rmnet0 type dummy ip link add dummy2 master rmnet0 type dummy ip link del rmnet0
ip link del dummy2
ip link del dummy1
Splat looks like:
[ 41.867595][ T1164] general protection fault, probably for non-canonical address 0xdffffc0000000101I [ 41.869993][ T1164] KASAN: null-ptr-deref in range [0x0000000000000808-0x000000000000080f] [ 41.872950][ T1164] CPU: 0 PID: 1164 Comm: ip Not tainted 5.6.0-rc1+ #447 [ 41.873915][ T1164] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006 [ 41.875161][ T1164] RIP: 0010:rmnet_unregister_bridge.isra.6+0x71/0xf0 [rmnet] [ 41.876178][ T1164] Code: 48 89 ef 48 89 c6 5b 5d e9 fc fe ff ff e8 f7 f3 ff ff 48 8d b8 08 08 00 00 48 ba 00 7 [ 41.878925][ T1164] RSP: 0018:ffff8880c4d0f188 EFLAGS: 00010202 [ 41.879774][ T1164] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000101 [ 41.887689][ T1164] RDX: dffffc0000000000 RSI: ffffffffb8cf64f0 RDI: 0000000000000808 [ 41.888727][ T1164] RBP: ffff8880c40e4000 R08: ffffed101b3c0e3c R09: 0000000000000001 [ 41.889749][ T1164] R10: 0000000000000001 R11: ffffed101b3c0e3b R12: 1ffff110189a1e3c [ 41.890783][ T1164] R13: ffff8880c4d0f200 R14: ffffffffb8d56160 R15: ffff8880ccc2c000 [ 41.891794][ T1164] FS: 00007f4300edc0c0(0000) GS:ffff8880d9c00000(0000) knlGS:0000000000000000 [ 41.892953][ T1164] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 41.893800][ T1164] CR2: 00007f43003bc8c0 CR3: 00000000ca53e001 CR4: 00000000000606f0 [ 41.894824][ T1164] Call Trace: [ 41.895274][ T1164] ? rcu_is_watching+0x2c/0x80 [ 41.895895][ T1164] rmnet_config_notify_cb+0x1f7/0x590 [rmnet] [ 41.896687][ T1164] ? rmnet_unregister_bridge.isra.6+0xf0/0xf0 [rmnet] [ 41.897611][ T1164] ? rmnet_unregister_bridge.isra.6+0xf0/0xf0 [rmnet] [ 41.898508][ T1164] ? __module_text_address+0x13/0x140 [ 41.899162][ T1164] notifier_call_chain+0x90/0x160 [ 41.899814][ T1164] rollback_registered_many+0x660/0xcf0 [ 41.900544][ T1164] ? netif_set_real_num_tx_queues+0x780/0x780 [ 41.901316][ T1164] ? __lock_acquire+0xdfe/0x3de0 [ 41.901958][ T1164] ? memset+0x1f/0x40 [ 41.902468][ T1164] ? __nla_validate_parse+0x98/0x1ab0 [ 41.903166][ T1164] unregister_netdevice_many.part.133+0x13/0x1b0 [ 41.903988][ T1164] rtnl_delete_link+0xbc/0x100
[ ... ]
--- .../ethernet/qualcomm/rmnet/rmnet_config.c | 131 +++++++++--------- .../ethernet/qualcomm/rmnet/rmnet_config.h | 1 + .../net/ethernet/qualcomm/rmnet/rmnet_vnd.c | 8 -- .../net/ethernet/qualcomm/rmnet/rmnet_vnd.h | 1 - 4 files changed, 64 insertions(+), 77 deletions(-)
drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c +63 -68
@@ -13,25 +13,6 @@#include "rmnet_vnd.h" #include "rmnet_private.h" -/* Locking scheme - -* The shared resource which needs to be protected is realdev->rx_handler_data. -* For the writer path, this is using rtnl_lock(). The writer paths are -* rmnet_newlink(), rmnet_dellink() and rmnet_force_unassociate_device(). These -* paths are already called with rtnl_lock() acquired in. There is also an -* ASSERT_RTNL() to ensure that we are calling with rtnl acquired. For -* dereference here, we will need to use rtnl_dereference(). Dev list writing -* needs to happen with rtnl_lock() acquired for netdev_master_upper_dev_link(). -* For the reader path, the real_dev->rx_handler_data is called in the TX / RX -* path. We only need rcu_read_lock() for these scenarios. In these cases, -* the rcu_read_lock() is held in __dev_queue_xmit() and -* netif_receive_skb_internal(), so readers need to use rcu_dereference_rtnl() -* to get the relevant information. For dev list reading, we again acquire -* rcu_read_lock() in rmnet_dellink() for netdev_master_upper_dev_get_rcu(). -* We also use unregister_netdevice_many() to free all rmnet devices in -* rmnet_force_unassociate_device() so we dont lose the rtnl_lock() and free in -* same context. -*/ -/* Local Definitions and Declarations */ static const struct nla_policy rmnet_policy[IFLA_RMNET_MAX +1 ] = {
@@ -51,9 +32,10 @@ rmnet_get_port_rtnl(const struct net_device *real_dev)return rtnl_dereference (real_dev->rx_handler_data); } -static int rmnet_unregister_real_device (struct net_device *real_dev, -struct rmnet_port *port) +static int rmnet_unregister_real_device (struct net_device *real_dev) { +struct rmnet_port *port =rmnet_get_port_rtnl (real_dev); +if (port->nr_rmnet_devs)return -EINVAL ;
@@ -93,28 +75,33 @@ static int rmnet_register_real_device(struct net_device *real_dev)return 0 ; } -static void rmnet_unregister_bridge (struct net_device *dev, -struct rmnet_port *port) +static void rmnet_unregister_bridge (struct rmnet_port *port) { -struct rmnet_port *bridge_port; -struct net_device *bridge_dev; +struct net_device *bridge_dev, *real_dev, *rmnet_dev; +struct rmnet_port *real_port;if (port->rmnet_mode !=RMNET_EPMODE_BRIDGE )return ; -/* bridge slave handling */ + rmnet_dev = port->rmnet_dev;if (!port->nr_rmnet_devs) { - bridge_dev = port->bridge_ep; +/* bridge device */ + real_dev = port->bridge_ep; + bridge_dev = port->dev; - bridge_port =rmnet_get_port_rtnl (bridge_dev); - bridge_port->bridge_ep =NULL ; - bridge_port->rmnet_mode =RMNET_EPMODE_VND ; + real_port =rmnet_get_port_rtnl (real_dev); + real_port->bridge_ep =NULL ; + real_port->rmnet_mode =RMNET_EPMODE_VND ; }else { +/* real device */ bridge_dev = port->bridge_ep; - bridge_port =rmnet_get_port_rtnl (bridge_dev); -rmnet_unregister_real_device (bridge_dev, bridge_port); + port->bridge_ep =NULL ; + port->rmnet_mode =RMNET_EPMODE_VND ; } + +netdev_upper_dev_unlink (bridge_dev, rmnet_dev); +rmnet_unregister_real_device (bridge_dev); } static int rmnet_newlink(struct net *src_net, struct net_device *dev,
@@ -161,6 +148,7 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev, goto err2; port->rmnet_mode = mode; + port->rmnet_dev = dev;hlist_add_head_rcu (&ep->hlnode, &port->muxed_ep[mux_id]);
@@ -178,8 +166,9 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev, err2:unregister_netdevice (dev); +rmnet_vnd_dellink (mux_id, port, ep); err1: -rmnet_unregister_real_device (real_dev, port); +rmnet_unregister_real_device (real_dev); err0:kfree (ep);return err;
@@ -188,30 +177,32 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev,static void rmnet_dellink (struct net_device *dev,struct list_head *head) {struct rmnet_priv *priv =netdev_priv (dev); -struct net_device *real_dev; +struct net_device *real_dev, *bridge_dev; +struct rmnet_port *real_port, *bridge_port;struct rmnet_endpoint *ep; -struct rmnet_port *port; -u8 mux_id; +u8 mux_id = priv->mux_id; real_dev = priv->real_dev; -if (!real_dev || !rmnet_is_real_dev_registered (real_dev)) +if (!rmnet_is_real_dev_registered (real_dev))return ; - port =rmnet_get_port_rtnl (real_dev); - - mux_id =rmnet_vnd_get_mux (dev); + real_port =rmnet_get_port_rtnl (real_dev); + bridge_dev = real_port->bridge_ep; +if (bridge_dev) { + bridge_port =rmnet_get_port_rtnl (bridge_dev); +rmnet_unregister_bridge (bridge_port); + } - ep =rmnet_get_endpoint (port, mux_id); + ep =rmnet_get_endpoint (real_port, mux_id);if (ep) {hlist_del_init_rcu (&ep->hlnode); -rmnet_unregister_bridge (dev, port); -rmnet_vnd_dellink (mux_id, port, ep); +rmnet_vnd_dellink (mux_id, real_port, ep);kfree (ep); } -netdev_upper_dev_unlink (real_dev, dev); -rmnet_unregister_real_device (real_dev, port); +netdev_upper_dev_unlink (real_dev, dev); +rmnet_unregister_real_device (real_dev);unregister_netdevice_queue (dev, head); }
@@ -223,23 +214,23 @@ static void rmnet_force_unassociate_device(struct net_device *real_dev)unsigned long bkt_ep;LIST_HEAD (list); -ASSERT_RTNL (); - port =rmnet_get_port_rtnl (real_dev); -rmnet_unregister_bridge (real_dev, port); - -hash_for_each_safe (port->muxed_ep, bkt_ep, tmp_ep, ep, hlnode) { -netdev_upper_dev_unlink (real_dev, ep->egress_dev); -unregister_netdevice_queue (ep->egress_dev, &list); -rmnet_vnd_dellink (ep->mux_id, port, ep); -hlist_del_init_rcu (&ep->hlnode); -kfree (ep); +if (port->nr_rmnet_devs) { +/* real device */ +rmnet_unregister_bridge (port); +hash_for_each_safe (port->muxed_ep, bkt_ep, tmp_ep, ep, hlnode) { +unregister_netdevice_queue (ep->egress_dev, &list); +netdev_upper_dev_unlink (real_dev, ep->egress_dev); +rmnet_vnd_dellink (ep->mux_id, port, ep); +hlist_del_init_rcu (&ep->hlnode); +kfree (ep); + } +rmnet_unregister_real_device (real_dev); +unregister_netdevice_many (&list); + }else { +rmnet_unregister_bridge (port); } - -unregister_netdevice_many (&list); - -rmnet_unregister_real_device (real_dev, port); } static int rmnet_config_notify_cb(struct notifier_block *nb,
@@ -418,6 +409,9 @@ int rmnet_add_bridge(struct net_device *rmnet_dev,if (port->nr_rmnet_devs >1 )return -EINVAL ; +if (port->rmnet_mode !=RMNET_EPMODE_VND ) +return -EINVAL ; +if (rmnet_is_real_dev_registered (slave_dev))return -EBUSY ;
@@ -425,9 +419,17 @@ int rmnet_add_bridge(struct net_device *rmnet_dev,if (err)return -EBUSY ; + err =netdev_master_upper_dev_link (slave_dev, rmnet_dev,NULL ,NULL , + extack); +if (err) { +rmnet_unregister_real_device (slave_dev); +return err; + } + slave_port =rmnet_get_port_rtnl (slave_dev); slave_port->rmnet_mode =RMNET_EPMODE_BRIDGE ; slave_port->bridge_ep = real_dev; + slave_port->rmnet_dev = rmnet_dev; port->rmnet_mode =RMNET_EPMODE_BRIDGE ; port->bridge_ep = slave_dev;
@@ -439,16 +441,9 @@ int rmnet_add_bridge(struct net_device *rmnet_dev,int rmnet_del_bridge (struct net_device *rmnet_dev,struct net_device *slave_dev) { -struct rmnet_priv *priv =netdev_priv (rmnet_dev); -struct net_device *real_dev = priv->real_dev; -struct rmnet_port *port, *slave_port; - - port =rmnet_get_port_rtnl (real_dev); - port->rmnet_mode =RMNET_EPMODE_VND ; - port->bridge_ep =NULL ; +struct rmnet_port *port =rmnet_get_port_rtnl (slave_dev); - slave_port =rmnet_get_port_rtnl (slave_dev); -rmnet_unregister_real_device (slave_dev, slave_port); +rmnet_unregister_bridge (port);netdev_dbg (slave_dev,"removed from rmnet as slave\n" );return 0 ;
drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h +1 -0
@@ -28,6 +28,7 @@ struct rmnet_port {u8 rmnet_mode;struct hlist_head muxed_ep[RMNET_MAX_LOGICAL_EP ];struct net_device *bridge_ep; +struct net_device *rmnet_dev; };extern struct rtnl_link_ops rmnet_link_ops;
drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c +0 -8
@@ -266,14 +266,6 @@ int rmnet_vnd_dellink(u8 id, struct rmnet_port *port,return 0 ; } -u8 rmnet_vnd_get_mux (struct net_device *rmnet_dev) -{ -struct rmnet_priv *priv; - - priv =netdev_priv (rmnet_dev); -return priv->mux_id; -} -int rmnet_vnd_do_flow_control (struct net_device *rmnet_dev,int enable) {netdev_dbg (rmnet_dev,"Setting VND TX queue state to %d\n" , enable);
drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.h +0 -1
@@ -16,6 +16,5 @@ int rmnet_vnd_dellink(u8 id, struct rmnet_port *port, struct rmnet_endpoint *ep);void rmnet_vnd_rx_fixup (struct sk_buff *skb,struct net_device *dev);void rmnet_vnd_tx_fixup (struct sk_buff *skb,struct net_device *dev); -u8 rmnet_vnd_get_mux (struct net_device *rmnet_dev);void rmnet_vnd_setup (struct net_device *dev);#endif /* _RMNET_VND_H_ */
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 49/60 net: rmnet: fix packet forwarding in rmnet bridge mode
In reply to Greg Kroah-HartmanFrom: Taehee Yoo <[email protected]>
[ Upstream commit ad3cc31b599ea80f06b29ebdc18b3a39878a48d6 ]
Packet forwarding is not working in rmnet bridge mode. Because when a packet is forwarded, skb_push() for an ethernet header is needed. But it doesn't call skb_push().
So, the ethernet header will be lost.
Test commands:
modprobe rmnet
ip netns add nst
ip netns add nst2
ip link add veth0 type veth peer name veth1
ip link add veth2 type veth peer name veth3
ip link set veth1 netns nst
ip link set veth3 netns nst2
ip link add rmnet0 link veth0 type rmnet mux_id 1 ip link set veth2 master rmnet0
ip link set veth0 up
ip link set veth2 up
ip link set rmnet0 up
ip a a 192.168.100.1/24 dev rmnet0
ip netns exec nst ip link set veth1 up
ip netns exec nst ip a a 192.168.100.2/24 dev veth1 ip netns exec nst2 ip link set veth3 up
ip netns exec nst2 ip a a 192.168.100.3/24 dev veth3 ip netns exec nst2 ping 192.168.100.2
--- drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c +3 -0
@@ -159,6 +159,9 @@ static int rmnet_map_egress_handler(struct sk_buff *skb,static void rmnet_bridge_handler (struct sk_buff *skb,struct net_device *bridge_dev) { +if (skb_mac_header_was_set (skb)) +skb_push (skb, skb->mac_len); +if (bridge_dev) { skb->dev = bridge_dev;dev_queue_xmit (skb);
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 50/60 sfc: fix timestamp reconstruction at 16-bit rollover points
In reply to Greg Kroah-HartmanFrom: Alex Maftei (amaftei) <[email protected]>
[ Upstream commit 23797b98909f34b75fd130369bde86f760db69d0 ]
We can't just use the top bits of the last sync event as they could be off-by-one every 65,536 seconds, giving an error in reconstruction of 65,536 seconds.
This patch uses the difference in the bottom 16 bits (mod 2^16) to calculate an offset that needs to be applied to the last sync event to get to the current time.
--- drivers/net/ethernet/sfc/ptp.c | 38 +++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-)
drivers/net/ethernet/sfc/ptp.c +35 -3
@@ -560,13 +560,45 @@ efx_ptp_mac_nic_to_ktime_correction(struct efx_nic *efx, u32 nic_major, u32 nic_minor, s32 correction) { + u32 sync_timestamp;ktime_t kt = {0 }; +s16 delta;if (!(nic_major &0x80000000 )) {WARN_ON_ONCE (nic_major >>16 ); -/* Use the top bits from the latest sync event. */ - nic_major &=0xffff ; - nic_major |= (last_sync_timestamp_major (efx) &0xffff0000 ); + +/* Medford provides 48 bits of timestamp, so we must get the top +* 16 bits from the timesync event state. +* +* We only have the lower 16 bits of the time now, but we do +* have a full resolution timestamp at some point in past. As +* long as the difference between the (real) now and the sync +* is less than 2^15, then we can reconstruct the difference +* between those two numbers using only the lower 16 bits of +* each. +* +* Put another way +* +* a - b = ((a mod k) - b) mod k +* +* when -k/2 < (a-b) < k/2. In our case k is 2^16. We know +* (a mod k) and b, so can calculate the delta, a - b. +* +*/ + sync_timestamp =last_sync_timestamp_major (efx); + +/* Because delta is s16 this does an implicit mask down to +* 16 bits which is what we need, assuming +* MEDFORD_TX_SECS_EVENT_BITS is 16. delta is signed so that +* we can deal with the (unlikely) case of sync timestamps +* arriving from the future. +*/ + delta = nic_major - sync_timestamp; + +/* Recover the fully specified time now, by applying the offset +* to the (fully specified) sync time. +*/ + nic_major = sync_timestamp + delta; kt = ptp->nic_to_kernel_time (nic_major, nic_minor, correction);
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 51/60 jbd2: fix data races at struct journal_head
In reply to Greg Kroah-HartmanFrom: Qian Cai <[email protected]>
[ Upstream commit 6c5d911249290f41f7b50b43344a7520605b1acb ]
journal_head::b_transaction and journal_head::b_next_transaction could be accessed concurrently as noticed by KCSAN,
LTP: starting fsync04
/dev/zero: Can't open blockdev
EXT4-fs (loop0): mounting ext3 file system using the ext4 subsystem EXT4-fs (loop0): mounted filesystem with ordered data mode. Opts: (null)
==================================================================
BUG: KCSAN: data-race in __jbd2_journal_refile_buffer [jbd2] / jbd2_write_access_granted [jbd2]
write to 0xffff99f9b1bd0e30 of 8 bytes by task 25721 on cpu 70:
__jbd2_journal_refile_buffer+0xdd/0x210 [jbd2] __jbd2_journal_refile_buffer at fs/jbd2/transaction.c:2569 jbd2_journal_commit_transaction+0x2d15/0x3f20 [jbd2] (inlined by) jbd2_journal_commit_transaction at fs/jbd2/commit.c:1034 kjournald2+0x13b/0x450 [jbd2] kthread+0x1cd/0x1f0 ret_from_fork+0x27/0x50
read to 0xffff99f9b1bd0e30 of 8 bytes by task 25724 on cpu 68:
jbd2_write_access_granted+0x1b2/0x250 [jbd2] jbd2_write_access_granted at fs/jbd2/transaction.c:1155 jbd2_journal_get_write_access+0x2c/0x60 [jbd2] __ext4_journal_get_write_access+0x50/0x90 [ext4] ext4_mb_mark_diskspace_used+0x158/0x620 [ext4] ext4_mb_new_blocks+0x54f/0xca0 [ext4] ext4_ind_map_blocks+0xc79/0x1b40 [ext4] ext4_map_blocks+0x3b4/0x950 [ext4] _ext4_get_block+0xfc/0x270 [ext4] ext4_get_block+0x3b/0x50 [ext4] __block_write_begin_int+0x22e/0xae0 __block_write_begin+0x39/0x50 ext4_write_begin+0x388/0xb50 [ext4] generic_perform_write+0x15d/0x290 ext4_buffered_write_iter+0x11f/0x210 [ext4] ext4_file_write_iter+0xce/0x9e0 [ext4] new_sync_write+0x29c/0x3b0 __vfs_write+0x92/0xa0 vfs_write+0x103/0x260 ksys_write+0x9d/0x130 __x64_sys_write+0x4c/0x60 do_syscall_64+0x91/0xb05 entry_SYSCALL_64_after_hwframe+0x49/0xbe
5 locks held by fsync04/25724:
#0: ffff99f9911093f8 (sb_writers#13){.+.+}, at: vfs_write+0x21c/0x260
#1: ffff99f9db4c0348 (&sb->s_type->i_mutex_key#15){+.+.}, at: ext4_buffered_write_iter+0x65/0x210 [ext4] #2: ffff99f5e7dfcf58 (jbd2_handle){++++}, at: start_this_handle+0x1c1/0x9d0 [jbd2]
#3: ffff99f9db4c0168 (&ei->i_data_sem){++++}, at: ext4_map_blocks+0x176/0x950 [ext4] #4: ffffffff99086b40 (rcu_read_lock){....}, at: jbd2_write_access_granted+0x4e/0x250 [jbd2]
irq event stamp: 1407125 hardirqs last enabled at (1407125): [<ffffffff980da9b7>] __find_get_block+0x107/0x790 hardirqs last disabled at (1407124): [<ffffffff980da8f9>] __find_get_block+0x49/0x790 softirqs last enabled at (1405528): [<ffffffff98a0034c>] __do_softirq+0x34c/0x57c softirqs last disabled at (1405521): [<ffffffff97cc67a2>] irq_exit+0xa2/0xc0
Reported by Kernel Concurrency Sanitizer on:
CPU: 68 PID: 25724 Comm: fsync04 Tainted: G L 5.6.0-rc2-next-20200221+ #7 Hardware name: HPE ProLiant DL385 Gen10/ProLiant DL385 Gen10, BIOS A40 07/10/2019
The plain reads are outside of jh->b_state_lock critical section which result in data races. Fix them by adding pairs of READ|WRITE_ONCE().
--- fs/jbd2/transaction.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
fs/jbd2/transaction.c +4 -4
@@ -1079,8 +1079,8 @@ static bool jbd2_write_access_granted(handle_t *handle, struct buffer_head *bh,/* For undo access buffer must have data copied */ if (undo && !jh->b_committed_data) goto out; -if (jh->b_transaction != handle->h_transaction && - jh->b_next_transaction != handle->h_transaction) +if (READ_ONCE (jh->b_transaction) != handle->h_transaction && +READ_ONCE (jh->b_next_transaction) != handle->h_transaction) goto out;/* * There are two reasons for the barrier here:
@@ -2535,8 +2535,8 @@ void __jbd2_journal_refile_buffer(struct journal_head *jh)* our jh reference and thus __jbd2_journal_file_buffer() must not * take a new one. */ - jh->b_transaction = jh->b_next_transaction; - jh->b_next_transaction =NULL ; +WRITE_ONCE (jh->b_transaction, jh->b_next_transaction); +WRITE_ONCE (jh->b_next_transaction,NULL );if (buffer_freed (bh)) jlist = BJ_Forget;else if (jh->b_modified)
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 52/60 blk-mq: insert flush request to the front of dispatch queue
In reply to Greg Kroah-HartmanFrom: Ming Lei <[email protected]>
[ Upstream commit cc3200eac4c5eb11c3f34848a014d1f286316310 ]
commit 01e99aeca397 ("blk-mq: insert passthrough request into hctx->dispatch directly") may change to add flush request to the tail of dispatch by applying the 'add_head' parameter of blk_mq_sched_insert_request.
Turns out this way causes performance regression on NCQ controller because flush is non-NCQ command, which can't be queued when there is any in-flight NCQ command. When adding flush rq to the front of hctx->dispatch, it is easier to introduce extra time to flush rq's latency compared with adding to the tail of dispatch queue because of S_SCHED_RESTART, then chance of flush merge is increased, and less flush requests may be issued to controller.
So always insert flush request to the front of dispatch queue just like before applying commit 01e99aeca397 ("blk-mq: insert passthrough request into hctx->dispatch directly").
--- block/blk-mq-sched.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
block/blk-mq-sched.c +22 -0
@@ -398,6 +398,28 @@ void blk_mq_sched_insert_request(struct request *rq, bool at_head,WARN_ON (e && (rq->tag !=-1 ));if (blk_mq_sched_bypass_insert (hctx, !!e, rq)) { +/* +* Firstly normal IO request is inserted to scheduler queue or +* sw queue, meantime we add flush request to dispatch queue( +* hctx->dispatch) directly and there is at most one in-flight +* flush request for each hw queue, so it doesn't matter to add +* flush request to tail or front of the dispatch queue. +* +* Secondly in case of NCQ, flush request belongs to non-NCQ +* command, and queueing it will fail when there is any +* in-flight normal IO request(NCQ command). When adding flush +* rq to the front of hctx->dispatch, it is easier to introduce +* extra time to flush rq's latency because of S_SCHED_RESTART +* compared with adding to the tail of dispatch queue, then +* chance of flush merge is increased, and less flush requests +* will be issued to controller. It is observed that ~10% time +* is saved in blktests block/004 on disk attached to AHCI/NCQ +* drive when adding flush rq to the front of hctx->dispatch. +* +* Simply queue flush rq to the front of hctx->dispatch so that +* intensive flush workloads can benefit in case of NCQ HW. +*/ + at_head = (rq->rq_flags &RQF_FLUSH_SEQ ) ? true : at_head;blk_mq_request_bypass_insert (rq, at_head, false); goto run; }
Signature · 1 line
2.20.1
Greg Kroah-Hartman
maintainerPATCH 53/60 net: qrtr: fix len of skb_put_padto in qrtr_node_enqueue
In reply to Greg Kroah-HartmanFrom: Carl Huang <[email protected]>
commit ce57785bf91b1ceaef4f4bffed8a47dc0919c8da upstream.
The len used for skb_put_padto is wrong, it need to add len of hdr.
In qrtr_node_enqueue, local variable size_t len is assign with skb->len, then skb_push(skb, sizeof(*hdr)) will add skb->len with sizeof(*hdr), so local variable size_t len is not same with skb->len after skb_push(skb, sizeof(*hdr)).
Then the purpose of skb_put_padto(skb, ALIGN(len, 4)) is to add add pad to the end of the skb's data if skb->len is not aligned to 4, but unfortunately it use len instead of skb->len, at this line, skb->len is 32 bytes(sizeof(*hdr)) more than len, for example, len is 3 bytes, then skb->len is 35 bytes(3 + 32), and ALIGN(len, 4) is 4 bytes, so __skb_put_padto will do nothing after check size(35) < len(4), the correct value should be 36(sizeof(*hdr) + ALIGN(len, 4) = 32 + 4), then __skb_put_padto will pass check size(35) < len(36) and add 1 byte to the end of skb's data, then logic is correct.
function of skb_push:
void *skb_push(struct sk_buff *skb, unsigned int len)
{
skb->data -= len;
skb->len += len;
if (unlikely(skb->data < skb->head))
skb_under_panic(skb, len, __builtin_return_address(0));
return skb->data;
}function of skb_put_padto
static inline int skb_put_padto(struct sk_buff *skb, unsigned int len)
{
return __skb_put_padto(skb, len, true);
}function of __skb_put_padto
static inline int __skb_put_padto(struct sk_buff *skb, unsigned int len,
bool free_on_error)
{
unsigned int size = skb->len;
if (unlikely(size < len)) {
len -= size;
if (__skb_pad(skb, len, free_on_error))
return -ENOMEM;
__skb_put(skb, len);
}
return 0;
}--- net/qrtr/qrtr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/qrtr/qrtr.c +1 -1
@@ -196,7 +196,7 @@ static int qrtr_node_enqueue(struct qrtr hdr->size =cpu_to_le32 (len); hdr->confirm_rx =0 ; -skb_put_padto (skb,ALIGN (len,4 )); +skb_put_padto (skb,ALIGN (len,4 ) +sizeof (*hdr));mutex_lock (&node->ep_lock);if (node->ep)
Greg Kroah-Hartman
maintainerPATCH 54/60 ARM: 8957/1: VDSO: Match ARMv8 timer in cntvct_functional()
In reply to Greg Kroah-HartmanFrom: Florian Fainelli <[email protected]>
commit 45939ce292b4b11159719faaf60aba7d58d5fe33 upstream.
It is possible for a system with an ARMv8 timer to run a 32-bit kernel. When this happens we will unconditionally have the vDSO code remove the __vdso_gettimeofday and __vdso_clock_gettime symbols because cntvct_functional() returns false since it does not match that compatibility string.
--- arch/arm/kernel/vdso.c | 2 ++ 1 file changed, 2 insertions(+)
arch/arm/kernel/vdso.c +2 -0
@@ -93,6 +93,8 @@ static bool __init cntvct_functional(voi*/ np =of_find_compatible_node (NULL ,NULL ,"arm,armv7-timer" );if (!np) + np =of_find_compatible_node (NULL ,NULL ,"arm,armv8-timer" ); +if (!np) goto out_put;if (of_property_read_bool (np,"arm,cpu-registers-not-fw-configured" ))
Greg Kroah-Hartman
maintainerPATCH 55/60 ARM: 8958/1: rename missed uaccess .fixup section
In reply to Greg Kroah-HartmanFrom: Kees Cook <[email protected]>
commit f87b1c49bc675da30d8e1e8f4b60b800312c7b90 upstream.
When the uaccess .fixup section was renamed to .text.fixup, one case was missed. Under ld.bfd, the orphaned section was moved close to .text (since they share the "ax" bits), so things would work normally on uaccess faults. Under ld.lld, the orphaned section was placed outside the .text section, making it unreachable.
--- arch/arm/lib/copy_from_user.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/lib/copy_from_user.S +1 -1
@@ -118,7 +118,7 @@ ENTRY(arm_copy_from_user) ENDPROC(arm_copy_from_user) - .pushsection .fixup,"ax" + .pushsection .text.fixup,"ax" .align 0 copy_abort_preamble ldmfd sp!, {r1, r2, r3}
Greg Kroah-Hartman
maintainerPATCH 56/60 mm: slub: add missing TID bump in kmem_cache_alloc_bulk()
In reply to Greg Kroah-HartmanFrom: Jann Horn <[email protected]>
commit fd4d9c7d0c71866ec0c2825189ebd2ce35bd95b8 upstream.
When kmem_cache_alloc_bulk() attempts to allocate N objects from a percpu freelist of length M, and N > M > 0, it will first remove the M elements from the percpu freelist, then call ___slab_alloc() to allocate the next element and repopulate the percpu freelist. ___slab_alloc() can re-enable IRQs via allocate_slab(), so the TID must be bumped before ___slab_alloc() to properly commit the freelist head change.
Fix it by unconditionally bumping c->tid when entering the slowpath.
--- mm/slub.c | 9 +++++++++ 1 file changed, 9 insertions(+)
mm/slub.c +9 -0
@@ -3155,6 +3155,15 @@ int kmem_cache_alloc_bulk(struct kmem_caif (unlikely (!object)) {/* +* We may have removed an object from c->freelist using +* the fastpath in the previous iteration; in that case, +* c->tid has not been bumped yet. +* Since ___slab_alloc() may reenable interrupts while +* allocating memory, we should bump c->tid now. +*/ + c->tid =next_tid (c->tid); + +/* * Invoking slow path likely have side-effect * of re-populating per CPU c->freelist */
Greg Kroah-Hartman
maintainerPATCH 57/60 HID: google: add moonball USB id
In reply to Greg Kroah-HartmanFrom: Chen-Tsung Hsieh <[email protected]>
commit 58322a1590fc189a8e1e349d309637d4a4942840 upstream.
Add 1 additional hammer-like device.
--- drivers/hid/hid-google-hammer.c | 2 ++ drivers/hid/hid-ids.h | 1 + 2 files changed, 3 insertions(+)
drivers/hid/hid-google-hammer.c +2 -0
@@ -474,6 +474,8 @@ static const struct hid_device_id hammer {HID_DEVICE (BUS_USB ,HID_GROUP_GENERIC , USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_MASTERBALL) }, { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, + USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_MOONBALL) }, + { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_STAFF) }, { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_WAND) },
drivers/hid/hid-ids.h +1 -0
@@ -478,6 +478,7 @@#define USB_DEVICE_ID_GOOGLE_WHISKERS 0x5030#define USB_DEVICE_ID_GOOGLE_MASTERBALL 0x503c#define USB_DEVICE_ID_GOOGLE_MAGNEMITE 0x503d +#define USB_DEVICE_ID_GOOGLE_MOONBALL 0x5044#define USB_VENDOR_ID_GOTOP 0x08f2#define USB_DEVICE_ID_SUPER_Q2 0x007f
Greg Kroah-Hartman
maintainerPATCH 58/60 HID: add ALWAYS_POLL quirk to lenovo pixart mouse
In reply to Greg Kroah-HartmanFrom: Tony Fischetti <[email protected]>
commit 819d578d51d0ce73f06e35d69395ef55cd683a74 upstream.
A lenovo pixart mouse (17ef:608d) is afflicted common the the malfunction where it disconnects and reconnects every minute--each time incrementing the device number. This patch adds the device id of the device and specifies that it needs the HID_QUIRK_ALWAYS_POLL quirk in order to work properly.
--- drivers/hid/hid-ids.h | 1 + drivers/hid/hid-quirks.c | 1 + 2 files changed, 2 insertions(+)
drivers/hid/hid-ids.h +1 -0
@@ -727,6 +727,7 @@#define USB_DEVICE_ID_LENOVO_X1_COVER 0x6085#define USB_DEVICE_ID_LENOVO_X1_TAB 0x60a3#define USB_DEVICE_ID_LENOVO_X1_TAB3 0x60b5 +#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_608D 0x608d#define USB_VENDOR_ID_LG 0x1fd2#define USB_DEVICE_ID_LG_MULTITOUCH 0x0064
drivers/hid/hid-quirks.c +1 -0
@@ -103,6 +103,7 @@ static const struct hid_device_id hid_qu { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_PENSKETCH_M912), HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M406XE), HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_PIXART_USB_OPTICAL_MOUSE_ID2), HID_QUIRK_ALWAYS_POLL }, + { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_608D), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C007), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C077), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KEYBOARD_G710_PLUS), HID_QUIRK_NOGET },
Greg Kroah-Hartman
maintainerPATCH 59/60 ARM: 8961/2: Fix Kbuild issue caused by per-task stack protector GCC plugin
In reply to Greg Kroah-HartmanFrom: Ard Biesheuvel <[email protected]>
commit 89604523a76eb3e13014b2bdab7f8870becee284 upstream.
When using plugins, GCC requires that the -fplugin= options precedes any of its plugin arguments appearing on the command line as well. This is usually not a concern, but as it turns out, this requirement is causing some issues with ARM's per-task stack protector plugin and Kbuild's implementation of $(cc-option).
When the per-task stack protector plugin is enabled, and we tweak the implementation of cc-option not to pipe the stderr output of GCC to /dev/null, the following output is generated when GCC is executed in the context of cc-option:
cc1: error: plugin arm_ssp_per_task_plugin should be specified before \
-fplugin-arg-arm_ssp_per_task_plugin-tso=1 in the command line
cc1: error: plugin arm_ssp_per_task_plugin should be specified before \
-fplugin-arg-arm_ssp_per_task_plugin-offset=24 in the command lineThese errors will cause any option passed to cc-option to be treated as unsupported, which is obviously incorrect.
The cause of this issue is the fact that the -fplugin= argument is added to GCC_PLUGINS_CFLAGS, whereas the arguments above are added to KBUILD_CFLAGS, and the contents of the former get filtered out of the latter before being passed to the GCC running the cc-option test, and so the -fplugin= option does not appear at all on the GCC command line.
Adding the arguments to GCC_PLUGINS_CFLAGS instead of KBUILD_CFLAGS would be the correct approach here, if it weren't for the fact that we are using $(eval) to defer the moment that they are added until after asm-offsets.h is generated, which is after the point where the contents of GCC_PLUGINS_CFLAGS are added to KBUILD_CFLAGS. So instead, we have to add our plugin arguments to both.
For similar reasons, we cannot append DISABLE_ARM_SSP_PER_TASK_PLUGIN to KBUILD_CFLAGS, as it will be passed to GCC when executing in the context of cc-option, whereas the other plugin arguments will have been filtered out, resulting in a similar error and false negative result as above. So add it to ccflags-y instead.
--- arch/arm/Makefile | 4 +++- arch/arm/boot/compressed/Makefile | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-)
arch/arm/Makefile +3 -1
@@ -307,13 +307,15 @@ endif ifeq ($(CONFIG_STACKPROTECTOR_PER_TASK),y) prepare: stack_protector_prepare stack_protector_prepare: prepare0 - $(eval KBUILD_CFLAGS += \ + $(eval SSP_PLUGIN_CFLAGS := \ -fplugin-arg-arm_ssp_per_task_plugin-tso=$(shell \ awk '{if ($$2 == "THREAD_SZ_ORDER") print $$3;}'\ include/generated/asm-offsets.h) \ -fplugin-arg-arm_ssp_per_task_plugin-offset=$(shell \ awk '{if ($$2 == "TI_STACK_CANARY") print $$3;}'\ include/generated/asm-offsets.h)) + $(eval KBUILD_CFLAGS += $(SSP_PLUGIN_CFLAGS)) + $(eval GCC_PLUGINS_CFLAGS += $(SSP_PLUGIN_CFLAGS)) endif all: $(notdir $(KBUILD_IMAGE))
arch/arm/boot/compressed/Makefile +2 -2
@@ -101,7 +101,6 @@ clean-files += piggy_data lib1funcs.S as $(libfdt) $(libfdt_hdrs) hyp-stub.S KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING -KBUILD_CFLAGS += $(DISABLE_ARM_SSP_PER_TASK_PLUGIN) ifeq ($(CONFIG_FUNCTION_TRACER),y) ORIG_CFLAGS := $(KBUILD_CFLAGS)
@@ -117,7 +116,8 @@ CFLAGS_fdt_ro.o := $(nossp_flags) CFLAGS_fdt_rw.o := $(nossp_flags) CFLAGS_fdt_wip.o := $(nossp_flags) -ccflags-y := -fpic $(call cc-option,-mno-single-pic-base,) -fno-builtin -I$(obj) +ccflags-y := -fpic $(call cc-option,-mno-single-pic-base,) -fno-builtin \ + -I$(obj) $(DISABLE_ARM_SSP_PER_TASK_PLUGIN) asflags-y := -DZIMAGE # Supply kernel BSS size to the decompressor via a linker symbol.
Greg Kroah-Hartman
maintainerPATCH 60/60 ipv4: ensure rcu_read_lock() in cipso_v4_error()
In reply to Greg Kroah-HartmanFrom: Matteo Croce <[email protected]>
commit 3e72dfdf8227b052393f71d820ec7599909dddc2 upstream.
Similarly to commit c543cb4a5f07 ("ipv4: ensure rcu_read_lock() in ipv4_link_failure()"), __ip_options_compile() must be called under rcu protection.
--- net/ipv4/cipso_ipv4.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
net/ipv4/cipso_ipv4.c +6 -1
@@ -1724,6 +1724,7 @@ void cipso_v4_error(struct sk_buff *skb, {unsigned char optbuf[sizeof (struct ip_options ) +40 ];struct ip_options *opt = (struct ip_options *)optbuf; +int res;if (ip_hdr (skb)->protocol ==IPPROTO_ICMP || error != -EACCES )return ;
@@ -1735,7 +1736,11 @@ void cipso_v4_error(struct sk_buff *skb,memset (opt,0 ,sizeof (struct ip_options )); opt->optlen =ip_hdr (skb)->ihl*4 -sizeof (struct iphdr ); -if (__ip_options_compile (dev_net (skb->dev), opt, skb,NULL )) +rcu_read_lock (); + res =__ip_options_compile (dev_net (skb->dev), opt, skb,NULL ); +rcu_read_unlock (); + +if (res)return ;if (gateway)
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.4.27 release. There are 60 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 Sat, 21 Mar 2020 12:37:04 +0000. 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/v5.x/stable-review/patch-5.4.27-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.4.y
and the diffstat can be found below.thanks,
greg k-h
Results from Linaro’s test farm.
This regression is platform specific.
On arm64 dragonboard 410c-QC410E* the LT hugemmap05 and hackbench test cases started failing on this build and easy to reproduce. Where as on other arm64 platforms (juno-r2, nxp-ls2088) these test PASS.
These two test case scenario run on independent execution.
Steps to reproduce,
cd /opt/ltp
./runltp -s hugemmap05
cd /opt/ltp/testcases/bin
./hackbench 50 process 1000
./hackbench 20 thread 1000
Test output log:
--------------------
hugemmap05.c:89: BROK: mmap((nil),402653184,3,1,6,0) failed: ENOMEM (12) tst_safe_sysv_ipc.c:99: BROK: hugemmap05.c:85: shmget(218431587, 402653184, b80) failed: ENOMEM (12)
Running with 50*40 (== 2000) tasks.fork() (error: Resource temporarily unavailable) Running with 20*40 (== 800) tasks.pthread_create failed: Resource temporarily unavailable (11)
*
RAM: 1GB LPDDR3 SDRAM @ 533MHz
CPU: ARM Cortex-A53 Quad-core up to 1.2 GHz per core
https://qa-reports.linaro.org/lkft/linux-stable-rc-5.4-oe/tests/ltp-hugetlb-tests/hugemmap05
https://qa-reports.linaro.org/lkft/linux-stable-rc-5.4-oe/tests/ltp-sched-tests/hackbench01
https://qa-reports.linaro.org/lkft/linux-stable-rc-5.4-oe/tests/ltp-sched-tests/hackbench02
--
Linaro LKFT
https://lkft.linaro.org
Greg Kroah-Hartman
maintainerQuoted 50 lines · Naresh Kamboju
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.4.27 release. There are 60 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 Sat, 21 Mar 2020 12:37:04 +0000. 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/v5.x/stable-review/patch-5.4.27-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.4.y
and the diffstat can be found below.thanks,
greg k-h
Results from Linaro’s test farm.
This regression is platform specific.On arm64 dragonboard 410c-QC410E* the LT hugemmap05 and hackbench test cases started failing on this build and easy to reproduce. Where as on other arm64 platforms (juno-r2, nxp-ls2088) these test PASS.
These two test case scenario run on independent execution.
Steps to reproduce,
cd/opt/ltp
./runltp -s hugemmap05cd
/opt/ltp/testcases/bin
./hackbench 50 process 1000
./hackbench 20 thread 1000Test output log:
--------------------
hugemmap05.c:89: BROK: mmap((nil),402653184,3,1,6,0) failed: ENOMEM (12) tst_safe_sysv_ipc.c:99: BROK: hugemmap05.c:85:shmget(218431587, 402653184, b80)failed: ENOMEM (12)Running with 50*40 (== 2000) tasks.
fork()(error: Resource temporarily unavailable) Running with 20*40 (== 800) tasks.pthread_createfailed: Resource temporarily unavailable (11)
Quoted 7 lines
*
RAM: 1GB LPDDR3 SDRAM @ 533MHz
CPU: ARM Cortex-A53 Quad-core up to 1.2 GHz per corehttps://qa-reports.linaro.org/lkft/linux-stable-rc-5.4-oe/tests/ltp-hugetlb-tests/hugemmap05
https://qa-reports.linaro.org/lkft/linux-stable-rc-5.4-oe/tests/ltp-sched-tests/hackbench01
https://qa-reports.linaro.org/lkft/linux-stable-rc-5.4-oe/tests/ltp-sched-tests/hackbench02
Any chance you can run 'git bisect' to find the issue here?
thanks,
greg k-h
Quoted 10 lines · Greg Kroah-Hartman
Quoted 8 lines · Naresh Kamboju
hugemmap05.c:89: BROK: mmap((nil),402653184,3,1,6,0) failed: ENOMEM (12) tst_safe_sysv_ipc.c:99: BROK: hugemmap05.c:85:
shmget(218431587, 402653184, b80)failed: ENOMEM (12)Running with 50*40 (== 2000) tasks.
fork()(error: Resource temporarily unavailable) Running with 20*40 (== 800) tasks.pthread_createfailed: Resource temporarily unavailable (11)
On 5.4.27-rc3 the above report problem not reproduced. I have re-tested multiple times to confirm this.
- Naresh
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.4.27 release. There are 60 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 Sat, 21 Mar 2020 12:37:04 +0000. Anything received after that time might be too late.
Build results:
total: 158 pass: 158 fail: 0 Qemu test results: total: 427 pass: 425 fail: 2
Failed tests:
mipsel64:64r6el_defconfig:notests:smp:ide:hd mipsel64:64r6el_defconfig:notests:smp:ide:cd
Building mipsel64:64r6el_defconfig:notests:smp:ide:hd ... failed
------------
Error log:arch/mips/vdso/vdso.so.dbg.raw: PIC 'jalr t9' calls are not supported
I was unable to figure out why I only see this problem in v5.4.y. The build error is easy to reproduce with gcc 9.2.0 and "64r6el_defconfig".
Guenter
Greg Kroah-Hartman
maintainerQuoted 18 lines · Guenter Roeck
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.4.27 release. There are 60 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 Sat, 21 Mar 2020 12:37:04 +0000. Anything received after that time might be too late.
Build results:
total: 158 pass: 158 fail: 0 Qemu test results: total: 427 pass: 425 fail: 2Failed tests:
mipsel64:64r6el_defconfig:notests:smp:ide:hd mipsel64:64r6el_defconfig:notests:smp:ide:cd
Quoted 7 lines
Building mipsel64:64r6el_defconfig:notests:smp:ide:hd ... failed
------------
Error log:arch/mips/vdso/vdso.so.dbg.raw: PIC 'jalr t9' calls are not supportedI was unable to figure out why I only see this problem in v5.4.y. The build error is easy to reproduce with gcc 9.2.0 and "64r6el_defconfig".
I've dropped a bunch of mips vdso patches from 5.5 and 5.4 queues now and will push out new -rcs with those in them to hopefully resolve these issues.
thanks,
greg k-h
Quoted 25 lines · Greg Kroah-Hartman
Quoted 23 lines · Guenter Roeck
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.4.27 release. There are 60 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 Sat, 21 Mar 2020 12:37:04 +0000. Anything received after that time might be too late.
Build results:
total: 158 pass: 158 fail: 0 Qemu test results: total: 427 pass: 425 fail: 2Failed tests:
mipsel64:64r6el_defconfig:notests:smp:ide:hd mipsel64:64r6el_defconfig:notests:smp:ide:cdBuilding mipsel64:64r6el_defconfig:notests:smp:ide:hd ... failed
------------
Error log:arch/mips/vdso/vdso.so.dbg.raw: PIC 'jalr t9' calls are not supported
Quoted 6 lines
Quoted 2 lines
I was unable to figure out why I only see this problem in v5.4.y. The build error is easy to reproduce with gcc 9.2.0 and "64r6el_defconfig".
I've dropped a bunch of mips vdso patches from 5.5 and 5.4 queues now and will push out new -rcs with those in them to hopefully resolve these issues.
amr64 and arm build failed on stable-rc 5.4 and 5.5
# make -sk KBUILD_BUILD_USER=TuxBuild -C/linux -j16 ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- HOSTCC=gcc CC="sccache aarch64-linux-gnu-gcc" O=build Image # ../drivers/mmc/host/sdhci-tegra.c: In function ‘sdhci_tegra_probe’: ../drivers/mmc/host/sdhci-tegra.c:1556:21: error: ‘MMC_CAP_NEED_RSP_BUSY’ undeclared (first use in this function); did you mean ‘MMC_CAP_NEEDS_POLL’? 1556 | host->mmc->caps |= MMC_CAP_NEED_RSP_BUSY; | ^~~~~~~~~~~~~~~~~~~~~ | MMC_CAP_NEEDS_POLL
Greg Kroah-Hartman
maintainerQuoted 36 lines · Naresh Kamboju
Quoted 25 lines · Greg Kroah-Hartman
Quoted 23 lines · Guenter Roeck
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.4.27 release. There are 60 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 Sat, 21 Mar 2020 12:37:04 +0000. Anything received after that time might be too late.
Build results:
total: 158 pass: 158 fail: 0 Qemu test results: total: 427 pass: 425 fail: 2Failed tests:
mipsel64:64r6el_defconfig:notests:smp:ide:hd mipsel64:64r6el_defconfig:notests:smp:ide:cdBuilding mipsel64:64r6el_defconfig:notests:smp:ide:hd ... failed
------------
Error log:arch/mips/vdso/vdso.so.dbg.raw: PIC 'jalr t9' calls are not supportedQuoted 6 lines
Quoted 2 lines
I was unable to figure out why I only see this problem in v5.4.y. The build error is easy to reproduce with gcc 9.2.0 and "64r6el_defconfig".
I've dropped a bunch of mips vdso patches from 5.5 and 5.4 queues now and will push out new -rcs with those in them to hopefully resolve these issues.
amr64 and arm build failed on stable-rc 5.4 and 5.5
Quoted 11 lines
# make -sk KBUILD_BUILD_USER=TuxBuild -C/linux -j16 ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- HOSTCC=gcc CC="sccache aarch64-linux-gnu-gcc" O=build Image # ../drivers/mmc/host/sdhci-tegra.c: In function ‘sdhci_tegra_probe’: ../drivers/mmc/host/sdhci-tegra.c:1556:21: error: ‘MMC_CAP_NEED_RSP_BUSY’ undeclared (first use in this function); did you mean ‘MMC_CAP_NEEDS_POLL’? 1556 | host->mmc->caps |= MMC_CAP_NEED_RSP_BUSY; | ^~~~~~~~~~~~~~~~~~~~~ | MMC_CAP_NEEDS_POLL
Crap, I didn't build for arm. I'll go push out -rc3 for this issue now, sorry for the noise...
greg k-h