From: Luo Meng luomeng12@huawei.com
[ Upstream commit 16238415eb9886328a89fe7a3cb0b88c7335fe16 ]
When the sum of fl->fl_start and l->l_len overflows, UBSAN shows the following warning:
UBSAN: Undefined behaviour in fs/locks.c:482:29 signed integer overflow: 2 + 9223372036854775806 cannot be represented in type 'long long int' Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0xe4/0x14e lib/dump_stack.c:118 ubsan_epilogue+0xe/0x81 lib/ubsan.c:161 handle_overflow+0x193/0x1e2 lib/ubsan.c:192 flock64_to_posix_lock fs/locks.c:482 [inline] flock_to_posix_lock+0x595/0x690 fs/locks.c:515 fcntl_setlk+0xf3/0xa90 fs/locks.c:2262 do_fcntl+0x456/0xf60 fs/fcntl.c:387 __do_sys_fcntl fs/fcntl.c:483 [inline] __se_sys_fcntl fs/fcntl.c:468 [inline] __x64_sys_fcntl+0x12d/0x180 fs/fcntl.c:468 do_syscall_64+0xc8/0x5a0 arch/x86/entry/common.c:293 entry_SYSCALL_64_after_hwframe+0x49/0xbe
Fix it by parenthesizing 'l->l_len - 1'.
Signed-off-by: Luo Meng luomeng12@huawei.com Signed-off-by: Jeff Layton jlayton@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/locks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/locks.c b/fs/locks.c index 28270e74be342..465917362eca3 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -479,7 +479,7 @@ static int flock64_to_posix_lock(struct file *filp, struct file_lock *fl, if (l->l_len > 0) { if (l->l_len - 1 > OFFSET_MAX - fl->fl_start) return -EOVERFLOW; - fl->fl_end = fl->fl_start + l->l_len - 1; + fl->fl_end = fl->fl_start + (l->l_len - 1);
} else if (l->l_len < 0) { if (fl->fl_start + l->l_len < 0)
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit d9594e0409651a237903a13c9718df889f43d43b ]
clang warns about additions on NULL pointers being undefined in C:
security/tomoyo/securityfs_if.c:226:59: warning: arithmetic on a null pointer treated as a cast from integer to pointer is a GNU extension [-Wnull-pointer-arithmetic] securityfs_create_file(name, mode, parent, ((u8 *) NULL) + key,
Change the code to instead use a cast through uintptr_t to avoid the warning.
Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Tetsuo Handa penguin-kernel@I-love.SAKURA.ne.jp Signed-off-by: Sasha Levin sashal@kernel.org --- security/tomoyo/securityfs_if.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/security/tomoyo/securityfs_if.c b/security/tomoyo/securityfs_if.c index 1d3d7e7a1f055..6f1161f4e613d 100644 --- a/security/tomoyo/securityfs_if.c +++ b/security/tomoyo/securityfs_if.c @@ -131,8 +131,8 @@ static const struct file_operations tomoyo_self_operations = { */ static int tomoyo_open(struct inode *inode, struct file *file) { - const int key = ((u8 *) file_inode(file)->i_private) - - ((u8 *) NULL); + const u8 key = (uintptr_t) file_inode(file)->i_private; + return tomoyo_open_control(key, file); }
@@ -223,7 +223,7 @@ static const struct file_operations tomoyo_operations = { static void __init tomoyo_create_entry(const char *name, const umode_t mode, struct dentry *parent, const u8 key) { - securityfs_create_file(name, mode, parent, ((u8 *) NULL) + key, + securityfs_create_file(name, mode, parent, (void *) (uintptr_t) key, &tomoyo_operations); }
From: Zhang Qilong zhangqilong3@huawei.com
[ Upstream commit 383e8a823014532ffd81c787ef9009f1c2bd3b79 ]
pm_runtime_get_sync() will increment pm usage counter even when it returns an error code. We should call put operation in error handling paths of omap_aes_hw_init.
Signed-off-by: Zhang Qilong zhangqilong3@huawei.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/omap-aes.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c index 9019f6b67986b..080c7cf077053 100644 --- a/drivers/crypto/omap-aes.c +++ b/drivers/crypto/omap-aes.c @@ -109,6 +109,7 @@ static int omap_aes_hw_init(struct omap_aes_dev *dd)
err = pm_runtime_get_sync(dd->dev); if (err < 0) { + pm_runtime_put_noidle(dd->dev); dev_err(dd->dev, "failed to get sync: %d\n", err); return err; }
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit 9364a2cf567187c0a075942c22d1f434c758de5d ]
Fix build errors when CONFIG_NET is not enabled. E.g. (trimmed):
ld: drivers/staging/wimax/op-msg.o: in function `wimax_msg_alloc': op-msg.c:(.text+0xa9): undefined reference to `__alloc_skb' ld: op-msg.c:(.text+0xcc): undefined reference to `genlmsg_put' ld: op-msg.c:(.text+0xfc): undefined reference to `nla_put' ld: op-msg.c:(.text+0x168): undefined reference to `kfree_skb' ld: drivers/staging/wimax/op-msg.o: in function `wimax_msg_data_len': op-msg.c:(.text+0x1ba): undefined reference to `nla_find' ld: drivers/staging/wimax/op-msg.o: in function `wimax_msg_send': op-msg.c:(.text+0x311): undefined reference to `init_net' ld: op-msg.c:(.text+0x326): undefined reference to `netlink_broadcast' ld: drivers/staging/wimax/stack.o: in function `__wimax_state_change': stack.c:(.text+0x433): undefined reference to `netif_carrier_off' ld: stack.c:(.text+0x46b): undefined reference to `netif_carrier_on' ld: stack.c:(.text+0x478): undefined reference to `netif_tx_wake_queue' ld: drivers/staging/wimax/stack.o: in function `wimax_subsys_exit': stack.c:(.exit.text+0xe): undefined reference to `genl_unregister_family' ld: drivers/staging/wimax/stack.o: in function `wimax_subsys_init': stack.c:(.init.text+0x1a): undefined reference to `genl_register_family'
Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: Jakub Kicinski kuba@kernel.org Cc: Arnd Bergmann arnd@arndb.de Cc: netdev@vger.kernel.org Acked-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Randy Dunlap rdunlap@infradead.org Link: https://lore.kernel.org/r/20201102072456.20303-1-rdunlap@infradead.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/wimax/Kconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/net/wimax/Kconfig b/net/wimax/Kconfig index e4d97ab476d58..945bdf4738eb6 100644 --- a/net/wimax/Kconfig +++ b/net/wimax/Kconfig @@ -4,6 +4,7 @@
menuconfig WIMAX tristate "WiMAX Wireless Broadband support" + depends on NET depends on RFKILL || !RFKILL help
From: akshatzen akshatzen@google.com
[ Upstream commit 48cd6b38eb4f2874f091c4776ea1c26e7e4f967e ]
In function check_fw_ready() we busy wait using udelay. The CPU is not released and we see need_resched failures.
Busy waiting is not necessary since we are in process context and we can sleep instead. Replace udelay with msleep of 20 ms intervals while waiting for firmware to become ready.
It has been verified that check_fw_ready is not being used in interrupt context anywhere, hence it is safe to make this change.
Link: https://lore.kernel.org/r/20201102165528.26510-4-Viswas.G@microchip.com.com Acked-by: Jack Wang jinpu.wang@cloud.ionos.com Signed-off-by: akshatzen akshatzen@google.com Signed-off-by: Viswas G Viswas.G@microchip.com Signed-off-by: Ruksar Devadi Ruksar.devadi@microchip.com Signed-off-by: Radha Ramachandran radha@google.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/pm8001/pm80xx_hwi.c | 21 +++++++++++---------- drivers/scsi/pm8001/pm80xx_hwi.h | 6 ++++++ 2 files changed, 17 insertions(+), 10 deletions(-)
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c index c63b5db435c59..6b22e6c10e0e4 100644 --- a/drivers/scsi/pm8001/pm80xx_hwi.c +++ b/drivers/scsi/pm8001/pm80xx_hwi.c @@ -703,6 +703,7 @@ static int mpi_init_check(struct pm8001_hba_info *pm8001_ha)
/** * check_fw_ready - The LLDD check if the FW is ready, if not, return error. + * This function sleeps hence it must not be used in atomic context. * @pm8001_ha: our hba card information */ static int check_fw_ready(struct pm8001_hba_info *pm8001_ha) @@ -713,16 +714,16 @@ static int check_fw_ready(struct pm8001_hba_info *pm8001_ha) int ret = 0;
/* reset / PCIe ready */ - max_wait_time = max_wait_count = 100 * 1000; /* 100 milli sec */ + max_wait_time = max_wait_count = 5; /* 100 milli sec */ do { - udelay(1); + msleep(FW_READY_INTERVAL); value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1); } while ((value == 0xFFFFFFFF) && (--max_wait_count));
/* check ila status */ - max_wait_time = max_wait_count = 1000 * 1000; /* 1000 milli sec */ + max_wait_time = max_wait_count = 50; /* 1000 milli sec */ do { - udelay(1); + msleep(FW_READY_INTERVAL); value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1); } while (((value & SCRATCH_PAD_ILA_READY) != SCRATCH_PAD_ILA_READY) && (--max_wait_count)); @@ -735,9 +736,9 @@ static int check_fw_ready(struct pm8001_hba_info *pm8001_ha) }
/* check RAAE status */ - max_wait_time = max_wait_count = 1800 * 1000; /* 1800 milli sec */ + max_wait_time = max_wait_count = 90; /* 1800 milli sec */ do { - udelay(1); + msleep(FW_READY_INTERVAL); value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1); } while (((value & SCRATCH_PAD_RAAE_READY) != SCRATCH_PAD_RAAE_READY) && (--max_wait_count)); @@ -750,9 +751,9 @@ static int check_fw_ready(struct pm8001_hba_info *pm8001_ha) }
/* check iop0 status */ - max_wait_time = max_wait_count = 600 * 1000; /* 600 milli sec */ + max_wait_time = max_wait_count = 30; /* 600 milli sec */ do { - udelay(1); + msleep(FW_READY_INTERVAL); value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1); } while (((value & SCRATCH_PAD_IOP0_READY) != SCRATCH_PAD_IOP0_READY) && (--max_wait_count)); @@ -768,9 +769,9 @@ static int check_fw_ready(struct pm8001_hba_info *pm8001_ha) if ((pm8001_ha->chip_id != chip_8008) && (pm8001_ha->chip_id != chip_8009)) { /* 200 milli sec */ - max_wait_time = max_wait_count = 200 * 1000; + max_wait_time = max_wait_count = 10; do { - udelay(1); + msleep(FW_READY_INTERVAL); value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1); } while (((value & SCRATCH_PAD_IOP1_READY) != SCRATCH_PAD_IOP1_READY) && (--max_wait_count)); diff --git a/drivers/scsi/pm8001/pm80xx_hwi.h b/drivers/scsi/pm8001/pm80xx_hwi.h index bbe1747234ff0..56022a59c08b3 100644 --- a/drivers/scsi/pm8001/pm80xx_hwi.h +++ b/drivers/scsi/pm8001/pm80xx_hwi.h @@ -1634,3 +1634,9 @@ typedef struct SASProtocolTimerConfig SASProtocolTimerConfig_t;
#define MEMBASE_II_SHIFT_REGISTER 0x1010 #endif + +/** + * As we know sleep (1~20) ms may result in sleep longer than ~20 ms, hence we + * choose 20 ms interval. + */ +#define FW_READY_INTERVAL 20
From: yuuzheng yuuzheng@google.com
[ Upstream commit 1f889b58716a5f5e3e4fe0e6742c1a4472f29ac1 ]
A use-after-free or null-pointer error occurs when the 251-byte response data is copied from IOMB buffer to response message buffer in function pm8001_mpi_get_nvmd_resp().
After sending the command get_nvmd_data(), the caller begins to sleep by calling wait_for_complete() and waits for the wake-up from calling complete() in pm8001_mpi_get_nvmd_resp(). Due to unexpected events (e.g., interrupt), if response buffer gets freed before memcpy(), a use-after-free error will occur. To fix this, the complete() should be called after memcpy().
Link: https://lore.kernel.org/r/20201102165528.26510-5-Viswas.G@microchip.com.com Acked-by: Jack Wang jinpu.wang@cloud.ionos.com Signed-off-by: yuuzheng yuuzheng@google.com Signed-off-by: Viswas G Viswas.G@microchip.com Signed-off-by: Ruksar Devadi Ruksar.devadi@microchip.com Signed-off-by: Radha Ramachandran radha@google.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/pm8001/pm8001_hwi.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index 3e814c0469fbd..026bf39e3892d 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c @@ -3196,10 +3196,15 @@ pm8001_mpi_get_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) pm8001_ha->memoryMap.region[NVMD].virt_ptr, fw_control_context->len); kfree(ccb->fw_control_context); + /* To avoid race condition, complete should be + * called after the message is copied to + * fw_control_context->usrAddr + */ + complete(pm8001_ha->nvmd_completion); + PM8001_MSG_DBG(pm8001_ha, pm8001_printk("Set nvm data complete!\n")); ccb->task = NULL; ccb->ccb_tag = 0xFFFFFFFF; pm8001_tag_free(pm8001_ha, tag); - complete(pm8001_ha->nvmd_completion); }
int pm8001_mpi_local_phy_ctl(struct pm8001_hba_info *pm8001_ha, void *piomb)
From: Boqun Feng boqun.feng@gmail.com
[ Upstream commit 8d1ddb5e79374fb277985a6b3faa2ed8631c5b4c ]
Syzbot reports a potential deadlock found by the newly added recursive read deadlock detection in lockdep:
[...] ======================================================== [...] WARNING: possible irq lock inversion dependency detected [...] 5.9.0-rc2-syzkaller #0 Not tainted [...] -------------------------------------------------------- [...] syz-executor.1/10214 just changed the state of lock: [...] ffff88811f506338 (&f->f_owner.lock){.+..}-{2:2}, at: send_sigurg+0x1d/0x200 [...] but this lock was taken by another, HARDIRQ-safe lock in the past: [...] (&dev->event_lock){-...}-{2:2} [...] [...] [...] and interrupts could create inverse lock ordering between them. [...] [...] [...] other info that might help us debug this: [...] Chain exists of: [...] &dev->event_lock --> &new->fa_lock --> &f->f_owner.lock [...] [...] Possible interrupt unsafe locking scenario: [...] [...] CPU0 CPU1 [...] ---- ---- [...] lock(&f->f_owner.lock); [...] local_irq_disable(); [...] lock(&dev->event_lock); [...] lock(&new->fa_lock); [...] <Interrupt> [...] lock(&dev->event_lock); [...] [...] *** DEADLOCK ***
The corresponding deadlock case is as followed:
CPU 0 CPU 1 CPU 2 read_lock(&fown->lock); spin_lock_irqsave(&dev->event_lock, ...) write_lock_irq(&filp->f_owner.lock); // wait for the lock read_lock(&fown-lock); // have to wait until the writer release // due to the fairness <interrupted> spin_lock_irqsave(&dev->event_lock); // wait for the lock
The lock dependency on CPU 1 happens if there exists a call sequence:
input_inject_event(): spin_lock_irqsave(&dev->event_lock,...); input_handle_event(): input_pass_values(): input_to_handler(): handler->event(): // evdev_event() evdev_pass_values(): spin_lock(&client->buffer_lock); __pass_event(): kill_fasync(): kill_fasync_rcu(): read_lock(&fa->fa_lock); send_sigio(): read_lock(&fown->lock);
To fix this, make the reader in send_sigurg() and send_sigio() use read_lock_irqsave() and read_lock_irqrestore().
Reported-by: syzbot+22e87cdf94021b984aa6@syzkaller.appspotmail.com Reported-by: syzbot+c5e32344981ad9f33750@syzkaller.appspotmail.com Signed-off-by: Boqun Feng boqun.feng@gmail.com Signed-off-by: Jeff Layton jlayton@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/fcntl.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/fs/fcntl.c b/fs/fcntl.c index 4137d96534a6c..e039af1872ab2 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c @@ -779,9 +779,10 @@ void send_sigio(struct fown_struct *fown, int fd, int band) { struct task_struct *p; enum pid_type type; + unsigned long flags; struct pid *pid; - read_lock(&fown->lock); + read_lock_irqsave(&fown->lock, flags);
type = fown->pid_type; pid = fown->pid; @@ -802,7 +803,7 @@ void send_sigio(struct fown_struct *fown, int fd, int band) read_unlock(&tasklist_lock); } out_unlock_fown: - read_unlock(&fown->lock); + read_unlock_irqrestore(&fown->lock, flags); }
static void send_sigurg_to_task(struct task_struct *p, @@ -817,9 +818,10 @@ int send_sigurg(struct fown_struct *fown) struct task_struct *p; enum pid_type type; struct pid *pid; + unsigned long flags; int ret = 0; - read_lock(&fown->lock); + read_lock_irqsave(&fown->lock, flags);
type = fown->pid_type; pid = fown->pid; @@ -842,7 +844,7 @@ int send_sigurg(struct fown_struct *fown) read_unlock(&tasklist_lock); } out_unlock_fown: - read_unlock(&fown->lock); + read_unlock_irqrestore(&fown->lock, flags); return ret; }
From: Qinglang Miao miaoqinglang@huawei.com
[ Upstream commit d1e7550ad081fa5e9260f636dd51e1c496e0fd5f ]
Add the missing destroy_workqueue() before return from ks7010_sdio_probe in the error handling case.
Signed-off-by: Qinglang Miao miaoqinglang@huawei.com Link: https://lore.kernel.org/r/20201028091552.136445-1-miaoqinglang@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/staging/ks7010/ks7010_sdio.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/staging/ks7010/ks7010_sdio.c b/drivers/staging/ks7010/ks7010_sdio.c index 74551eb717fc7..b3445a19db6f1 100644 --- a/drivers/staging/ks7010/ks7010_sdio.c +++ b/drivers/staging/ks7010/ks7010_sdio.c @@ -1028,10 +1028,12 @@ static int ks7010_sdio_probe(struct sdio_func *func,
ret = register_netdev(priv->net_dev); if (ret) - goto err_free_netdev; + goto err_destroy_wq;
return 0;
+ err_destroy_wq: + destroy_workqueue(priv->wq); err_free_netdev: free_netdev(netdev); err_release_irq:
From: Zhang Qilong zhangqilong3@huawei.com
[ Upstream commit 071dc1787a2f8bb636f864c1f306280deea3b1d5 ]
The 'EPERM' cannot appear in the previous path, we should use '-EPERM' to check it. For example:
Call trace: ->rtl8192_rx_isr ->usb_submit_urb ->usb_hcd_submit_urb ->rh_urb_enqueue ->rh_queue_status ->usb_hcd_link_urb_to_ep
Signed-off-by: Zhang Qilong zhangqilong3@huawei.com Link: https://lore.kernel.org/r/20201028122648.47959-1-zhangqilong3@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/staging/rtl8192u/r8192U_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index 87244a2089763..e141a0086f8d5 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -928,7 +928,7 @@ static void rtl8192_rx_isr(struct urb *urb) urb->context = skb; skb_queue_tail(&priv->rx_queue, skb); err = usb_submit_urb(urb, GFP_ATOMIC); - if (err && err != EPERM) + if (err && err != -EPERM) netdev_err(dev, "can not submit rxurb, err is %x, URB status is %x\n", err, urb->status);
From: Qinglang Miao miaoqinglang@huawei.com
[ Upstream commit 5a5aa912f687204d50455d0db36f94dd8de601c2 ]
Add the missing iounmap() of gpch->regs before return from ar7_gpio_init() in the error handling case.
Signed-off-by: Qinglang Miao miaoqinglang@huawei.com Signed-off-by: Thomas Bogendoerfer tsbogend@alpha.franken.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/mips/ar7/gpio.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/mips/ar7/gpio.c b/arch/mips/ar7/gpio.c index 4eee7e9e26ee2..3ba58f980fec2 100644 --- a/arch/mips/ar7/gpio.c +++ b/arch/mips/ar7/gpio.c @@ -332,6 +332,7 @@ int __init ar7_gpio_init(void) if (ret) { printk(KERN_ERR "%s: failed to add gpiochip\n", gpch->chip.label); + iounmap(gpch->regs); return ret; } printk(KERN_INFO "%s: registered %d GPIOs\n",
From: Qinglang Miao miaoqinglang@huawei.com
[ Upstream commit 2673ecf9586551c5bcee499c1cc1949f6f7cc9a1 ]
Add the missing iounmap() of iounmap(mips_gcr_base) before return from mips_cm_probe() in the error handling case.
Signed-off-by: Qinglang Miao miaoqinglang@huawei.com Signed-off-by: Thomas Bogendoerfer tsbogend@alpha.franken.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/mips/kernel/mips-cm.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/mips/kernel/mips-cm.c b/arch/mips/kernel/mips-cm.c index 50d3d74001cbe..aedd353b9b925 100644 --- a/arch/mips/kernel/mips-cm.c +++ b/arch/mips/kernel/mips-cm.c @@ -228,6 +228,7 @@ int mips_cm_probe(void) if ((base_reg & CM_GCR_BASE_GCRBASE) != addr) { pr_err("GCRs appear to have been moved (expected them at 0x%08lx)!\n", (unsigned long)addr); + iounmap(mips_gcr_base); mips_gcr_base = NULL; return -ENODEV; }
From: "Paul E. McKenney" paulmck@kernel.org
[ Upstream commit 6b74fa0a776e3715d385b23d29db469179c825b0 ]
If an locktorture torture-test run is given a bad kvm.sh argument, the test will complain to the console, which is good. What is bad is that from the user's perspective, it will just hang for the time specified by the --duration argument. This commit therefore forces an immediate kernel shutdown if a lock_torture_init()-time error occurs, thus avoiding the appearance of a hang. It also forces a console splat in this case to clearly indicate the presence of an error.
Signed-off-by: Paul E. McKenney paulmck@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/locking/locktorture.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/kernel/locking/locktorture.c b/kernel/locking/locktorture.c index 95395ef5922ac..89e3ae2262e59 100644 --- a/kernel/locking/locktorture.c +++ b/kernel/locking/locktorture.c @@ -43,6 +43,7 @@ #include <linux/slab.h> #include <linux/percpu-rwsem.h> #include <linux/torture.h> +#include <linux/reboot.h>
MODULE_LICENSE("GPL"); MODULE_AUTHOR("Paul E. McKenney paulmck@us.ibm.com"); @@ -1055,6 +1056,10 @@ static int __init lock_torture_init(void) unwind: torture_init_end(); lock_torture_cleanup(); + if (shutdown_secs) { + WARN_ON(!IS_MODULE(CONFIG_LOCK_TORTURE_TEST)); + kernel_power_off(); + } return firsterr; }
From: "Paul E. McKenney" paulmck@kernel.org
[ Upstream commit c64659ef29e3901be0900ec6fb0485fa3dbdcfd8 ]
Even when the kernel panics and qemu dies, runs with jitter enabled will continue uselessly until the jitter.sh processes terminate. This can be annoying if a planned one-hour run instead dies during boot.
This commit therefore kills the jitter.sh processes when the run ends more than one minute prior to the termination time specified by the kvm.sh --duration argument or its default.
Signed-off-by: Paul E. McKenney paulmck@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- .../selftests/rcutorture/bin/kvm-test-1-run.sh | 14 ++++++++++++++ tools/testing/selftests/rcutorture/bin/kvm.sh | 5 ++++- 2 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh b/tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh index f7247ee00514d..73cba8d13179c 100755 --- a/tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh +++ b/tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh @@ -216,6 +216,20 @@ do echo "ps -fp $killpid" >> $resdir/Warnings 2>&1 ps -fp $killpid >> $resdir/Warnings 2>&1 fi + # Reduce probability of PID reuse by allowing a one-minute buffer + if test $((kruntime + 60)) -lt $seconds && test -s "$resdir/../jitter_pids" + then + awk < "$resdir/../jitter_pids" ' + NF > 0 { + pidlist = pidlist " " $1; + n++; + } + END { + if (n > 0) { + print "kill " pidlist; + } + }' | sh + fi else echo ' ---' `date`: "Kernel done" fi diff --git a/tools/testing/selftests/rcutorture/bin/kvm.sh b/tools/testing/selftests/rcutorture/bin/kvm.sh index 5a7a62d76a50b..02fd8a19fa7ea 100755 --- a/tools/testing/selftests/rcutorture/bin/kvm.sh +++ b/tools/testing/selftests/rcutorture/bin/kvm.sh @@ -401,8 +401,11 @@ function dump(first, pastlast, batchnum) print "if test -n "$needqemurun"" print "then" print "\techo ---- Starting kernels. `date` | tee -a " rd "log"; - for (j = 0; j < njitter; j++) + print "\techo > " rd "jitter_pids" + for (j = 0; j < njitter; j++) { print "\tjitter.sh " j " " dur " " ja[2] " " ja[3] "&" + print "\techo $! >> " rd "jitter_pids" + } print "\twait" print "\techo ---- All kernel runs complete. `date` | tee -a " rd "log"; print "else"
From: "Paul E. McKenney" paulmck@kernel.org
[ Upstream commit 4994684ce10924a0302567c315c91b0a64eeef46 ]
If an rcutorture torture-test run is given a bad kvm.sh argument, the test will complain to the console, which is good. What is bad is that from the user's perspective, it will just hang for the time specified by the --duration argument. This commit therefore forces an immediate kernel shutdown if a rcu_torture_init()-time error occurs, thus avoiding the appearance of a hang. It also forces a console splat in this case to clearly indicate the presence of an error.
Signed-off-by: Paul E. McKenney paulmck@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/rcu/rcutorture.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c index 0b7af7e2bcbb1..79129a91347f0 100644 --- a/kernel/rcu/rcutorture.c +++ b/kernel/rcu/rcutorture.c @@ -2134,6 +2134,10 @@ rcu_torture_init(void) unwind: torture_init_end(); rcu_torture_cleanup(); + if (shutdown_secs) { + WARN_ON(!IS_MODULE(CONFIG_RCU_TORTURE_TEST)); + kernel_power_off(); + } return firsterr; }
From: Marek Vasut marex@denx.de
[ Upstream commit 65277100caa2f2c62b6f3c4648b90d6f0435f3bc ]
In case RSI9116 SDIO WiFi operates in STA mode against Intel 9260 in AP mode, the association fails. The former is using wpa_supplicant during association, the later is set up using hostapd:
iwl$ cat hostapd.conf interface=wlp1s0 ssid=test country_code=DE hw_mode=g channel=1 wpa=2 wpa_passphrase=test wpa_key_mgmt=WPA-PSK iwl$ hostapd -d hostapd.conf
rsi$ wpa_supplicant -i wlan0 -c <(wpa_passphrase test test)
The problem is that the TX EAPOL data descriptor RSI_DESC_REQUIRE_CFM_TO_HOST flag and extended descriptor EAPOL4_CONFIRM frame type are not set in case the AP is iwlwifi, because in that case the TX EAPOL packet is 2 bytes shorter.
The downstream vendor driver has this change in place already [1], however there is no explanation for it, neither is there any commit history from which such explanation could be obtained.
[1] https://github.com/SiliconLabs/RS911X-nLink-OSD/blob/master/rsi/rsi_91x_hal....
Signed-off-by: Marek Vasut marex@denx.de Cc: Angus Ainslie angus@akkea.ca Cc: David S. Miller davem@davemloft.net Cc: Jakub Kicinski kuba@kernel.org Cc: Kalle Valo kvalo@codeaurora.org Cc: Lee Jones lee.jones@linaro.org Cc: Martin Kepplinger martink@posteo.de Cc: Sebastian Krzyszkowiak sebastian.krzyszkowiak@puri.sm Cc: Siva Rebbagondla siva8118@gmail.com Cc: linux-wireless@vger.kernel.org Cc: netdev@vger.kernel.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20201015111616.429220-1-marex@denx.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/rsi/rsi_91x_hal.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/rsi/rsi_91x_hal.c b/drivers/net/wireless/rsi/rsi_91x_hal.c index a7b341e95e764..0da95777f1c15 100644 --- a/drivers/net/wireless/rsi/rsi_91x_hal.c +++ b/drivers/net/wireless/rsi/rsi_91x_hal.c @@ -238,7 +238,8 @@ int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb) rsi_set_len_qno(&data_desc->len_qno, (skb->len - FRAME_DESC_SZ), RSI_WIFI_MGMT_Q); - if ((skb->len - header_size) == EAPOL4_PACKET_LEN) { + if (((skb->len - header_size) == EAPOL4_PACKET_LEN) || + ((skb->len - header_size) == EAPOL4_PACKET_LEN - 2)) { data_desc->misc_flags |= RSI_DESC_REQUIRE_CFM_TO_HOST; xtend_desc->confirm_frame_type = EAPOL4_CONFIRM;
From: Qinglang Miao miaoqinglang@huawei.com
[ Upstream commit f2e66f212a9de04afc2caa5ec79057c0ac75c728 ]
Add the missing platform_driver_unregister() before return from panel_simple_init in the error handling case when failed to register panel_simple_dsi_driver with CONFIG_DRM_MIPI_DSI enabled.
Signed-off-by: Qinglang Miao miaoqinglang@huawei.com Signed-off-by: Sam Ravnborg sam@ravnborg.org Link: https://patchwork.freedesktop.org/patch/msgid/20201031011856.137307-1-miaoqi... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/panel/panel-simple.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 8814aa38c5e7b..eead8f075c94b 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -2878,8 +2878,10 @@ static int __init panel_simple_init(void)
if (IS_ENABLED(CONFIG_DRM_MIPI_DSI)) { err = mipi_dsi_driver_register(&panel_simple_dsi_driver); - if (err < 0) + if (err < 0) { + platform_driver_unregister(&panel_simple_platform_driver); return err; + } }
return 0;
From: KuoHsiang Chou kuohsiang_chou@aspeedtech.com
[ Upstream commit 2d26123dd9075df82f217364f585a3a6aab5412d ]
[Bug] Change the vertical synchroous polary of 1920x1080 @60Hz from Negtive to Positive
Signed-off-by: KuoHsiang Chou kuohsiang_chou@aspeedtech.com Signed-off-by: Thomas Zimmermann tzimmermann@suse.de Link: https://patchwork.freedesktop.org/patch/msgid/20201105094729.106059-1-kuohsi... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/ast/ast_tables.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/ast/ast_tables.h b/drivers/gpu/drm/ast/ast_tables.h index d665dd5af5dd8..dbe1cc620f6e6 100644 --- a/drivers/gpu/drm/ast/ast_tables.h +++ b/drivers/gpu/drm/ast/ast_tables.h @@ -293,10 +293,10 @@ static const struct ast_vbios_enhtable res_1600x900[] = {
static const struct ast_vbios_enhtable res_1920x1080[] = { {2200, 1920, 88, 44, 1125, 1080, 4, 5, VCLK148_5, /* 60Hz */ - (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo | + (SyncPP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo | AST2500PreCatchCRT), 60, 1, 0x38 }, {2200, 1920, 88, 44, 1125, 1080, 4, 5, VCLK148_5, /* 60Hz */ - (SyncNP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo | + (SyncPP | Charx8Dot | LineCompareOff | WideScreenMode | NewModeInfo | AST2500PreCatchCRT), 0xFF, 1, 0x38 }, };
From: Christian Borntraeger borntraeger@de.ibm.com
[ Upstream commit d041315ef75cf52df19613f56a2da2c5911c163c ]
The s390-trng does provide 100% entropy. The quality value is supported to be between 1 and 1024 and not 1..1000. Use 1024 to make this driver the preferred one. If we ever have a better driver that has the same quality but is faster we can change this again when merging the new driver. No need to be conservative.
This makes sure that the hw variant is preferred over things like virtio-rng, where the hypervisor has a potential to be misconfigured and thus should have a slightly lower confidence.
Cc: Harald Freudenberger freude@linux.ibm.com Signed-off-by: Christian Borntraeger borntraeger@de.ibm.com Signed-off-by: Heiko Carstens hca@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/char/hw_random/s390-trng.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/char/hw_random/s390-trng.c b/drivers/char/hw_random/s390-trng.c index aca48e893fca1..14747fb23a57f 100644 --- a/drivers/char/hw_random/s390-trng.c +++ b/drivers/char/hw_random/s390-trng.c @@ -196,14 +196,15 @@ static int trng_hwrng_read(struct hwrng *rng, void *data, size_t max, bool wait)
/* * hwrng register struct - * The trng is suppost to have 100% entropy, and thus - * we register with a very high quality value. + * The trng is supposed to have 100% entropy, and thus we register with a very + * high quality value. If we ever have a better driver in the future, we should + * change this value again when we merge this driver. */ static struct hwrng trng_hwrng_dev = { .name = "s390-trng", .data_read = trng_hwrng_data_read, .read = trng_hwrng_read, - .quality = 999, + .quality = 1024, };
From: Ole Bjørn Midtbø omidtbo@cisco.com
[ Upstream commit cca342d98bef68151a80b024f7bf5f388d1fbdea ]
A different wait queue was used when removing ctrl_wait than when adding it. This effectively made the remove operation without locking compared to other operations on the wait queue ctrl_wait was part of. This caused issues like below where dead000000000100 is LIST_POISON1 and dead000000000200 is LIST_POISON2.
list_add corruption. next->prev should be prev (ffffffc1b0a33a08), \ but was dead000000000200. (next=ffffffc03ac77de0). ------------[ cut here ]------------ CPU: 3 PID: 2138 Comm: bluetoothd Tainted: G O 4.4.238+ #9 ... ---[ end trace 0adc2158f0646eac ]--- Call trace: [<ffffffc000443f78>] __list_add+0x38/0xb0 [<ffffffc0000f0d04>] add_wait_queue+0x4c/0x68 [<ffffffc00020eecc>] __pollwait+0xec/0x100 [<ffffffc000d1556c>] bt_sock_poll+0x74/0x200 [<ffffffc000bdb8a8>] sock_poll+0x110/0x128 [<ffffffc000210378>] do_sys_poll+0x220/0x480 [<ffffffc0002106f0>] SyS_poll+0x80/0x138 [<ffffffc00008510c>] __sys_trace_return+0x0/0x4
Unable to handle kernel paging request at virtual address dead000000000100 ... CPU: 4 PID: 5387 Comm: kworker/u15:3 Tainted: G W O 4.4.238+ #9 ... Call trace: [<ffffffc0000f079c>] __wake_up_common+0x7c/0xa8 [<ffffffc0000f0818>] __wake_up+0x50/0x70 [<ffffffc000be11b0>] sock_def_wakeup+0x58/0x60 [<ffffffc000de5e10>] l2cap_sock_teardown_cb+0x200/0x224 [<ffffffc000d3f2ac>] l2cap_chan_del+0xa4/0x298 [<ffffffc000d45ea0>] l2cap_conn_del+0x118/0x198 [<ffffffc000d45f8c>] l2cap_disconn_cfm+0x6c/0x78 [<ffffffc000d29934>] hci_event_packet+0x564/0x2e30 [<ffffffc000d19b0c>] hci_rx_work+0x10c/0x360 [<ffffffc0000c2218>] process_one_work+0x268/0x460 [<ffffffc0000c2678>] worker_thread+0x268/0x480 [<ffffffc0000c94e0>] kthread+0x118/0x128 [<ffffffc000085070>] ret_from_fork+0x10/0x20 ---[ end trace 0adc2158f0646ead ]---
Signed-off-by: Ole Bjørn Midtbø omidtbo@cisco.com Signed-off-by: Marcel Holtmann marcel@holtmann.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/bluetooth/hidp/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 253975cce943e..0cbd0bca971ff 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -1282,7 +1282,7 @@ static int hidp_session_thread(void *arg)
/* cleanup runtime environment */ remove_wait_queue(sk_sleep(session->intr_sock->sk), &intr_wait); - remove_wait_queue(sk_sleep(session->intr_sock->sk), &ctrl_wait); + remove_wait_queue(sk_sleep(session->ctrl_sock->sk), &ctrl_wait); wake_up_interruptible(&session->report_queue); hidp_del_timer(session);
From: Alexander Lobakin alobakin@pm.me
[ Upstream commit 8be33ecfc1ffd2da20cc29e957e4cb6eb99310cb ]
Similar to commit fda55eca5a33f ("net: introduce skb_transport_header_was_set()"), avoid resetting transport offsets that were already set by GRO layer. This not only mirrors the behavior of __netif_receive_skb_core(), but also makes sense when it comes to UDP GSO fraglists forwarding: transport offset of such skbs is set only once by GRO receive callback and remains untouched and correct up to the xmitting driver in 1:1 case, but becomes junk after untagging in ingress VLAN case and breaks UDP GSO offload. This does not happen after this change, and all types of forwarding of UDP GSO fraglists work as expected.
Since v1 [1]: - keep the code 1:1 with __netif_receive_skb_core() (Jakub).
[1] https://lore.kernel.org/netdev/zYurwsZRN7BkqSoikWQLVqHyxz18h4LhHU4NFa2Vw@cp4...
Signed-off-by: Alexander Lobakin alobakin@pm.me Link: https://lore.kernel.org/r/7JgIkgEztzt0W6ZtC9V9Cnk5qfkrUFYcpN871syCi8@cp4-web... Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/core/skbuff.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index b5d9c9b2c7028..57fdf450fd6fe 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -5144,7 +5144,8 @@ struct sk_buff *skb_vlan_untag(struct sk_buff *skb) goto err_free;
skb_reset_network_header(skb); - skb_reset_transport_header(skb); + if (!skb_transport_header_was_set(skb)) + skb_reset_transport_header(skb); skb_reset_mac_len(skb);
return skb;
From: Dinghao Liu dinghao.liu@zju.edu.cn
[ Upstream commit a5d704d33245b0799947a3008f9f376dba4d5c91 ]
pm_runtime_get_sync() increments the runtime PM usage counter even when it returns an error code. However, users of its direct wrappers in omapdrm assume that PM usage counter will not change on error. Thus a pairing decrement is needed on the error handling path for these wrappers to keep the counter balanced.
Signed-off-by: Dinghao Liu dinghao.liu@zju.edu.cn Signed-off-by: Tomi Valkeinen tomi.valkeinen@ti.com Link: https://patchwork.freedesktop.org/patch/msgid/20200822065743.13671-1-dinghao... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/omapdrm/dss/dispc.c | 7 +++++-- drivers/gpu/drm/omapdrm/dss/dsi.c | 7 +++++-- drivers/gpu/drm/omapdrm/dss/dss.c | 7 +++++-- drivers/gpu/drm/omapdrm/dss/hdmi4.c | 6 +++--- drivers/gpu/drm/omapdrm/dss/hdmi5.c | 6 +++--- drivers/gpu/drm/omapdrm/dss/venc.c | 7 +++++-- 6 files changed, 26 insertions(+), 14 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c b/drivers/gpu/drm/omapdrm/dss/dispc.c index 84f274c4a4cbf..9dbe952872785 100644 --- a/drivers/gpu/drm/omapdrm/dss/dispc.c +++ b/drivers/gpu/drm/omapdrm/dss/dispc.c @@ -675,8 +675,11 @@ int dispc_runtime_get(struct dispc_device *dispc) DSSDBG("dispc_runtime_get\n");
r = pm_runtime_get_sync(&dispc->pdev->dev); - WARN_ON(r < 0); - return r < 0 ? r : 0; + if (WARN_ON(r < 0)) { + pm_runtime_put_noidle(&dispc->pdev->dev); + return r; + } + return 0; }
void dispc_runtime_put(struct dispc_device *dispc) diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c index 8160954ebc257..80e8efcb8acf7 100644 --- a/drivers/gpu/drm/omapdrm/dss/dsi.c +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c @@ -1143,8 +1143,11 @@ static int dsi_runtime_get(struct dsi_data *dsi) DSSDBG("dsi_runtime_get\n");
r = pm_runtime_get_sync(dsi->dev); - WARN_ON(r < 0); - return r < 0 ? r : 0; + if (WARN_ON(r < 0)) { + pm_runtime_put_noidle(dsi->dev); + return r; + } + return 0; }
static void dsi_runtime_put(struct dsi_data *dsi) diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c b/drivers/gpu/drm/omapdrm/dss/dss.c index 7e9e2f0644544..9db2454b25488 100644 --- a/drivers/gpu/drm/omapdrm/dss/dss.c +++ b/drivers/gpu/drm/omapdrm/dss/dss.c @@ -878,8 +878,11 @@ int dss_runtime_get(struct dss_device *dss) DSSDBG("dss_runtime_get\n");
r = pm_runtime_get_sync(&dss->pdev->dev); - WARN_ON(r < 0); - return r < 0 ? r : 0; + if (WARN_ON(r < 0)) { + pm_runtime_put_noidle(&dss->pdev->dev); + return r; + } + return 0; }
void dss_runtime_put(struct dss_device *dss) diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c b/drivers/gpu/drm/omapdrm/dss/hdmi4.c index 5879f45f6fc9b..38bdf50d39a58 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c @@ -52,10 +52,10 @@ static int hdmi_runtime_get(struct omap_hdmi *hdmi) DSSDBG("hdmi_runtime_get\n");
r = pm_runtime_get_sync(&hdmi->pdev->dev); - WARN_ON(r < 0); - if (r < 0) + if (WARN_ON(r < 0)) { + pm_runtime_put_noidle(&hdmi->pdev->dev); return r; - + } return 0; }
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5.c b/drivers/gpu/drm/omapdrm/dss/hdmi5.c index ae1a001d1b838..16f33aa5ad185 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi5.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi5.c @@ -53,10 +53,10 @@ static int hdmi_runtime_get(struct omap_hdmi *hdmi) DSSDBG("hdmi_runtime_get\n");
r = pm_runtime_get_sync(&hdmi->pdev->dev); - WARN_ON(r < 0); - if (r < 0) + if (WARN_ON(r < 0)) { + pm_runtime_put_noidle(&hdmi->pdev->dev); return r; - + } return 0; }
diff --git a/drivers/gpu/drm/omapdrm/dss/venc.c b/drivers/gpu/drm/omapdrm/dss/venc.c index ac01907dcc345..9ef2942d938fd 100644 --- a/drivers/gpu/drm/omapdrm/dss/venc.c +++ b/drivers/gpu/drm/omapdrm/dss/venc.c @@ -438,8 +438,11 @@ static int venc_runtime_get(struct venc_device *venc) DSSDBG("venc_runtime_get\n");
r = pm_runtime_get_sync(&venc->pdev->dev); - WARN_ON(r < 0); - return r < 0 ? r : 0; + if (WARN_ON(r < 0)) { + pm_runtime_put_noidle(&venc->pdev->dev); + return r; + } + return 0; }
static void venc_runtime_put(struct venc_device *venc)
From: Tsuchiya Yuto kitakar@gmail.com
[ Upstream commit 4add4d988f95f47493500a7a19c623827061589b ]
If a reset is performed, but even the reset fails for some reasons (e.g., on Surface devices, the fw reset requires another quirks), cancel_work_sync() hangs in mwifiex_cleanup_pcie().
# firmware went into a bad state [...] [ 1608.281690] mwifiex_pcie 0000:03:00.0: info: shutdown mwifiex... [ 1608.282724] mwifiex_pcie 0000:03:00.0: rx_pending=0, tx_pending=1, cmd_pending=0 [ 1608.292400] mwifiex_pcie 0000:03:00.0: PREP_CMD: card is removed [ 1608.292405] mwifiex_pcie 0000:03:00.0: PREP_CMD: card is removed # reset performed after firmware went into a bad state [ 1609.394320] mwifiex_pcie 0000:03:00.0: WLAN FW already running! Skip FW dnld [ 1609.394335] mwifiex_pcie 0000:03:00.0: WLAN FW is active # but even the reset failed [ 1619.499049] mwifiex_pcie 0000:03:00.0: mwifiex_cmd_timeout_func: Timeout cmd id = 0xfa, act = 0xe000 [ 1619.499094] mwifiex_pcie 0000:03:00.0: num_data_h2c_failure = 0 [ 1619.499103] mwifiex_pcie 0000:03:00.0: num_cmd_h2c_failure = 0 [ 1619.499110] mwifiex_pcie 0000:03:00.0: is_cmd_timedout = 1 [ 1619.499117] mwifiex_pcie 0000:03:00.0: num_tx_timeout = 0 [ 1619.499124] mwifiex_pcie 0000:03:00.0: last_cmd_index = 0 [ 1619.499133] mwifiex_pcie 0000:03:00.0: last_cmd_id: fa 00 07 01 07 01 07 01 07 01 [ 1619.499140] mwifiex_pcie 0000:03:00.0: last_cmd_act: 00 e0 00 00 00 00 00 00 00 00 [ 1619.499147] mwifiex_pcie 0000:03:00.0: last_cmd_resp_index = 3 [ 1619.499155] mwifiex_pcie 0000:03:00.0: last_cmd_resp_id: 07 81 07 81 07 81 07 81 07 81 [ 1619.499162] mwifiex_pcie 0000:03:00.0: last_event_index = 2 [ 1619.499169] mwifiex_pcie 0000:03:00.0: last_event: 58 00 58 00 58 00 58 00 58 00 [ 1619.499177] mwifiex_pcie 0000:03:00.0: data_sent=0 cmd_sent=1 [ 1619.499185] mwifiex_pcie 0000:03:00.0: ps_mode=0 ps_state=0 [ 1619.499215] mwifiex_pcie 0000:03:00.0: info: _mwifiex_fw_dpc: unregister device # mwifiex_pcie_work hang happening [ 1823.233923] INFO: task kworker/3:1:44 blocked for more than 122 seconds. [ 1823.233932] Tainted: G WC OE 5.10.0-rc1-1-mainline #1 [ 1823.233935] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. [ 1823.233940] task:kworker/3:1 state:D stack: 0 pid: 44 ppid: 2 flags:0x00004000 [ 1823.233960] Workqueue: events mwifiex_pcie_work [mwifiex_pcie] [ 1823.233965] Call Trace: [ 1823.233981] __schedule+0x292/0x820 [ 1823.233990] schedule+0x45/0xe0 [ 1823.233995] schedule_timeout+0x11c/0x160 [ 1823.234003] wait_for_completion+0x9e/0x100 [ 1823.234012] __flush_work.isra.0+0x156/0x210 [ 1823.234018] ? flush_workqueue_prep_pwqs+0x130/0x130 [ 1823.234026] __cancel_work_timer+0x11e/0x1a0 [ 1823.234035] mwifiex_cleanup_pcie+0x28/0xd0 [mwifiex_pcie] [ 1823.234049] mwifiex_free_adapter+0x24/0xe0 [mwifiex] [ 1823.234060] _mwifiex_fw_dpc+0x294/0x560 [mwifiex] [ 1823.234074] mwifiex_reinit_sw+0x15d/0x300 [mwifiex] [ 1823.234080] mwifiex_pcie_reset_done+0x50/0x80 [mwifiex_pcie] [ 1823.234087] pci_try_reset_function+0x5c/0x90 [ 1823.234094] process_one_work+0x1d6/0x3a0 [ 1823.234100] worker_thread+0x4d/0x3d0 [ 1823.234107] ? rescuer_thread+0x410/0x410 [ 1823.234112] kthread+0x142/0x160 [ 1823.234117] ? __kthread_bind_mask+0x60/0x60 [ 1823.234124] ret_from_fork+0x22/0x30 [...]
This is a deadlock caused by calling cancel_work_sync() in mwifiex_cleanup_pcie():
- Device resets are done via mwifiex_pcie_card_reset() - which schedules card->work to call mwifiex_pcie_card_reset_work() - which calls pci_try_reset_function(). - This leads to mwifiex_pcie_reset_done() be called on the same workqueue, which in turn calls - mwifiex_reinit_sw() and that calls - _mwifiex_fw_dpc().
The problem is now that _mwifiex_fw_dpc() calls mwifiex_free_adapter() in case firmware initialization fails. That ends up calling mwifiex_cleanup_pcie().
Note that all those calls are still running on the workqueue. So when mwifiex_cleanup_pcie() now calls cancel_work_sync(), it's really waiting on itself to complete, causing a deadlock.
This commit fixes the deadlock by skipping cancel_work_sync() on a reset failure path.
After this commit, when reset fails, the following output is expected to be shown:
kernel: mwifiex_pcie 0000:03:00.0: info: _mwifiex_fw_dpc: unregister device kernel: mwifiex: Failed to bring up adapter: -5 kernel: mwifiex_pcie 0000:03:00.0: reinit failed: -5
To reproduce this issue, for example, try putting the root port of wifi into D3 (replace "00:1d.3" with your setup).
# put into D3 (root port) sudo setpci -v -s 00:1d.3 CAP_PM+4.b=0b
Cc: Maximilian Luz luzmaximilian@gmail.com Signed-off-by: Tsuchiya Yuto kitakar@gmail.com Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20201028142346.18355-1-kitakar@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/marvell/mwifiex/pcie.c | 18 +++++++++++++++++- drivers/net/wireless/marvell/mwifiex/pcie.h | 2 ++ 2 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c index 991b9cc180006..5907b34037c24 100644 --- a/drivers/net/wireless/marvell/mwifiex/pcie.c +++ b/drivers/net/wireless/marvell/mwifiex/pcie.c @@ -381,6 +381,8 @@ static void mwifiex_pcie_reset_prepare(struct pci_dev *pdev) clear_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &card->work_flags); clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &card->work_flags); mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__); + + card->pci_reset_ongoing = true; }
/* @@ -409,6 +411,8 @@ static void mwifiex_pcie_reset_done(struct pci_dev *pdev) dev_err(&pdev->dev, "reinit failed: %d\n", ret); else mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__); + + card->pci_reset_ongoing = false; }
static const struct pci_error_handlers mwifiex_pcie_err_handler = { @@ -3000,7 +3004,19 @@ static void mwifiex_cleanup_pcie(struct mwifiex_adapter *adapter) int ret; u32 fw_status;
- cancel_work_sync(&card->work); + /* Perform the cancel_work_sync() only when we're not resetting + * the card. It's because that function never returns if we're + * in reset path. If we're here when resetting the card, it means + * that we failed to reset the card (reset failure path). + */ + if (!card->pci_reset_ongoing) { + mwifiex_dbg(adapter, MSG, "performing cancel_work_sync()...\n"); + cancel_work_sync(&card->work); + mwifiex_dbg(adapter, MSG, "cancel_work_sync() done\n"); + } else { + mwifiex_dbg(adapter, MSG, + "skipped cancel_work_sync() because we're in card reset failure path\n"); + }
ret = mwifiex_read_reg(adapter, reg->fw_status, &fw_status); if (fw_status == FIRMWARE_READY_PCIE) { diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.h b/drivers/net/wireless/marvell/mwifiex/pcie.h index f7ce9b6db6b41..72d0c01ff3592 100644 --- a/drivers/net/wireless/marvell/mwifiex/pcie.h +++ b/drivers/net/wireless/marvell/mwifiex/pcie.h @@ -391,6 +391,8 @@ struct pcie_service_card { struct mwifiex_msix_context share_irq_ctx; struct work_struct work; unsigned long work_flags; + + bool pci_reset_ongoing; };
static inline int
From: Necip Fazil Yildiran fazilyildiran@gmail.com
[ Upstream commit 09a48cbcd7af9203296938044f1100bb113ce01a ]
When BCM47XX_SSB is enabled and SSB_PCIHOST is disabled, it results in the following Kbuild warning:
WARNING: unmet direct dependencies detected for SSB_B43_PCI_BRIDGE Depends on [n]: SSB [=y] && SSB_PCIHOST [=n] Selected by [y]: - BCM47XX_SSB [=y] && BCM47XX [=y] && PCI [=y]
The reason is that BCM47XX_SSB selects SSB_B43_PCI_BRIDGE without depending on or selecting SSB_PCIHOST while SSB_B43_PCI_BRIDGE depends on SSB_PCIHOST. This can also fail building the kernel as demonstrated in a bug report.
Honor the kconfig dependency to remove unmet direct dependency warnings and avoid any potential build failures.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=210051 Signed-off-by: Necip Fazil Yildiran fazilyildiran@gmail.com Signed-off-by: Thomas Bogendoerfer tsbogend@alpha.franken.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/mips/bcm47xx/Kconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/mips/bcm47xx/Kconfig b/arch/mips/bcm47xx/Kconfig index 29471038d817e..54e79f3047a14 100644 --- a/arch/mips/bcm47xx/Kconfig +++ b/arch/mips/bcm47xx/Kconfig @@ -9,6 +9,7 @@ config BCM47XX_SSB select SSB_DRIVER_MIPS select SSB_DRIVER_EXTIF select SSB_EMBEDDED + select SSB_PCIHOST if PCI select SSB_B43_PCI_BRIDGE if PCI select SSB_DRIVER_PCICORE if PCI select SSB_PCICORE_HOSTMODE if PCI
From: Thierry Reding treding@nvidia.com
[ Upstream commit c9f64d1fc101c64ea2be1b2e562b4395127befc9 ]
When dumping the name and NTP servers advertised by DHCP, a blank line is emitted if either of the lists is empty. This can lead to confusing issues such as the blank line getting flagged as warning. This happens because the blank line is the result of pr_cont("\n") and that may see its level corrupted by some other driver concurrently writing to the console.
Fix this by making sure that the terminating newline is only emitted if at least one entry in the lists was printed before.
Reported-by: Jon Hunter jonathanh@nvidia.com Signed-off-by: Thierry Reding treding@nvidia.com Link: https://lore.kernel.org/r/20201110073757.1284594-1-thierry.reding@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/ipv4/ipconfig.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index 88212615bf4ce..812c69fb8e773 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c @@ -1445,7 +1445,7 @@ static int __init ip_auto_config(void) int retries = CONF_OPEN_RETRIES; #endif int err; - unsigned int i; + unsigned int i, count;
/* Initialise all name servers and NTP servers to NONE (but only if the * "ip=" or "nfsaddrs=" kernel command line parameters weren't decoded, @@ -1573,7 +1573,7 @@ static int __init ip_auto_config(void) if (ic_dev_mtu) pr_cont(", mtu=%d", ic_dev_mtu); /* Name servers (if any): */ - for (i = 0; i < CONF_NAMESERVERS_MAX; i++) { + for (i = 0, count = 0; i < CONF_NAMESERVERS_MAX; i++) { if (ic_nameservers[i] != NONE) { if (i == 0) pr_info(" nameserver%u=%pI4", @@ -1581,12 +1581,14 @@ static int __init ip_auto_config(void) else pr_cont(", nameserver%u=%pI4", i, &ic_nameservers[i]); + + count++; } - if (i + 1 == CONF_NAMESERVERS_MAX) + if ((i + 1 == CONF_NAMESERVERS_MAX) && count > 0) pr_cont("\n"); } /* NTP servers (if any): */ - for (i = 0; i < CONF_NTP_SERVERS_MAX; i++) { + for (i = 0, count = 0; i < CONF_NTP_SERVERS_MAX; i++) { if (ic_ntp_servers[i] != NONE) { if (i == 0) pr_info(" ntpserver%u=%pI4", @@ -1594,8 +1596,10 @@ static int __init ip_auto_config(void) else pr_cont(", ntpserver%u=%pI4", i, &ic_ntp_servers[i]); + + count++; } - if (i + 1 == CONF_NTP_SERVERS_MAX) + if ((i + 1 == CONF_NTP_SERVERS_MAX) && count > 0) pr_cont("\n"); } #endif /* !SILENT */
From: Dinghao Liu dinghao.liu@zju.edu.cn
[ Upstream commit 751341b4d7841e2b76e78eec382c2e119165497f ]
When dbBackSplit() fails, mp should be released to prevent memleak. It's the same when dbJoin() fails.
Signed-off-by: Dinghao Liu dinghao.liu@zju.edu.cn Signed-off-by: Dave Kleikamp dave.kleikamp@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/jfs/jfs_dmap.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c index 49263e220dbcf..071abfc8e3e50 100644 --- a/fs/jfs/jfs_dmap.c +++ b/fs/jfs/jfs_dmap.c @@ -2562,15 +2562,19 @@ dbAdjCtl(struct bmap * bmp, s64 blkno, int newval, int alloc, int level) */ if (oldval == NOFREE) { rc = dbBackSplit((dmtree_t *) dcp, leafno); - if (rc) + if (rc) { + release_metapage(mp); return rc; + } oldval = dcp->stree[ti]; } dbSplit((dmtree_t *) dcp, leafno, dcp->budmin, newval); } else { rc = dbJoin((dmtree_t *) dcp, leafno, newval); - if (rc) + if (rc) { + release_metapage(mp); return rc; + } }
/* check if the root of the current dmap control page changed due
From: Evgeny Novikov novikov@ispras.ru
[ Upstream commit af0321a5be3e5647441eb6b79355beaa592df97a ]
zr364xx_start_readpipe() can fail but callers do not care about that. This can result in various negative consequences. The patch adds missed error handling.
Found by Linux Driver Verification project (linuxtesting.org).
Signed-off-by: Evgeny Novikov novikov@ispras.ru Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/usb/zr364xx/zr364xx.c | 31 ++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-)
diff --git a/drivers/media/usb/zr364xx/zr364xx.c b/drivers/media/usb/zr364xx/zr364xx.c index 501030bb2e7d0..ff2d07fa1c6a6 100644 --- a/drivers/media/usb/zr364xx/zr364xx.c +++ b/drivers/media/usb/zr364xx/zr364xx.c @@ -1349,6 +1349,7 @@ static int zr364xx_board_init(struct zr364xx_camera *cam) { struct zr364xx_pipeinfo *pipe = cam->pipe; unsigned long i; + int err;
DBG("board init: %p\n", cam); memset(pipe, 0, sizeof(*pipe)); @@ -1381,9 +1382,8 @@ static int zr364xx_board_init(struct zr364xx_camera *cam)
if (i == 0) { printk(KERN_INFO KBUILD_MODNAME ": out of memory. Aborting\n"); - kfree(cam->pipe->transfer_buffer); - cam->pipe->transfer_buffer = NULL; - return -ENOMEM; + err = -ENOMEM; + goto err_free; } else cam->buffer.dwFrames = i;
@@ -1398,9 +1398,17 @@ static int zr364xx_board_init(struct zr364xx_camera *cam) /*** end create system buffers ***/
/* start read pipe */ - zr364xx_start_readpipe(cam); + err = zr364xx_start_readpipe(cam); + if (err) + goto err_free; + DBG(": board initialized\n"); return 0; + +err_free: + kfree(cam->pipe->transfer_buffer); + cam->pipe->transfer_buffer = NULL; + return err; }
static int zr364xx_probe(struct usb_interface *intf, @@ -1597,10 +1605,19 @@ static int zr364xx_resume(struct usb_interface *intf) if (!cam->was_streaming) return 0;
- zr364xx_start_readpipe(cam); + res = zr364xx_start_readpipe(cam); + if (res) + return res; + res = zr364xx_prepare(cam); - if (!res) - zr364xx_start_acquire(cam); + if (res) + goto err_prepare; + + zr364xx_start_acquire(cam); + return 0; + +err_prepare: + zr364xx_stop_readpipe(cam); return res; } #endif
From: Hans Verkuil hverkuil-cisco@xs4all.nl
[ Upstream commit e91c255733d9bbb4978a372f44fb5ed689ccdbd1 ]
If a CEC device node is unregistered, then it should be marked as unregistered before waking up any filehandles that are waiting for an event.
This ensures that there is no race condition where an application can call CEC_DQEVENT and have the ioctl return 0 instead of ENODEV.
Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/cec/cec-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/media/cec/cec-core.c b/drivers/media/cec/cec-core.c index b278ab90b3871..1cd2f9d4a6045 100644 --- a/drivers/media/cec/cec-core.c +++ b/drivers/media/cec/cec-core.c @@ -160,12 +160,12 @@ static void cec_devnode_unregister(struct cec_adapter *adap) mutex_unlock(&devnode->lock); return; } + devnode->registered = false; + devnode->unregistered = true;
list_for_each_entry(fh, &devnode->fhs, list) wake_up_interruptible(&fh->wait);
- devnode->registered = false; - devnode->unregistered = true; mutex_unlock(&devnode->lock);
mutex_lock(&adap->lock);
From: Evgeny Novikov novikov@ispras.ru
[ Upstream commit 6651dba2bd838f34cf5a1e84229aaa579b1a94fe ]
isif_probe() invokes iounmap() on error handling paths, but it does not reset the global state. So, later it can invoke iounmap() even when ioremap() fails. This is the case also for isif_remove(). The patch resets the global state after invoking iounmap() to avoid this.
Found by Linux Driver Verification project (linuxtesting.org).
Signed-off-by: Evgeny Novikov novikov@ispras.ru Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/davinci/isif.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/media/platform/davinci/isif.c b/drivers/media/platform/davinci/isif.c index 80fa60a4c4489..d91634d529bb3 100644 --- a/drivers/media/platform/davinci/isif.c +++ b/drivers/media/platform/davinci/isif.c @@ -1084,10 +1084,14 @@ static int isif_probe(struct platform_device *pdev) release_mem_region(res->start, resource_size(res)); i--; fail_nobase_res: - if (isif_cfg.base_addr) + if (isif_cfg.base_addr) { iounmap(isif_cfg.base_addr); - if (isif_cfg.linear_tbl0_addr) + isif_cfg.base_addr = NULL; + } + if (isif_cfg.linear_tbl0_addr) { iounmap(isif_cfg.linear_tbl0_addr); + isif_cfg.linear_tbl0_addr = NULL; + }
while (i >= 0) { res = platform_get_resource(pdev, IORESOURCE_MEM, i); @@ -1105,8 +1109,11 @@ static int isif_remove(struct platform_device *pdev) int i = 0;
iounmap(isif_cfg.base_addr); + isif_cfg.base_addr = NULL; iounmap(isif_cfg.linear_tbl0_addr); + isif_cfg.linear_tbl0_addr = NULL; iounmap(isif_cfg.linear_tbl1_addr); + isif_cfg.linear_tbl1_addr = NULL; while (i < 3) { res = platform_get_resource(pdev, IORESOURCE_MEM, i); if (res)
From: Jan Höppner hoeppner@linux.ibm.com
[ Upstream commit 9e34c8ba91697cb7441805c36d92ab3e695df6e0 ]
During online processing and setting up a DASD device, the configuration data for operational paths is read and validated two times (dasd_eckd_read_conf()). The first time to provide information that are necessary for the LCU setup. A second time after the LCU setup as a device might report different configuration data then.
When the configuration setup for each operational path is being validated, an initial call to dasd_eckd_clear_conf_data() is issued. This call wipes all previously available configuration data and path information for each path. However, the operational path mask is not updated during this process.
As a result, the stored operational path mask might no longer correspond to the operational paths mask reported by the CIO layer, as several paths might be gone between the two dasd_eckd_read_conf() calls.
This inconsistency leads to more severe issues in later path handling changes. Fix this by removing the channel paths from the operational path mask during the dasd_eckd_clear_conf_data() call.
Signed-off-by: Jan Höppner hoeppner@linux.ibm.com Signed-off-by: Stefan Haberland sth@linux.ibm.com Reviewed-by: Stefan Haberland sth@linux.ibm.com Reviewed-by: Cornelia Huck cohuck@redhat.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/s390/block/dasd_eckd.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index a2e34c853ca98..a801ee11843c3 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c @@ -981,6 +981,7 @@ static void dasd_eckd_clear_conf_data(struct dasd_device *device) device->path[i].cssid = 0; device->path[i].ssid = 0; device->path[i].chpid = 0; + dasd_path_notoper(device, i); } }
From: Qinglang Miao miaoqinglang@huawei.com
[ Upstream commit ee50d6e60d9a8e110e984cdd9e788d93eff540ba ]
Add the missing platform_device_unregister() before return from zd1301_frontend_attach in the error handling case when pdev->dev.driver is empty.
There's an error handling route named err_platform_device_unregister, so just reuse it.
Signed-off-by: Qinglang Miao miaoqinglang@huawei.com Signed-off-by: Sean Young sean@mess.org Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/usb/dvb-usb-v2/zd1301.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/usb/dvb-usb-v2/zd1301.c b/drivers/media/usb/dvb-usb-v2/zd1301.c index d1eb4b7bc0519..563d11fb6c18c 100644 --- a/drivers/media/usb/dvb-usb-v2/zd1301.c +++ b/drivers/media/usb/dvb-usb-v2/zd1301.c @@ -159,7 +159,7 @@ static int zd1301_frontend_attach(struct dvb_usb_adapter *adap) } if (!pdev->dev.driver) { ret = -ENODEV; - goto err; + goto err_platform_device_unregister; } if (!try_module_get(pdev->dev.driver->owner)) { ret = -ENODEV;
From: Dinghao Liu dinghao.liu@zju.edu.cn
[ Upstream commit 167faadfcf9339088910e9e85a1b711fcbbef8e9 ]
When device_create() fails, dvbdev and dvbdevfops should be freed just like when dvb_register_media_device() fails.
Signed-off-by: Dinghao Liu dinghao.liu@zju.edu.cn Signed-off-by: Sean Young sean@mess.org Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/dvb-core/dvbdev.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index 04dc2f4bc7aaf..a652b6b1eb1fd 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -541,6 +541,9 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, if (IS_ERR(clsdev)) { pr_err("%s: failed to create device dvb%d.%s%d (%ld)\n", __func__, adap->num, dnames[type], id, PTR_ERR(clsdev)); + dvb_media_device_free(dvbdev); + kfree(dvbdevfops); + kfree(dvbdev); return PTR_ERR(clsdev); } dprintk("DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n",
From: Krzysztof Kozlowski krzk@kernel.org
[ Upstream commit ade8e9d3fb9232ddfb87a4bc641b35b988d9757b ]
Printing kernel pointers is discouraged because they might leak kernel memory layout. This fixes smatch warning:
drivers/mmc/host/tmio_mmc.c:177 tmio_mmc_probe() warn: argument 3 to %08lx specifier is cast from pointer
Reported-by: kernel test robot lkp@intel.com Reported-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Krzysztof Kozlowski krzk@kernel.org Link: https://lore.kernel.org/r/20201116164252.44078-1-krzk@kernel.org Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mmc/host/tmio_mmc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c index 43a2ea5cff24f..9564aaf71442b 100644 --- a/drivers/mmc/host/tmio_mmc.c +++ b/drivers/mmc/host/tmio_mmc.c @@ -114,8 +114,7 @@ static int tmio_mmc_probe(struct platform_device *pdev) if (ret) goto host_remove;
- pr_info("%s at 0x%08lx irq %d\n", mmc_hostname(host->mmc), - (unsigned long)host->ctl, irq); + pr_info("%s at 0x%p irq %d\n", mmc_hostname(host->mmc), host->ctl, irq);
return 0;
From: Youling Tang tangyouling@loongson.cn
[ Upstream commit 3c5902d270edb6ccc3049acfe5d3e96653c87dcd ]
If the clk_register fails, we should free hw before function returns to prevent memleak.
Signed-off-by: Youling Tang tangyouling@loongson.cn Signed-off-by: Tony Lindgren tony@atomide.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c index b64d717bfab6c..45fa2a87d5715 100644 --- a/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c +++ b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c @@ -247,6 +247,12 @@ void omap2xxx_clkt_vps_init(void) hw->hw.init = &init;
clk = clk_register(NULL, &hw->hw); + if (IS_ERR(clk)) { + printk(KERN_ERR "Failed to register clock\n"); + kfree(hw); + return; + } + clkdev_create(clk, "cpufreq_ck", NULL); return; cleanup:
From: Thomas Bogendoerfer tsbogend@alpha.franken.de
[ Upstream commit 411406a8c758d9ad6f908fab3a6cf1d3d89e1d08 ]
MIPS protection bits are setup during runtime so using defines like PAGE_SHARED ignores this runtime changes. Using vm_get_page_prot to get correct page protection fixes this.
Signed-off-by: Thomas Bogendoerfer tsbogend@alpha.franken.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/mips/kvm/mmu.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/mips/kvm/mmu.c b/arch/mips/kvm/mmu.c index 098a7afd4d384..5631d6aee1a70 100644 --- a/arch/mips/kvm/mmu.c +++ b/arch/mips/kvm/mmu.c @@ -1099,6 +1099,7 @@ int kvm_mips_handle_commpage_tlb_fault(unsigned long badvaddr, { kvm_pfn_t pfn; pte_t *ptep; + pgprot_t prot;
ptep = kvm_trap_emul_pte_for_gva(vcpu, badvaddr); if (!ptep) { @@ -1108,7 +1109,8 @@ int kvm_mips_handle_commpage_tlb_fault(unsigned long badvaddr,
pfn = PFN_DOWN(virt_to_phys(vcpu->arch.kseg0_commpage)); /* Also set valid and dirty, so refill handler doesn't have to */ - *ptep = pte_mkyoung(pte_mkdirty(pfn_pte(pfn, PAGE_SHARED))); + prot = vm_get_page_prot(VM_READ|VM_WRITE|VM_SHARED); + *ptep = pte_mkyoung(pte_mkdirty(pfn_pte(pfn, prot)));
/* Invalidate this entry in the TLB, guest kernel ASID only */ kvm_mips_host_tlb_inv(vcpu, badvaddr, false, true);
From: Jaegeuk Kim jaegeuk@google.com
[ Upstream commit b664511297644eac34038df877b3ad7bcaa81913 ]
While running a stress test which enables/disables clkgating, we occasionally hit device timeout. This patch avoids a subtle race condition to address it.
Link: https://lore.kernel.org/r/20201117165839.1643377-3-jaegeuk@kernel.org Reviewed-by: Can Guo cang@codeaurora.org Signed-off-by: Jaegeuk Kim jaegeuk@google.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/ufs/ufshcd.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 7e4e6e982055e..b2fd853f07573 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -1766,19 +1766,19 @@ static ssize_t ufshcd_clkgate_enable_store(struct device *dev, return -EINVAL;
value = !!value; + + spin_lock_irqsave(hba->host->host_lock, flags); if (value == hba->clk_gating.is_enabled) goto out;
- if (value) { - ufshcd_release(hba); - } else { - spin_lock_irqsave(hba->host->host_lock, flags); + if (value) + __ufshcd_release(hba); + else hba->clk_gating.active_reqs++; - spin_unlock_irqrestore(hba->host->host_lock, flags); - }
hba->clk_gating.is_enabled = value; out: + spin_unlock_irqrestore(hba->host->host_lock, flags); return count; }
From: Hans de Goede hdegoede@redhat.com
[ Upstream commit e524f252c42fc4f2bc4a2c3f99fe8659af5576a8 ]
Add OBDA0623 ACPI HID to the acpi_device_id table. This HID is used for the RTL8723BS Bluetooth part on the Acer Switch 10E SW3-016.
BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1665610 Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Marcel Holtmann marcel@holtmann.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/bluetooth/hci_h5.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c index 5a68cd4dd71cb..702aa08c6395f 100644 --- a/drivers/bluetooth/hci_h5.c +++ b/drivers/bluetooth/hci_h5.c @@ -928,6 +928,7 @@ static struct h5_vnd rtl_vnd = { #ifdef CONFIG_ACPI static const struct acpi_device_id h5_acpi_match[] = { #ifdef CONFIG_BT_HCIUART_RTL + { "OBDA0623", (kernel_ulong_t)&rtl_vnd }, { "OBDA8723", (kernel_ulong_t)&rtl_vnd }, #endif { },
From: Takashi Iwai tiwai@suse.de
[ Upstream commit 4974b7950929e4a28d4eaee48e4ad07f168ac132 ]
The PCM trigger callback is atomic, hence we must not call a function like usb_set_interface() there. Calling it from there would lead to a kernel Oops.
Fix it by moving the usb_set_interface() call to set_sync_endpoint().
Also, apply the snd_usb_set_interface_quirk() for consistency, too.
Tested-by: Keith Milner kamilner@superlative.org Tested-by: Dylan Robinson dylan_robinson@motu.com Link: https://lore.kernel.org/r/20201123085347.19667-3-tiwai@suse.de Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- sound/usb/pcm.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-)
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index e4d2fcc89c306..5ff51c2983a19 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c @@ -243,21 +243,6 @@ static int start_endpoints(struct snd_usb_substream *subs) !test_and_set_bit(SUBSTREAM_FLAG_SYNC_EP_STARTED, &subs->flags)) { struct snd_usb_endpoint *ep = subs->sync_endpoint;
- if (subs->data_endpoint->iface != subs->sync_endpoint->iface || - subs->data_endpoint->altsetting != subs->sync_endpoint->altsetting) { - err = usb_set_interface(subs->dev, - subs->sync_endpoint->iface, - subs->sync_endpoint->altsetting); - if (err < 0) { - clear_bit(SUBSTREAM_FLAG_SYNC_EP_STARTED, &subs->flags); - dev_err(&subs->dev->dev, - "%d:%d: cannot set interface (%d)\n", - subs->sync_endpoint->iface, - subs->sync_endpoint->altsetting, err); - return -EIO; - } - } - dev_dbg(&subs->dev->dev, "Starting sync EP @%p\n", ep);
ep->sync_slave = subs->data_endpoint; @@ -501,6 +486,19 @@ static int set_sync_endpoint(struct snd_usb_substream *subs,
subs->data_endpoint->sync_master = subs->sync_endpoint;
+ if (subs->data_endpoint->iface != subs->sync_endpoint->iface || + subs->data_endpoint->altsetting != subs->sync_endpoint->altsetting) { + err = usb_set_interface(subs->dev, + subs->sync_endpoint->iface, + subs->sync_endpoint->altsetting); + if (err < 0) + return err; + dev_dbg(&dev->dev, "setting usb interface %d:%d\n", + subs->sync_endpoint->iface, + subs->sync_endpoint->altsetting); + snd_usb_set_interface_quirk(dev); + } + return 0; }
From: David Howells dhowells@redhat.com
[ Upstream commit d2ae4e918218f543214fbd906db68a6c580efbbb ]
Don't let someone reading a service-side rxrpc-type key get access to the session key that was exchanged with the client. The server application will, at some point, need to be able to read the information in the ticket, but this probably shouldn't include the key material.
Signed-off-by: David Howells dhowells@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- include/keys/rxrpc-type.h | 1 + net/rxrpc/key.c | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/include/keys/rxrpc-type.h b/include/keys/rxrpc-type.h index 8cf829dbf20ec..1cb996dac3238 100644 --- a/include/keys/rxrpc-type.h +++ b/include/keys/rxrpc-type.h @@ -88,6 +88,7 @@ struct rxk5_key { */ struct rxrpc_key_token { u16 security_index; /* RxRPC header security index */ + bool no_leak_key; /* Don't copy the key to userspace */ struct rxrpc_key_token *next; /* the next token in the list */ union { struct rxkad_key *kad; diff --git a/net/rxrpc/key.c b/net/rxrpc/key.c index 2fe2add62a8ed..dd8a12847b712 100644 --- a/net/rxrpc/key.c +++ b/net/rxrpc/key.c @@ -1077,7 +1077,8 @@ static long rxrpc_read(const struct key *key, case RXRPC_SECURITY_RXKAD: toksize += 8 * 4; /* viceid, kvno, key*2, begin, * end, primary, tktlen */ - toksize += RND(token->kad->ticket_len); + if (!token->no_leak_key) + toksize += RND(token->kad->ticket_len); break;
case RXRPC_SECURITY_RXK5: @@ -1181,7 +1182,10 @@ static long rxrpc_read(const struct key *key, ENCODE(token->kad->start); ENCODE(token->kad->expiry); ENCODE(token->kad->primary_flag); - ENCODE_DATA(token->kad->ticket_len, token->kad->ticket); + if (token->no_leak_key) + ENCODE(0); + else + ENCODE_DATA(token->kad->ticket_len, token->kad->ticket); break;
case RXRPC_SECURITY_RXK5:
From: Finn Thain fthain@telegraphics.com.au
[ Upstream commit 03fe6a640a05c5dc04b6bcdddfb981d015e84ed4 ]
It is possible that bus_reset_cleanup() or .eh_abort_handler could be invoked during NCR5380_queuecommand(). If that takes place before the new command is enqueued and after the ST-DMA "lock" has been acquired, the ST-DMA "lock" will be released again. This will result in a lost DMA interrupt and a command timeout. Fix this by excluding EH and interrupt handlers while the new command is enqueued.
Link: https://lore.kernel.org/r/af25163257796b50bb99d4ede4025cea55787b8f.160584719... Tested-by: Michael Schmitz schmitzmic@gmail.com Reviewed-by: Michael Schmitz schmitzmic@gmail.com Signed-off-by: Finn Thain fthain@telegraphics.com.au Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/NCR5380.c | 9 ++++++--- drivers/scsi/atari_scsi.c | 10 +++------- 2 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c index 95a3e3bf2b431..7907694013fc1 100644 --- a/drivers/scsi/NCR5380.c +++ b/drivers/scsi/NCR5380.c @@ -559,11 +559,14 @@ static int NCR5380_queue_command(struct Scsi_Host *instance,
cmd->result = 0;
- if (!NCR5380_acquire_dma_irq(instance)) - return SCSI_MLQUEUE_HOST_BUSY; - spin_lock_irqsave(&hostdata->lock, flags);
+ if (!NCR5380_acquire_dma_irq(instance)) { + spin_unlock_irqrestore(&hostdata->lock, flags); + + return SCSI_MLQUEUE_HOST_BUSY; + } + /* * Insert the cmd into the issue queue. Note that REQUEST SENSE * commands are added to the head of the queue since any command will diff --git a/drivers/scsi/atari_scsi.c b/drivers/scsi/atari_scsi.c index 764c46d7333e6..42f11c8815a7f 100644 --- a/drivers/scsi/atari_scsi.c +++ b/drivers/scsi/atari_scsi.c @@ -376,15 +376,11 @@ static int falcon_get_lock(struct Scsi_Host *instance) if (IS_A_TT()) return 1;
- if (stdma_is_locked_by(scsi_falcon_intr) && - instance->hostt->can_queue > 1) + if (stdma_is_locked_by(scsi_falcon_intr)) return 1;
- if (in_interrupt()) - return stdma_try_lock(scsi_falcon_intr, instance); - - stdma_lock(scsi_falcon_intr, instance); - return 1; + /* stdma_lock() may sleep which means it can't be used here */ + return stdma_try_lock(scsi_falcon_intr, instance); }
#ifndef MODULE
From: Zhen Lei thunder.leizhen@huawei.com
[ Upstream commit 30ea026e33c6dda48849d9fe0d15c1d280a92d53 ]
1. Change node name to match '^serial(@[0-9a-f,]+)*$' 2. Change clock-names to "baudclk", "apb_pclk". Both of them use the same clock.
Signed-off-by: Zhen Lei thunder.leizhen@huawei.com Signed-off-by: Wei Xu xuwei5@hisilicon.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/hip01.dtsi | 24 ++++++++++++------------ arch/arm/boot/dts/hip04-d01.dts | 2 +- arch/arm/boot/dts/hip04.dtsi | 6 +++--- 3 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/arch/arm/boot/dts/hip01.dtsi b/arch/arm/boot/dts/hip01.dtsi index f7cf4f53e764d..db4c813896b96 100644 --- a/arch/arm/boot/dts/hip01.dtsi +++ b/arch/arm/boot/dts/hip01.dtsi @@ -44,41 +44,41 @@ amba { compatible = "simple-bus"; ranges;
- uart0: uart@10001000 { + uart0: serial@10001000 { compatible = "snps,dw-apb-uart"; reg = <0x10001000 0x1000>; - clocks = <&hisi_refclk144mhz>; - clock-names = "apb_pclk"; + clocks = <&hisi_refclk144mhz>, <&hisi_refclk144mhz>; + clock-names = "baudclk", "apb_pclk"; reg-shift = <2>; interrupts = <0 32 4>; status = "disabled"; };
- uart1: uart@10002000 { + uart1: serial@10002000 { compatible = "snps,dw-apb-uart"; reg = <0x10002000 0x1000>; - clocks = <&hisi_refclk144mhz>; - clock-names = "apb_pclk"; + clocks = <&hisi_refclk144mhz>, <&hisi_refclk144mhz>; + clock-names = "baudclk", "apb_pclk"; reg-shift = <2>; interrupts = <0 33 4>; status = "disabled"; };
- uart2: uart@10003000 { + uart2: serial@10003000 { compatible = "snps,dw-apb-uart"; reg = <0x10003000 0x1000>; - clocks = <&hisi_refclk144mhz>; - clock-names = "apb_pclk"; + clocks = <&hisi_refclk144mhz>, <&hisi_refclk144mhz>; + clock-names = "baudclk", "apb_pclk"; reg-shift = <2>; interrupts = <0 34 4>; status = "disabled"; };
- uart3: uart@10006000 { + uart3: serial@10006000 { compatible = "snps,dw-apb-uart"; reg = <0x10006000 0x1000>; - clocks = <&hisi_refclk144mhz>; - clock-names = "apb_pclk"; + clocks = <&hisi_refclk144mhz>, <&hisi_refclk144mhz>; + clock-names = "baudclk", "apb_pclk"; reg-shift = <2>; interrupts = <0 4 4>; status = "disabled"; diff --git a/arch/arm/boot/dts/hip04-d01.dts b/arch/arm/boot/dts/hip04-d01.dts index ca48641d0f48d..9abf9bcf89e41 100644 --- a/arch/arm/boot/dts/hip04-d01.dts +++ b/arch/arm/boot/dts/hip04-d01.dts @@ -25,7 +25,7 @@ memory@0,10000000 { };
soc { - uart0: uart@4007000 { + uart0: serial@4007000 { status = "ok"; }; }; diff --git a/arch/arm/boot/dts/hip04.dtsi b/arch/arm/boot/dts/hip04.dtsi index 44044f2751151..9593a78ccf067 100644 --- a/arch/arm/boot/dts/hip04.dtsi +++ b/arch/arm/boot/dts/hip04.dtsi @@ -253,12 +253,12 @@ arm-pmu { <0 79 4>; };
- uart0: uart@4007000 { + uart0: serial@4007000 { compatible = "snps,dw-apb-uart"; reg = <0x4007000 0x1000>; interrupts = <0 381 4>; - clocks = <&clk_168m>; - clock-names = "uartclk"; + clocks = <&clk_168m>, <&clk_168m>; + clock-names = "baudclk", "apb_pclk"; reg-shift = <2>; status = "disabled"; };
From: Zhen Lei thunder.leizhen@huawei.com
[ Upstream commit e5e225fd495ef1dffc64b81b2094e427f9cc4016 ]
1. Change node name to match '^serial(@[0-9a-f,]+)*$' 2. Change clock-names to "uartclk", "apb_pclk". Both of them use the same clock. 3. Change pinctrl-names to "default", "sleep".
Signed-off-by: Zhen Lei thunder.leizhen@huawei.com Signed-off-by: Wei Xu xuwei5@hisilicon.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/hi3519.dtsi | 20 +++++++++---------- arch/arm/boot/dts/hi3620-hi4511.dts | 20 +++++++++---------- arch/arm/boot/dts/hi3620.dtsi | 30 ++++++++++++++--------------- arch/arm/boot/dts/hisi-x5hd2.dtsi | 30 ++++++++++++++--------------- 4 files changed, 50 insertions(+), 50 deletions(-)
diff --git a/arch/arm/boot/dts/hi3519.dtsi b/arch/arm/boot/dts/hi3519.dtsi index 5729ecfcdc8bf..7df6358081d29 100644 --- a/arch/arm/boot/dts/hi3519.dtsi +++ b/arch/arm/boot/dts/hi3519.dtsi @@ -65,8 +65,8 @@ uart0: serial@12100000 { compatible = "arm,pl011", "arm,primecell"; reg = <0x12100000 0x1000>; interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&crg HI3519_UART0_CLK>; - clock-names = "apb_pclk"; + clocks = <&crg HI3519_UART0_CLK>, <&crg HI3519_UART0_CLK>; + clock-names = "uartclk", "apb_pclk"; status = "disable"; };
@@ -74,8 +74,8 @@ uart1: serial@12101000 { compatible = "arm,pl011", "arm,primecell"; reg = <0x12101000 0x1000>; interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&crg HI3519_UART1_CLK>; - clock-names = "apb_pclk"; + clocks = <&crg HI3519_UART1_CLK>, <&crg HI3519_UART1_CLK>; + clock-names = "uartclk", "apb_pclk"; status = "disable"; };
@@ -83,8 +83,8 @@ uart2: serial@12102000 { compatible = "arm,pl011", "arm,primecell"; reg = <0x12102000 0x1000>; interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&crg HI3519_UART2_CLK>; - clock-names = "apb_pclk"; + clocks = <&crg HI3519_UART2_CLK>, <&crg HI3519_UART2_CLK>; + clock-names = "uartclk", "apb_pclk"; status = "disable"; };
@@ -92,8 +92,8 @@ uart3: serial@12103000 { compatible = "arm,pl011", "arm,primecell"; reg = <0x12103000 0x1000>; interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&crg HI3519_UART3_CLK>; - clock-names = "apb_pclk"; + clocks = <&crg HI3519_UART3_CLK>, <&crg HI3519_UART3_CLK>; + clock-names = "uartclk", "apb_pclk"; status = "disable"; };
@@ -101,8 +101,8 @@ uart4: serial@12104000 { compatible = "arm,pl011", "arm,primecell"; reg = <0x12104000 0x1000>; interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&crg HI3519_UART4_CLK>; - clock-names = "apb_pclk"; + clocks = <&crg HI3519_UART4_CLK>, <&crg HI3519_UART4_CLK>; + clock-names = "uartclk", "apb_pclk"; status = "disable"; };
diff --git a/arch/arm/boot/dts/hi3620-hi4511.dts b/arch/arm/boot/dts/hi3620-hi4511.dts index a579fbf13b5f5..847920004f34c 100644 --- a/arch/arm/boot/dts/hi3620-hi4511.dts +++ b/arch/arm/boot/dts/hi3620-hi4511.dts @@ -30,36 +30,36 @@ dual_timer0: dual_timer@800000 { status = "ok"; };
- uart0: uart@b00000 { /* console */ - pinctrl-names = "default", "idle"; + uart0: serial@b00000 { /* console */ + pinctrl-names = "default", "sleep"; pinctrl-0 = <&uart0_pmx_func &uart0_cfg_func>; pinctrl-1 = <&uart0_pmx_idle &uart0_cfg_idle>; status = "ok"; };
- uart1: uart@b01000 { /* modem */ - pinctrl-names = "default", "idle"; + uart1: serial@b01000 { /* modem */ + pinctrl-names = "default", "sleep"; pinctrl-0 = <&uart1_pmx_func &uart1_cfg_func>; pinctrl-1 = <&uart1_pmx_idle &uart1_cfg_idle>; status = "ok"; };
- uart2: uart@b02000 { /* audience */ - pinctrl-names = "default", "idle"; + uart2: serial@b02000 { /* audience */ + pinctrl-names = "default", "sleep"; pinctrl-0 = <&uart2_pmx_func &uart2_cfg_func>; pinctrl-1 = <&uart2_pmx_idle &uart2_cfg_idle>; status = "ok"; };
- uart3: uart@b03000 { - pinctrl-names = "default", "idle"; + uart3: serial@b03000 { + pinctrl-names = "default", "sleep"; pinctrl-0 = <&uart3_pmx_func &uart3_cfg_func>; pinctrl-1 = <&uart3_pmx_idle &uart3_cfg_idle>; status = "ok"; };
- uart4: uart@b04000 { - pinctrl-names = "default", "idle"; + uart4: serial@b04000 { + pinctrl-names = "default", "sleep"; pinctrl-0 = <&uart4_pmx_func &uart4_cfg_func>; pinctrl-1 = <&uart4_pmx_idle &uart4_cfg_func>; status = "ok"; diff --git a/arch/arm/boot/dts/hi3620.dtsi b/arch/arm/boot/dts/hi3620.dtsi index 541d700945444..9c12f3df78fd7 100644 --- a/arch/arm/boot/dts/hi3620.dtsi +++ b/arch/arm/boot/dts/hi3620.dtsi @@ -165,48 +165,48 @@ timer5: timer@600 { interrupts = <1 13 0xf01>; };
- uart0: uart@b00000 { + uart0: serial@b00000 { compatible = "arm,pl011", "arm,primecell"; reg = <0xb00000 0x1000>; interrupts = <0 20 4>; - clocks = <&clock HI3620_UARTCLK0>; - clock-names = "apb_pclk"; + clocks = <&clock HI3620_UARTCLK0>, <&clock HI3620_UARTCLK0>; + clock-names = "uartclk", "apb_pclk"; status = "disabled"; };
- uart1: uart@b01000 { + uart1: serial@b01000 { compatible = "arm,pl011", "arm,primecell"; reg = <0xb01000 0x1000>; interrupts = <0 21 4>; - clocks = <&clock HI3620_UARTCLK1>; - clock-names = "apb_pclk"; + clocks = <&clock HI3620_UARTCLK1>, <&clock HI3620_UARTCLK1>; + clock-names = "uartclk", "apb_pclk"; status = "disabled"; };
- uart2: uart@b02000 { + uart2: serial@b02000 { compatible = "arm,pl011", "arm,primecell"; reg = <0xb02000 0x1000>; interrupts = <0 22 4>; - clocks = <&clock HI3620_UARTCLK2>; - clock-names = "apb_pclk"; + clocks = <&clock HI3620_UARTCLK2>, <&clock HI3620_UARTCLK2>; + clock-names = "uartclk", "apb_pclk"; status = "disabled"; };
- uart3: uart@b03000 { + uart3: serial@b03000 { compatible = "arm,pl011", "arm,primecell"; reg = <0xb03000 0x1000>; interrupts = <0 23 4>; - clocks = <&clock HI3620_UARTCLK3>; - clock-names = "apb_pclk"; + clocks = <&clock HI3620_UARTCLK3>, <&clock HI3620_UARTCLK3>; + clock-names = "uartclk", "apb_pclk"; status = "disabled"; };
- uart4: uart@b04000 { + uart4: serial@b04000 { compatible = "arm,pl011", "arm,primecell"; reg = <0xb04000 0x1000>; interrupts = <0 24 4>; - clocks = <&clock HI3620_UARTCLK4>; - clock-names = "apb_pclk"; + clocks = <&clock HI3620_UARTCLK4>, <&clock HI3620_UARTCLK4>; + clock-names = "uartclk", "apb_pclk"; status = "disabled"; };
diff --git a/arch/arm/boot/dts/hisi-x5hd2.dtsi b/arch/arm/boot/dts/hisi-x5hd2.dtsi index 50d3f8426da17..3e8395f9c8d8f 100644 --- a/arch/arm/boot/dts/hisi-x5hd2.dtsi +++ b/arch/arm/boot/dts/hisi-x5hd2.dtsi @@ -89,48 +89,48 @@ timer4: timer@a81000 { status = "disabled"; };
- uart0: uart@b00000 { + uart0: serial@b00000 { compatible = "arm,pl011", "arm,primecell"; reg = <0x00b00000 0x1000>; interrupts = <0 49 4>; - clocks = <&clock HIX5HD2_FIXED_83M>; - clock-names = "apb_pclk"; + clocks = <&clock HIX5HD2_FIXED_83M>, <&clock HIX5HD2_FIXED_83M>; + clock-names = "uartclk", "apb_pclk"; status = "disabled"; };
- uart1: uart@6000 { + uart1: serial@6000 { compatible = "arm,pl011", "arm,primecell"; reg = <0x00006000 0x1000>; interrupts = <0 50 4>; - clocks = <&clock HIX5HD2_FIXED_83M>; - clock-names = "apb_pclk"; + clocks = <&clock HIX5HD2_FIXED_83M>, <&clock HIX5HD2_FIXED_83M>; + clock-names = "uartclk", "apb_pclk"; status = "disabled"; };
- uart2: uart@b02000 { + uart2: serial@b02000 { compatible = "arm,pl011", "arm,primecell"; reg = <0x00b02000 0x1000>; interrupts = <0 51 4>; - clocks = <&clock HIX5HD2_FIXED_83M>; - clock-names = "apb_pclk"; + clocks = <&clock HIX5HD2_FIXED_83M>, <&clock HIX5HD2_FIXED_83M>; + clock-names = "uartclk", "apb_pclk"; status = "disabled"; };
- uart3: uart@b03000 { + uart3: serial@b03000 { compatible = "arm,pl011", "arm,primecell"; reg = <0x00b03000 0x1000>; interrupts = <0 52 4>; - clocks = <&clock HIX5HD2_FIXED_83M>; - clock-names = "apb_pclk"; + clocks = <&clock HIX5HD2_FIXED_83M>, <&clock HIX5HD2_FIXED_83M>; + clock-names = "uartclk", "apb_pclk"; status = "disabled"; };
- uart4: uart@b04000 { + uart4: serial@b04000 { compatible = "arm,pl011", "arm,primecell"; reg = <0xb04000 0x1000>; interrupts = <0 53 4>; - clocks = <&clock HIX5HD2_FIXED_83M>; - clock-names = "apb_pclk"; + clocks = <&clock HIX5HD2_FIXED_83M>, <&clock HIX5HD2_FIXED_83M>; + clock-names = "uartclk", "apb_pclk"; status = "disabled"; };
From: Zhen Lei thunder.leizhen@huawei.com
[ Upstream commit 64f5b52554a1de47a53972a47b9b58d8d66ee5aa ]
1. Change node name to match '^usb(@.*)?'
These errors are detected by generic-ehci.yaml and generic-ohci.yaml.
Signed-off-by: Zhen Lei thunder.leizhen@huawei.com Signed-off-by: Wei Xu xuwei5@hisilicon.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/hisi-x5hd2.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/hisi-x5hd2.dtsi b/arch/arm/boot/dts/hisi-x5hd2.dtsi index 3e8395f9c8d8f..d199dbe318a66 100644 --- a/arch/arm/boot/dts/hisi-x5hd2.dtsi +++ b/arch/arm/boot/dts/hisi-x5hd2.dtsi @@ -455,14 +455,14 @@ gmac1: ethernet@1841000 { status = "disabled"; };
- usb0: ehci@1890000 { + usb0: usb@1890000 { compatible = "generic-ehci"; reg = <0x1890000 0x1000>; interrupts = <0 66 4>; clocks = <&clock HIX5HD2_USB_CLK>; };
- usb1: ohci@1880000 { + usb1: usb@1880000 { compatible = "generic-ohci"; reg = <0x1880000 0x1000>; interrupts = <0 67 4>;
From: Zhen Lei thunder.leizhen@huawei.com
[ Upstream commit 8e9e8dd7ce093344a89792deaeb6caedde636dcf ]
Change bus node name from "amba" to "amba-bus" to match '^([a-z][a-z0-9\-]+-bus|bus|soc|axi|ahb|apb)(@[0-9a-f]+)?$'
Signed-off-by: Zhen Lei thunder.leizhen@huawei.com Signed-off-by: Wei Xu xuwei5@hisilicon.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/hi3620-hi4511.dts | 2 +- arch/arm/boot/dts/hi3620.dtsi | 2 +- arch/arm/boot/dts/hip01.dtsi | 2 +- arch/arm/boot/dts/hisi-x5hd2.dtsi | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/arm/boot/dts/hi3620-hi4511.dts b/arch/arm/boot/dts/hi3620-hi4511.dts index 847920004f34c..65df6b8684ffc 100644 --- a/arch/arm/boot/dts/hi3620-hi4511.dts +++ b/arch/arm/boot/dts/hi3620-hi4511.dts @@ -25,7 +25,7 @@ memory { reg = <0x40000000 0x20000000>; };
- amba { + amba-bus { dual_timer0: dual_timer@800000 { status = "ok"; }; diff --git a/arch/arm/boot/dts/hi3620.dtsi b/arch/arm/boot/dts/hi3620.dtsi index 9c12f3df78fd7..40bf9ed299458 100644 --- a/arch/arm/boot/dts/hi3620.dtsi +++ b/arch/arm/boot/dts/hi3620.dtsi @@ -66,7 +66,7 @@ cpu@3 { }; };
- amba { + amba-bus {
#address-cells = <1>; #size-cells = <1>; diff --git a/arch/arm/boot/dts/hip01.dtsi b/arch/arm/boot/dts/hip01.dtsi index db4c813896b96..a1acc7bfc4325 100644 --- a/arch/arm/boot/dts/hip01.dtsi +++ b/arch/arm/boot/dts/hip01.dtsi @@ -38,7 +38,7 @@ soc { interrupt-parent = <&gic>; ranges = <0 0x10000000 0x20000000>;
- amba { + amba-bus { #address-cells = <1>; #size-cells = <1>; compatible = "simple-bus"; diff --git a/arch/arm/boot/dts/hisi-x5hd2.dtsi b/arch/arm/boot/dts/hisi-x5hd2.dtsi index d199dbe318a66..cf98f7adab462 100644 --- a/arch/arm/boot/dts/hisi-x5hd2.dtsi +++ b/arch/arm/boot/dts/hisi-x5hd2.dtsi @@ -33,7 +33,7 @@ soc { interrupt-parent = <&gic>; ranges = <0 0xf8000000 0x8000000>;
- amba { + amba-bus { #address-cells = <1>; #size-cells = <1>; compatible = "simple-bus";
From: Zhen Lei thunder.leizhen@huawei.com
[ Upstream commit 4c246408f0bdbc4100c95a5dad9e0688b4a3cfd0 ]
1. Change clock-names to "sspclk", "apb_pclk". Both of them use the same clock.
Signed-off-by: Zhen Lei thunder.leizhen@huawei.com Signed-off-by: Wei Xu xuwei5@hisilicon.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/hi3519.dtsi | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/arch/arm/boot/dts/hi3519.dtsi b/arch/arm/boot/dts/hi3519.dtsi index 7df6358081d29..9955b6f0a6340 100644 --- a/arch/arm/boot/dts/hi3519.dtsi +++ b/arch/arm/boot/dts/hi3519.dtsi @@ -140,8 +140,8 @@ spi_bus0: spi@12120000 { compatible = "arm,pl022", "arm,primecell"; reg = <0x12120000 0x1000>; interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&crg HI3519_SPI0_CLK>; - clock-names = "apb_pclk"; + clocks = <&crg HI3519_SPI0_CLK>, <&crg HI3519_SPI0_CLK>; + clock-names = "sspclk", "apb_pclk"; num-cs = <1>; #address-cells = <1>; #size-cells = <0>; @@ -152,8 +152,8 @@ spi_bus1: spi@12121000 { compatible = "arm,pl022", "arm,primecell"; reg = <0x12121000 0x1000>; interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&crg HI3519_SPI1_CLK>; - clock-names = "apb_pclk"; + clocks = <&crg HI3519_SPI1_CLK>, <&crg HI3519_SPI1_CLK>; + clock-names = "sspclk", "apb_pclk"; num-cs = <1>; #address-cells = <1>; #size-cells = <0>; @@ -164,8 +164,8 @@ spi_bus2: spi@12122000 { compatible = "arm,pl022", "arm,primecell"; reg = <0x12122000 0x1000>; interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&crg HI3519_SPI2_CLK>; - clock-names = "apb_pclk"; + clocks = <&crg HI3519_SPI2_CLK>, <&crg HI3519_SPI2_CLK>; + clock-names = "sspclk", "apb_pclk"; num-cs = <1>; #address-cells = <1>; #size-cells = <0>;
From: Andy Lutomirski luto@kernel.org
[ Upstream commit 716572b0003ef67a4889bd7d85baf5099c5a0248 ]
Setting GS to 1, 2, or 3 causes a nonsensical part of the IRET microcode to change GS back to zero on a return from kernel mode to user mode. The result is that these tests fail randomly depending on when interrupts happen. Detect when this happens and let the test pass.
Signed-off-by: Andy Lutomirski luto@kernel.org Signed-off-by: Borislav Petkov bp@suse.de Link: https://lkml.kernel.org/r/7567fd44a1d60a9424f25b19a998f12149993b0d.160434659... Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/x86/fsgsbase.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/x86/fsgsbase.c b/tools/testing/selftests/x86/fsgsbase.c index f249e042b3b51..026cd644360f6 100644 --- a/tools/testing/selftests/x86/fsgsbase.c +++ b/tools/testing/selftests/x86/fsgsbase.c @@ -318,8 +318,8 @@ static void set_gs_and_switch_to(unsigned long local, local = read_base(GS);
/* - * Signal delivery seems to mess up weird selectors. Put it - * back. + * Signal delivery is quite likely to change a selector + * of 1, 2, or 3 back to 0 due to IRET being defective. */ asm volatile ("mov %0, %%gs" : : "rm" (force_sel)); } else { @@ -337,6 +337,14 @@ static void set_gs_and_switch_to(unsigned long local, if (base == local && sel_pre_sched == sel_post_sched) { printf("[OK]\tGS/BASE remained 0x%hx/0x%lx\n", sel_pre_sched, local); + } else if (base == local && sel_pre_sched >= 1 && sel_pre_sched <= 3 && + sel_post_sched == 0) { + /* + * IRET is misdesigned and will squash selectors 1, 2, or 3 + * to zero. Don't fail the test just because this happened. + */ + printf("[OK]\tGS/BASE changed from 0x%hx/0x%lx to 0x%hx/0x%lx because IRET is defective\n", + sel_pre_sched, local, sel_post_sched, base); } else { nerrs++; printf("[FAIL]\tGS/BASE changed from 0x%hx/0x%lx to 0x%hx/0x%lx\n",
From: Dmitry Safonov dima@arista.com
[ Upstream commit 01c195de620bb6c3ecda0dbf295fe685d8232e10 ]
bindex can be out of BA window (64): tid 0 seq 2983, start_seq 2915, bindex 68, index 39 tid 0 seq 2984, start_seq 2915, bindex 69, index 40 tid 0 seq 2985, start_seq 2915, bindex 70, index 41 tid 0 seq 2986, start_seq 2915, bindex 71, index 42 tid 0 seq 2879, start_seq 2915, bindex 4060, index 63 tid 0 seq 2854, start_seq 2915, bindex 4035, index 38 tid 0 seq 2795, start_seq 2915, bindex 3976, index 43 tid 0 seq 2989, start_seq 2924, bindex 65, index 45 tid 0 seq 2992, start_seq 2924, bindex 68, index 48 tid 0 seq 2993, start_seq 2924, bindex 69, index 49 tid 0 seq 2994, start_seq 2924, bindex 70, index 50 tid 0 seq 2997, start_seq 2924, bindex 73, index 53 tid 0 seq 2795, start_seq 2941, bindex 3950, index 43 tid 0 seq 2921, start_seq 2941, bindex 4076, index 41 tid 0 seq 2929, start_seq 2941, bindex 4084, index 49 tid 0 seq 3011, start_seq 2946, bindex 65, index 3 tid 0 seq 3012, start_seq 2946, bindex 66, index 4 tid 0 seq 3013, start_seq 2946, bindex 67, index 5
In result isset() will try to dereference something on the stack, causing panics: BUG: unable to handle page fault for address: ffffa742800ed01f #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page PGD 6a4e9067 P4D 6a4e9067 PUD 6a4ec067 PMD 6a4ed067 PTE 0 Oops: 0000 [#1] PREEMPT SMP PTI CPU: 1 PID: 0 Comm: swapper/1 Kdump: loaded Not tainted 5.8.5-arch1-1-kdump #1 Hardware name: Apple Inc. MacBookAir3,1/Mac-942452F5819B1C1B, BIOS MBA31.88Z.0061.B07.1201241641 01/24/12 RIP: 0010:brcms_c_ampdu_dotxstatus+0x343/0x9f0 [brcmsmac] Code: 54 24 20 66 81 e2 ff 0f 41 83 e4 07 89 d1 0f b7 d2 66 c1 e9 03 0f b7 c9 4c 8d 5c 0c 48 49 8b 4d 10 48 8b 79 68 41 57 44 89 e1 <41> 0f b6 33 41 d3 e0 48 c7 c1 38 e0 ea c0 48 83 c7 10 44 21 c6 4c RSP: 0018:ffffa742800ecdd0 EFLAGS: 00010207 RAX: 0000000000000019 RBX: 000000000000000b RCX: 0000000000000006 RDX: 0000000000000ffe RSI: 0000000000000004 RDI: ffff8fc6ad776800 RBP: ffff8fc6855acb00 R08: 0000000000000001 R09: 00000000000005d9 R10: 00000000fffffffe R11: ffffa742800ed01f R12: 0000000000000006 R13: ffff8fc68d75a000 R14: 00000000000005db R15: 0000000000000019 FS: 0000000000000000(0000) GS:ffff8fc6aad00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: ffffa742800ed01f CR3: 000000002480a000 CR4: 00000000000406e0 Call Trace: <IRQ> brcms_c_dpc+0xb46/0x1020 [brcmsmac] ? wlc_intstatus+0xc8/0x180 [brcmsmac] ? __raise_softirq_irqoff+0x1a/0x80 brcms_dpc+0x37/0xd0 [brcmsmac] tasklet_action_common.constprop.0+0x51/0xb0 __do_softirq+0xff/0x340 ? handle_level_irq+0x1a0/0x1a0 asm_call_on_stack+0x12/0x20 </IRQ> do_softirq_own_stack+0x5f/0x80 irq_exit_rcu+0xcb/0x120 common_interrupt+0xd1/0x200 asm_common_interrupt+0x1e/0x40 RIP: 0010:cpuidle_enter_state+0xb3/0x420
Check if the block is within BA window and only then check block's status. Otherwise as Behan wrote: "When I came back to Dublin I was courtmartialed in my absence and sentenced to death in my absence, so I said they could shoot me in my absence."
Also reported: https://bbs.archlinux.org/viewtopic.php?id=258428 https://lore.kernel.org/linux-wireless/87tuwgi92n.fsf@yujinakao.com/
Reported-by: Yuji Nakao contact@yujinakao.com Signed-off-by: Dmitry Safonov dima@arista.com Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20201116030635.645811-1-dima@arista.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../net/wireless/broadcom/brcm80211/brcmsmac/ampdu.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/ampdu.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/ampdu.c index fa391e4eb0989..44f65b8bff9e0 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/ampdu.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/ampdu.c @@ -953,14 +953,19 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, index = TX_SEQ_TO_INDEX(seq); ack_recd = false; if (ba_recd) { + int block_acked; + bindex = MODSUB_POW2(seq, start_seq, SEQNUM_MAX); + if (bindex < AMPDU_TX_BA_MAX_WSIZE) + block_acked = isset(bitmap, bindex); + else + block_acked = 0; brcms_dbg_ht(wlc->hw->d11core, "tid %d seq %d, start_seq %d, bindex %d set %d, index %d\n", tid, seq, start_seq, bindex, - isset(bitmap, bindex), index); + block_acked, index); /* if acked then clear bit and free packet */ - if ((bindex < AMPDU_TX_BA_MAX_WSIZE) - && isset(bitmap, bindex)) { + if (block_acked) { ini->txretry[index] = 0;
/*
From: Stefan Assmann sassmann@kpanic.de
[ Upstream commit 6ec12e1e9404acb27a7434220bbe5f75e7bb2859 ]
When the virtual link state was set to "enable" ethtool would report link speed as 40000Mb/s regardless of the underlying device. Report the correct link speed.
Example from a XXV710 NIC. Before: $ ip link set ens3f0 vf 0 state auto $ ethtool enp8s2 | grep Speed Speed: 25000Mb/s $ ip link set ens3f0 vf 0 state enable $ ethtool enp8s2 | grep Speed Speed: 40000Mb/s After: $ ip link set ens3f0 vf 0 state auto $ ethtool enp8s2 | grep Speed Speed: 25000Mb/s $ ip link set ens3f0 vf 0 state enable $ ethtool enp8s2 | grep Speed Speed: 25000Mb/s
Signed-off-by: Stefan Assmann sassmann@kpanic.de Tested-by: Aaron Brown aaron.f.brown@intel.com Signed-off-by: Tony Nguyen anthony.l.nguyen@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c index dd0c9604d3c92..bf2a1ae428610 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c @@ -58,7 +58,7 @@ static void i40e_vc_notify_vf_link_state(struct i40e_vf *vf) if (vf->link_forced) { pfe.event_data.link_event.link_status = vf->link_up; pfe.event_data.link_event.link_speed = - (vf->link_up ? VIRTCHNL_LINK_SPEED_40GB : 0); + (vf->link_up ? i40e_virtchnl_link_speed(ls->link_speed) : 0); } else { pfe.event_data.link_event.link_status = ls->link_info & I40E_AQ_LINK_UP; @@ -4204,6 +4204,7 @@ int i40e_ndo_set_vf_link_state(struct net_device *netdev, int vf_id, int link) { struct i40e_netdev_priv *np = netdev_priv(netdev); struct i40e_pf *pf = np->vsi->back; + struct i40e_link_status *ls = &pf->hw.phy.link_info; struct virtchnl_pf_event pfe; struct i40e_hw *hw = &pf->hw; struct i40e_vf *vf; @@ -4236,7 +4237,7 @@ int i40e_ndo_set_vf_link_state(struct net_device *netdev, int vf_id, int link) vf->link_forced = true; vf->link_up = true; pfe.event_data.link_event.link_status = true; - pfe.event_data.link_event.link_speed = VIRTCHNL_LINK_SPEED_40GB; + pfe.event_data.link_event.link_speed = i40e_virtchnl_link_speed(ls->link_speed); break; case IFLA_VF_LINK_STATE_DISABLE: vf->link_forced = true;
From: "Andrea Parri (Microsoft)" parri.andrea@gmail.com
[ Upstream commit 206ad34d52a2f1205c84d08c12fc116aad0eb407 ]
Lack of validation could lead to out-of-bound reads and information leaks (cf. usage of nvdev->chan_table[]). Check that the number of allocated sub-channels fits into the expected range.
Suggested-by: Saruhan Karademir skarade@microsoft.com Signed-off-by: Andrea Parri (Microsoft) parri.andrea@gmail.com Reviewed-by: Haiyang Zhang haiyangz@microsoft.com Acked-by: Jakub Kicinski kuba@kernel.org Cc: "David S. Miller" davem@davemloft.net Cc: Jakub Kicinski kuba@kernel.org Cc: netdev@vger.kernel.org Link: https://lore.kernel.org/r/20201118153310.112404-1-parri.andrea@gmail.com Signed-off-by: Wei Liu wei.liu@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/hyperv/rndis_filter.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c index dd91834f841d5..1554d4fa0bb08 100644 --- a/drivers/net/hyperv/rndis_filter.c +++ b/drivers/net/hyperv/rndis_filter.c @@ -1111,6 +1111,11 @@ int rndis_set_subchannel(struct net_device *ndev, return -EIO; }
+ /* Check that number of allocated sub channel is within the expected range */ + if (init_packet->msg.v5_msg.subchn_comp.num_subchannels > nvdev->num_chn - 1) { + netdev_err(ndev, "invalid number of allocated sub channel\n"); + return -EINVAL; + } nvdev->num_chn = 1 + init_packet->msg.v5_msg.subchn_comp.num_subchannels;
From: Nicolin Chen nicoleotsuka@gmail.com
[ Upstream commit d5f583bf8654c231b781096bc1a186065cda72b3 ]
This is used to protect potential race condition at use_count. since probes of client drivers, calling attach_dev(), may run concurrently.
Signed-off-by: Nicolin Chen nicoleotsuka@gmail.com Tested-by: Dmitry Osipenko digetx@gmail.com Reviewed-by: Dmitry Osipenko digetx@gmail.com Acked-by: Thierry Reding treding@nvidia.com Link: https://lore.kernel.org/r/20201125101013.14953-3-nicoleotsuka@gmail.com Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iommu/tegra-smmu.c | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-)
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c index fa0ecb5e63809..63679cce95054 100644 --- a/drivers/iommu/tegra-smmu.c +++ b/drivers/iommu/tegra-smmu.c @@ -252,26 +252,19 @@ static int tegra_smmu_alloc_asid(struct tegra_smmu *smmu, unsigned int *idp) { unsigned long id;
- mutex_lock(&smmu->lock); - id = find_first_zero_bit(smmu->asids, smmu->soc->num_asids); - if (id >= smmu->soc->num_asids) { - mutex_unlock(&smmu->lock); + if (id >= smmu->soc->num_asids) return -ENOSPC; - }
set_bit(id, smmu->asids); *idp = id;
- mutex_unlock(&smmu->lock); return 0; }
static void tegra_smmu_free_asid(struct tegra_smmu *smmu, unsigned int id) { - mutex_lock(&smmu->lock); clear_bit(id, smmu->asids); - mutex_unlock(&smmu->lock); }
static bool tegra_smmu_capable(enum iommu_cap cap) @@ -406,17 +399,21 @@ static int tegra_smmu_as_prepare(struct tegra_smmu *smmu, struct tegra_smmu_as *as) { u32 value; - int err; + int err = 0; + + mutex_lock(&smmu->lock);
if (as->use_count > 0) { as->use_count++; - return 0; + goto unlock; }
as->pd_dma = dma_map_page(smmu->dev, as->pd, 0, SMMU_SIZE_PD, DMA_TO_DEVICE); - if (dma_mapping_error(smmu->dev, as->pd_dma)) - return -ENOMEM; + if (dma_mapping_error(smmu->dev, as->pd_dma)) { + err = -ENOMEM; + goto unlock; + }
/* We can't handle 64-bit DMA addresses */ if (!smmu_dma_addr_valid(smmu, as->pd_dma)) { @@ -439,24 +436,35 @@ static int tegra_smmu_as_prepare(struct tegra_smmu *smmu, as->smmu = smmu; as->use_count++;
+ mutex_unlock(&smmu->lock); + return 0;
err_unmap: dma_unmap_page(smmu->dev, as->pd_dma, SMMU_SIZE_PD, DMA_TO_DEVICE); +unlock: + mutex_unlock(&smmu->lock); + return err; }
static void tegra_smmu_as_unprepare(struct tegra_smmu *smmu, struct tegra_smmu_as *as) { - if (--as->use_count > 0) + mutex_lock(&smmu->lock); + + if (--as->use_count > 0) { + mutex_unlock(&smmu->lock); return; + }
tegra_smmu_free_asid(smmu, as->id);
dma_unmap_page(smmu->dev, as->pd_dma, SMMU_SIZE_PD, DMA_TO_DEVICE);
as->smmu = NULL; + + mutex_unlock(&smmu->lock); }
static int tegra_smmu_attach_dev(struct iommu_domain *domain,
From: Ethan Warth redyoshi49q@gmail.com
[ Upstream commit 1008230f2abeb624f6d71b2e1c424fa4eeebbf84 ]
Mayflash/Dragonrise seems to have yet another device ID for one of their Gamecube controller adapters. Previous to this commit, the adapter registered only one /dev/input/js* device, and all controller inputs (from any controller) were mapped to this device. This patch defines the 1846 USB device ID and enables the HID_QUIRK_MULTI_INPUT quirk for it, which fixes that (with the patch, four /dev/input/js* devices are created, one for each of the four controller ports).
Signed-off-by: Ethan Warth redyoshi49q@gmail.com Tested-by: Wladimir J. van der Laan laanwj@gmail.com Signed-off-by: Jiri Kosina jkosina@suse.cz Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hid/hid-ids.h | 1 + drivers/hid/hid-mf.c | 2 ++ drivers/hid/hid-quirks.c | 2 ++ 3 files changed, 5 insertions(+)
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 6d118da1615d4..1b2ac2bf4598a 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -358,6 +358,7 @@ #define USB_DEVICE_ID_DRAGONRISE_DOLPHINBAR 0x1803 #define USB_DEVICE_ID_DRAGONRISE_GAMECUBE1 0x1843 #define USB_DEVICE_ID_DRAGONRISE_GAMECUBE2 0x1844 +#define USB_DEVICE_ID_DRAGONRISE_GAMECUBE3 0x1846
#define USB_VENDOR_ID_DWAV 0x0eef #define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER 0x0001 diff --git a/drivers/hid/hid-mf.c b/drivers/hid/hid-mf.c index 03f10516131df..a41202d385096 100644 --- a/drivers/hid/hid-mf.c +++ b/drivers/hid/hid-mf.c @@ -161,6 +161,8 @@ static const struct hid_device_id mf_devices[] = { .driver_data = HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE2), .driver_data = 0 }, /* No quirk required */ + { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE3), + .driver_data = HID_QUIRK_MULTI_INPUT }, { } }; MODULE_DEVICE_TABLE(hid, mf_devices); diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c index 10cb42a00fe87..8fbe7b9cd84a3 100644 --- a/drivers/hid/hid-quirks.c +++ b/drivers/hid/hid-quirks.c @@ -74,6 +74,7 @@ static const struct hid_device_id hid_quirks[] = { { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_REDRAGON_SEYMUR2), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE }, { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_DOLPHINBAR), HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE1), HID_QUIRK_MULTI_INPUT }, + { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE3), HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_PS3), HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_WIIU), HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER), HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET }, @@ -498,6 +499,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_DOLPHINBAR) }, { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE1) }, { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE2) }, + { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE3) }, #endif #if IS_ENABLED(CONFIG_HID_MICROSOFT) { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500) },
From: Marc Zyngier maz@kernel.org
[ Upstream commit 776a3c04da9fa144241476f4a0d263899d6cad26 ]
GIC400 has full support for virtualization, and yet the tegra186 DT doesn't expose the GICH/GICV regions (despite exposing the maintenance interrupt that only makes sense for virtualization).
Add the missing regions, based on the hunch that the HW doesn't use the CPU build-in interfaces, but instead the external ones provided by the GIC. KVM's virtual GIC now works with this change.
Signed-off-by: Marc Zyngier maz@kernel.org Signed-off-by: Thierry Reding treding@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/nvidia/tegra186.dtsi | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi b/arch/arm64/boot/dts/nvidia/tegra186.dtsi index b762227f6aa18..1f8db9c128bd7 100644 --- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi @@ -284,7 +284,9 @@ gic: interrupt-controller@3881000 { #interrupt-cells = <3>; interrupt-controller; reg = <0x0 0x03881000 0x0 0x1000>, - <0x0 0x03882000 0x0 0x2000>; + <0x0 0x03882000 0x0 0x2000>, + <0x0 0x03884000 0x0 0x2000>, + <0x0 0x03886000 0x0 0x2000>; interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; interrupt-parent = <&gic>;
From: Thara Gopinath thara.gopinath@linaro.org
[ Upstream commit 1148a9654b5a69611d33e14719251c6ec20f5f2c ]
Partial hash was being copied into the final result buffer without the entire message block processed. Depending on how the end user processes this result buffer, errors vary from result buffer corruption to result buffer poisoing. Fix this issue by ensuring that only the final hash value is copied into the result buffer.
Reviewed-by: Bjorn Andersson bjorn.andersson@linaro.org Signed-off-by: Thara Gopinath thara.gopinath@linaro.org Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/qce/sha.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/crypto/qce/sha.c b/drivers/crypto/qce/sha.c index d8a5db11b7ea1..49e29cb6d5b8d 100644 --- a/drivers/crypto/qce/sha.c +++ b/drivers/crypto/qce/sha.c @@ -55,7 +55,7 @@ static void qce_ahash_done(void *data) dma_unmap_sg(qce->dev, &rctx->result_sg, 1, DMA_FROM_DEVICE);
memcpy(rctx->digest, result->auth_iv, digestsize); - if (req->result) + if (req->result && rctx->last_blk) memcpy(req->result, result->auth_iv, digestsize);
rctx->byte_count[0] = cpu_to_be32(result->auth_byte_count[0]);
From: Mauro Carvalho Chehab mchehab+huawei@kernel.org
[ Upstream commit d0ac1a26ed5943127cb0156148735f5f52a07075 ]
As reported on: https://lore.kernel.org/linux-media/20190627222020.45909-1-willemdebruijn.ke...
if gp8psk_usb_in_op() returns an error, the status var is not initialized. Yet, this var is used later on, in order to identify: - if the device was already started; - if firmware has loaded; - if the LNBf was powered on.
Using status = 0 seems to ensure that everything will be properly powered up.
So, instead of the proposed solution, let's just set status = 0.
Reported-by: syzbot syzkaller@googlegroups.com Reported-by: Willem de Bruijn willemb@google.com Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/usb/dvb-usb/gp8psk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/usb/dvb-usb/gp8psk.c b/drivers/media/usb/dvb-usb/gp8psk.c index 13e96b0aeb0fc..d97eab01cb8c7 100644 --- a/drivers/media/usb/dvb-usb/gp8psk.c +++ b/drivers/media/usb/dvb-usb/gp8psk.c @@ -185,7 +185,7 @@ static int gp8psk_load_bcm4500fw(struct dvb_usb_device *d)
static int gp8psk_power_ctrl(struct dvb_usb_device *d, int onoff) { - u8 status, buf; + u8 status = 0, buf; int gp_product_id = le16_to_cpu(d->udev->descriptor.idProduct);
if (onoff) {
From: Martin Schiller ms@dev.tdt.de
[ Upstream commit 62480b992ba3fb1d7260b11293aed9d6557831c7 ]
1. DTE interface changes immediately to LAPB_STATE_1 and start sending SABM(E).
2. DCE interface sends N2-times DM and changes to LAPB_STATE_1 afterwards if there is no response in the meantime.
Signed-off-by: Martin Schiller ms@dev.tdt.de Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/lapb/lapb_timer.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/net/lapb/lapb_timer.c b/net/lapb/lapb_timer.c index 5d4ae01951b56..51fc09fa41247 100644 --- a/net/lapb/lapb_timer.c +++ b/net/lapb/lapb_timer.c @@ -90,11 +90,18 @@ static void lapb_t1timer_expiry(struct timer_list *t) switch (lapb->state) {
/* - * If we are a DCE, keep going DM .. DM .. DM + * If we are a DCE, send DM up to N2 times, then switch to + * STATE_1 and send SABM(E). */ case LAPB_STATE_0: - if (lapb->mode & LAPB_DCE) + if (lapb->mode & LAPB_DCE && + lapb->n2count != lapb->n2) { + lapb->n2count++; lapb_send_control(lapb, LAPB_DM, LAPB_POLLOFF, LAPB_RESPONSE); + } else { + lapb->state = LAPB_STATE_1; + lapb_establish_data_link(lapb); + } break;
/*
From: Sami Tolvanen samitolvanen@google.com
[ Upstream commit 83321c335dccba262a57378361d63da96b8166d6 ]
e820__mapped_all() is passed as a callback to is_mmconf_reserved(), which expects a function of type:
typedef bool (*check_reserved_t)(u64 start, u64 end, unsigned type);
However, e820__mapped_all() accepts enum e820_type as the last argument and this type mismatch trips indirect call checking with Clang's Control-Flow Integrity (CFI).
As is_mmconf_reserved() only passes enum e820_type values for the type argument, change the typedef and the unused type argument in is_acpi_reserved() to enum e820_type to fix the type mismatch.
Reported-by: Sedat Dilek sedat.dilek@gmail.com Suggested-by: Borislav Petkov bp@alien8.de Signed-off-by: Sami Tolvanen samitolvanen@google.com Signed-off-by: Borislav Petkov bp@suse.de Link: https://lkml.kernel.org/r/20201130193900.456726-1-samitolvanen@google.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/pci/mmconfig-shared.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c index 7389db538c304..8fbb9676e56cf 100644 --- a/arch/x86/pci/mmconfig-shared.c +++ b/arch/x86/pci/mmconfig-shared.c @@ -424,7 +424,7 @@ static acpi_status find_mboard_resource(acpi_handle handle, u32 lvl, return AE_OK; }
-static bool is_acpi_reserved(u64 start, u64 end, unsigned not_used) +static bool is_acpi_reserved(u64 start, u64 end, enum e820_type not_used) { struct resource mcfg_res;
@@ -441,7 +441,7 @@ static bool is_acpi_reserved(u64 start, u64 end, unsigned not_used) return mcfg_res.flags; }
-typedef bool (*check_reserved_t)(u64 start, u64 end, unsigned type); +typedef bool (*check_reserved_t)(u64 start, u64 end, enum e820_type type);
static bool __ref is_mmconf_reserved(check_reserved_t is_reserved, struct pci_mmcfg_region *cfg,
From: Gabriele Paoloni gabriele.paoloni@intel.com
[ Upstream commit 3a866b16fd2360a9c4ebf71cfbf7ebfe968c1409 ]
Right now for LMCE, if no_way_out is set, mce_panic() is called regardless of mca_cfg.tolerant. This is not correct as, if mca_cfg.tolerant = 3, the code should never panic.
Add that check.
[ bp: use local ptr 'cfg'. ]
Signed-off-by: Gabriele Paoloni gabriele.paoloni@intel.com Signed-off-by: Borislav Petkov bp@suse.de Reviewed-by: Tony Luck tony.luck@intel.com Link: https://lkml.kernel.org/r/20201127161819.3106432-4-gabriele.paoloni@intel.co... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/kernel/cpu/mcheck/mce.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index 2a13468f87739..c0f71b731d4b3 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c @@ -1294,7 +1294,7 @@ void do_machine_check(struct pt_regs *regs, long error_code) * to see it will clear it. */ if (lmce) { - if (no_way_out) + if (no_way_out && cfg->tolerant < 3) mce_panic("Fatal local machine check", &m, msg); } else { order = mce_start(&no_way_out);
From: Danielle Ratson danieller@nvidia.com
[ Upstream commit 22ec19f3aee327806c37c9fa1188741574bc6445 ]
Drivers that support bridge offload need to be notified about changes to the bridge's VLAN protocol so that they could react accordingly and potentially veto the change.
Add a new switchdev attribute to communicate the change to drivers.
Signed-off-by: Danielle Ratson danieller@nvidia.com Reviewed-by: Petr Machata petrm@nvidia.com Acked-by: Nikolay Aleksandrov nikolay@nvidia.com Signed-off-by: Ido Schimmel idosch@nvidia.com Reviewed-by: Ivan Vecera ivecera@redhat.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/net/switchdev.h | 2 ++ net/bridge/br_vlan.c | 16 ++++++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/include/net/switchdev.h b/include/net/switchdev.h index d574ce63bf220..59f73b94ec6b2 100644 --- a/include/net/switchdev.h +++ b/include/net/switchdev.h @@ -50,6 +50,7 @@ enum switchdev_attr_id { SWITCHDEV_ATTR_ID_PORT_MROUTER, SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME, SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING, + SWITCHDEV_ATTR_ID_BRIDGE_VLAN_PROTOCOL, SWITCHDEV_ATTR_ID_BRIDGE_MC_DISABLED, SWITCHDEV_ATTR_ID_BRIDGE_MROUTER, }; @@ -68,6 +69,7 @@ struct switchdev_attr { bool mrouter; /* PORT_MROUTER */ clock_t ageing_time; /* BRIDGE_AGEING_TIME */ bool vlan_filtering; /* BRIDGE_VLAN_FILTERING */ + u16 vlan_protocol; /* BRIDGE_VLAN_PROTOCOL */ bool mc_disabled; /* MC_DISABLED */ } u; }; diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c index 5f3950f00f73b..bfc010e887564 100644 --- a/net/bridge/br_vlan.c +++ b/net/bridge/br_vlan.c @@ -764,15 +764,25 @@ EXPORT_SYMBOL_GPL(br_vlan_enabled);
int __br_vlan_set_proto(struct net_bridge *br, __be16 proto) { + struct switchdev_attr attr = { + .orig_dev = br->dev, + .id = SWITCHDEV_ATTR_ID_BRIDGE_VLAN_PROTOCOL, + .flags = SWITCHDEV_F_SKIP_EOPNOTSUPP, + .u.vlan_protocol = ntohs(proto), + }; int err = 0; struct net_bridge_port *p; struct net_bridge_vlan *vlan; struct net_bridge_vlan_group *vg; - __be16 oldproto; + __be16 oldproto = br->vlan_proto;
if (br->vlan_proto == proto) return 0;
+ err = switchdev_port_attr_set(br->dev, &attr); + if (err && err != -EOPNOTSUPP) + return err; + /* Add VLANs for the new proto to the device filter. */ list_for_each_entry(p, &br->port_list, list) { vg = nbp_vlan_group(p); @@ -783,7 +793,6 @@ int __br_vlan_set_proto(struct net_bridge *br, __be16 proto) } }
- oldproto = br->vlan_proto; br->vlan_proto = proto;
recalculate_group_addr(br); @@ -799,6 +808,9 @@ int __br_vlan_set_proto(struct net_bridge *br, __be16 proto) return 0;
err_filt: + attr.u.vlan_protocol = ntohs(oldproto); + switchdev_port_attr_set(br->dev, &attr); + list_for_each_entry_continue_reverse(vlan, &vg->vlan_list, vlist) vlan_vid_del(p->dev, proto, vlan->vid);
From: Daniel Lee Kruse daniel.lee.kruse@protonmail.com
[ Upstream commit dbf0b3a7b719eb3f72cb53c2ce7d34a012a9c261 ]
On AMD Family 15h (Models 30h-3fh), I/O Memory Management Unit RiSC engine sometimes stalls, requiring a reset.
As result, MythTV and w-scan won't scan channels on the AMD Kaveri APU with the Hauppauge QuadHD TV tuner card.
For the solution I added the Input/Output Memory Management Unit's PCI Identity of 0x1423 to the broken_dev_id[] array, which is used by a quirks logic meant to fix similar problems with other AMD chipsets.
Signed-off-by: Daniel Lee Kruse daniel.lee.kruse@protonmail.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/pci/cx23885/cx23885-core.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/media/pci/cx23885/cx23885-core.c b/drivers/media/pci/cx23885/cx23885-core.c index fd5c52b21436b..a1d738969d7b1 100644 --- a/drivers/media/pci/cx23885/cx23885-core.c +++ b/drivers/media/pci/cx23885/cx23885-core.c @@ -2084,6 +2084,10 @@ static struct { * 0x1451 is PCI ID for the IOMMU found on Ryzen */ { PCI_VENDOR_ID_AMD, 0x1451 }, + /* According to sudo lspci -nn, + * 0x1423 is the PCI ID for the IOMMU found on Kaveri + */ + { PCI_VENDOR_ID_AMD, 0x1423 }, };
static bool cx23885_does_need_dma_reset(void)
From: Mingrui Ren jiladahe1997@gmail.com
[ Upstream commit aef1b6a27970607721a618a0b990716ca8dbbf97 ]
As described in Documentation, poll_init() is called by kgdb to initialize hardware which supports both poll_put_char() and poll_get_char().
It's necessary to enable TXEN bit, otherwise, it will cause hardware fault and kernel panic when calling imx_poll_put_char().
Generally, if use /dev/ttymxc0 as kgdb console as well as system console, ttymxc0 is initialized early by system console which does enable TXEN bit.But when use /dev/ttymxc1 as kgbd console, ttymxc1 is only initialized by imx_poll_init() cannot enable the TXEN bit, which will cause kernel panic.
Signed-off-by: Mingrui Ren jiladahe1997@gmail.com Link: https://lore.kernel.org/r/20201202072543.151-1-972931182@qq.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/imx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 7a6e26b12bf64..f3626ee1b06a2 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -1784,7 +1784,7 @@ static int imx_uart_poll_init(struct uart_port *port) ucr1 |= UCR1_UARTEN; ucr1 &= ~(UCR1_TXMPTYEN | UCR1_RTSDEN | UCR1_RRDYEN);
- ucr2 |= UCR2_RXEN; + ucr2 |= UCR2_RXEN | UCR2_TXEN; ucr2 &= ~UCR2_ATEN;
imx_uart_writel(sport, ucr1, UCR1);
From: Jinyang He hejinyang@loongson.cn
[ Upstream commit c0aac3a51cb6364bed367ee3e1a96ed414f386b4 ]
Most platforms do not need to do synci instruction operations when synci_step is 0. But for example, the synci implementation on Loongson64 platform has some changes. On the one hand, it ensures that the memory access instructions have been completed. On the other hand, it guarantees that all prefetch instructions need to be fetched again. And its address information is useless. Thus, only one synci operation is required when synci_step is 0 on Loongson64 platform. I guess that some other platforms have similar implementations on synci, so add judgment conditions in `while` to ensure that at least all platforms perform synci operations once. For those platforms that do not need synci, they just do one more operation similar to nop.
Signed-off-by: Jinyang He hejinyang@loongson.cn Signed-off-by: Thomas Bogendoerfer tsbogend@alpha.franken.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/mips/kernel/relocate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/mips/kernel/relocate.c b/arch/mips/kernel/relocate.c index cbf4cc0b0b6cf..5639c2d5cf0e4 100644 --- a/arch/mips/kernel/relocate.c +++ b/arch/mips/kernel/relocate.c @@ -64,7 +64,7 @@ static void __init sync_icache(void *kbase, unsigned long kernel_length) : "r" (kbase));
kbase += step; - } while (kbase < kend); + } while (step && kbase < kend);
/* Completion barrier */ __sync();
From: Takashi Iwai tiwai@suse.de
[ Upstream commit 88a06d6fd6b369d88cec46c62db3e2604a2f50d5 ]
The runtime->avail field may be accessed concurrently while some places refer to it without taking the runtime->lock spinlock, as detected by KCSAN. Usually this isn't a big problem, but for consistency and safety, we should take the spinlock at each place referencing this field.
Reported-by: syzbot+a23a6f1215c84756577c@syzkaller.appspotmail.com Reported-by: syzbot+3d367d1df1d2b67f5c19@syzkaller.appspotmail.com Link: https://lore.kernel.org/r/20201206083527.21163-1-tiwai@suse.de Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- sound/core/rawmidi.c | 49 +++++++++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 14 deletions(-)
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c index 9b26973fe697a..f4f855d7a7910 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c @@ -87,11 +87,21 @@ static inline unsigned short snd_rawmidi_file_flags(struct file *file) } }
-static inline int snd_rawmidi_ready(struct snd_rawmidi_substream *substream) +static inline bool __snd_rawmidi_ready(struct snd_rawmidi_runtime *runtime) +{ + return runtime->avail >= runtime->avail_min; +} + +static bool snd_rawmidi_ready(struct snd_rawmidi_substream *substream) { struct snd_rawmidi_runtime *runtime = substream->runtime; + unsigned long flags; + bool ready;
- return runtime->avail >= runtime->avail_min; + spin_lock_irqsave(&runtime->lock, flags); + ready = __snd_rawmidi_ready(runtime); + spin_unlock_irqrestore(&runtime->lock, flags); + return ready; }
static inline int snd_rawmidi_ready_append(struct snd_rawmidi_substream *substream, @@ -960,7 +970,7 @@ int snd_rawmidi_receive(struct snd_rawmidi_substream *substream, if (result > 0) { if (runtime->event) schedule_work(&runtime->event_work); - else if (snd_rawmidi_ready(substream)) + else if (__snd_rawmidi_ready(runtime)) wake_up(&runtime->sleep); } spin_unlock_irqrestore(&runtime->lock, flags); @@ -1039,7 +1049,7 @@ static ssize_t snd_rawmidi_read(struct file *file, char __user *buf, size_t coun result = 0; while (count > 0) { spin_lock_irq(&runtime->lock); - while (!snd_rawmidi_ready(substream)) { + while (!__snd_rawmidi_ready(runtime)) { wait_queue_entry_t wait;
if ((file->f_flags & O_NONBLOCK) != 0 || result > 0) { @@ -1056,9 +1066,11 @@ static ssize_t snd_rawmidi_read(struct file *file, char __user *buf, size_t coun return -ENODEV; if (signal_pending(current)) return result > 0 ? result : -ERESTARTSYS; - if (!runtime->avail) - return result > 0 ? result : -EIO; spin_lock_irq(&runtime->lock); + if (!runtime->avail) { + spin_unlock_irq(&runtime->lock); + return result > 0 ? result : -EIO; + } } spin_unlock_irq(&runtime->lock); count1 = snd_rawmidi_kernel_read1(substream, @@ -1196,7 +1208,7 @@ int __snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int coun runtime->avail += count; substream->bytes += count; if (count > 0) { - if (runtime->drain || snd_rawmidi_ready(substream)) + if (runtime->drain || __snd_rawmidi_ready(runtime)) wake_up(&runtime->sleep); } return count; @@ -1363,9 +1375,11 @@ static ssize_t snd_rawmidi_write(struct file *file, const char __user *buf, return -ENODEV; if (signal_pending(current)) return result > 0 ? result : -ERESTARTSYS; - if (!runtime->avail && !timeout) - return result > 0 ? result : -EIO; spin_lock_irq(&runtime->lock); + if (!runtime->avail && !timeout) { + spin_unlock_irq(&runtime->lock); + return result > 0 ? result : -EIO; + } } spin_unlock_irq(&runtime->lock); count1 = snd_rawmidi_kernel_write1(substream, buf, NULL, count); @@ -1445,6 +1459,7 @@ static void snd_rawmidi_proc_info_read(struct snd_info_entry *entry, struct snd_rawmidi *rmidi; struct snd_rawmidi_substream *substream; struct snd_rawmidi_runtime *runtime; + unsigned long buffer_size, avail, xruns;
rmidi = entry->private_data; snd_iprintf(buffer, "%s\n\n", rmidi->name); @@ -1463,13 +1478,16 @@ static void snd_rawmidi_proc_info_read(struct snd_info_entry *entry, " Owner PID : %d\n", pid_vnr(substream->pid)); runtime = substream->runtime; + spin_lock_irq(&runtime->lock); + buffer_size = runtime->buffer_size; + avail = runtime->avail; + spin_unlock_irq(&runtime->lock); snd_iprintf(buffer, " Mode : %s\n" " Buffer size : %lu\n" " Avail : %lu\n", runtime->oss ? "OSS compatible" : "native", - (unsigned long) runtime->buffer_size, - (unsigned long) runtime->avail); + buffer_size, avail); } } } @@ -1487,13 +1505,16 @@ static void snd_rawmidi_proc_info_read(struct snd_info_entry *entry, " Owner PID : %d\n", pid_vnr(substream->pid)); runtime = substream->runtime; + spin_lock_irq(&runtime->lock); + buffer_size = runtime->buffer_size; + avail = runtime->avail; + xruns = runtime->xruns; + spin_unlock_irq(&runtime->lock); snd_iprintf(buffer, " Buffer size : %lu\n" " Avail : %lu\n" " Overruns : %lu\n", - (unsigned long) runtime->buffer_size, - (unsigned long) runtime->avail, - (unsigned long) runtime->xruns); + buffer_size, avail, xruns); } } }
From: Yangtao Li tiny.windzz@gmail.com
[ Upstream commit 3a5e6732a74c44d7c78a764b9a7701135565df8f ]
Use dev_pm_opp_put_prop_name() to avoid mem leak, which free opp_table.
Signed-off-by: Yangtao Li tiny.windzz@gmail.com Signed-off-by: Yangtao Li frank@allwinnertech.com Signed-off-by: Viresh Kumar viresh.kumar@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cpufreq/sti-cpufreq.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/cpufreq/sti-cpufreq.c b/drivers/cpufreq/sti-cpufreq.c index 6b5d241c30b70..01bf9e3a85772 100644 --- a/drivers/cpufreq/sti-cpufreq.c +++ b/drivers/cpufreq/sti-cpufreq.c @@ -226,7 +226,8 @@ static int sti_cpufreq_set_opp_info(void) opp_table = dev_pm_opp_set_supported_hw(dev, version, VERSION_ELEMENTS); if (IS_ERR(opp_table)) { dev_err(dev, "Failed to set supported hardware\n"); - return PTR_ERR(opp_table); + ret = PTR_ERR(opp_table); + goto err_put_prop_name; }
dev_dbg(dev, "pcode: %d major: %d minor: %d substrate: %d\n", @@ -235,6 +236,10 @@ static int sti_cpufreq_set_opp_info(void) version[0], version[1], version[2]);
return 0; + +err_put_prop_name: + dev_pm_opp_put_prop_name(opp_table); + return ret; }
static int sti_cpufreq_fetch_syscon_registers(void)
From: Qinglang Miao miaoqinglang@huawei.com
[ Upstream commit 2f05c19d9ef4f5a42634f83bdb0db596ffc0dd30 ]
Add the missing platform_driver_unregister() before return from mtk_cpufreq_driver_init in the error handling case when failed to register mtk-cpufreq platform device
Signed-off-by: Qinglang Miao miaoqinglang@huawei.com Signed-off-by: Viresh Kumar viresh.kumar@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cpufreq/mediatek-cpufreq.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/cpufreq/mediatek-cpufreq.c b/drivers/cpufreq/mediatek-cpufreq.c index eb8920d398181..83c0c078d3048 100644 --- a/drivers/cpufreq/mediatek-cpufreq.c +++ b/drivers/cpufreq/mediatek-cpufreq.c @@ -586,6 +586,7 @@ static int __init mtk_cpufreq_driver_init(void) pdev = platform_device_register_simple("mtk-cpufreq", -1, NULL, 0); if (IS_ERR(pdev)) { pr_err("failed to register mtk-cpufreq platform device\n"); + platform_driver_unregister(&mtk_cpufreq_platdrv); return PTR_ERR(pdev); }
From: Jacopo Mondi jacopo+renesas@jmondi.org
[ Upstream commit fb25ca37317200fa97ea6b8952e07958f06da7a6 ]
The VNCSI_IFMD register controls the data expansion mode and the channel routing between the CSI-2 receivers and VIN instances.
According to the chip manual revision 2.20 not all fields are available for all the SoCs: - V3M, V3H and E3 do not support the DES1 field has they do not feature a CSI20 receiver. - D3 only supports parallel input, and the whole register shall always be written as 0.
Inspect the per-SoC channel routing table where the available CSI-2 instances are reported and configure VNCSI_IFMD accordingly.
This patch supports this BSP change commit:
https://github.com/renesas-rcar/linux-bsp/commit/f54697394457 ("media: rcar-vin: Fix VnCSI_IFMD register access for r8a77990")
[hverkuil: replace BSP commit ID with BSP URL]
Reviewed-by: Niklas Söderlund niklas.soderlund+renesas@ragnatech.se Suggested-by: Niklas Söderlund niklas.soderlund+renesas@ragnatech.se Signed-off-by: Jacopo Mondi jacopo+renesas@jmondi.org Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/rcar-vin/rcar-dma.c | 25 +++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-)
diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c index 70a8cc433a03f..4fee9132472bb 100644 --- a/drivers/media/platform/rcar-vin/rcar-dma.c +++ b/drivers/media/platform/rcar-vin/rcar-dma.c @@ -1319,7 +1319,9 @@ int rvin_dma_register(struct rvin_dev *vin, int irq) */ int rvin_set_channel_routing(struct rvin_dev *vin, u8 chsel) { - u32 ifmd, vnmc; + const struct rvin_group_route *route; + u32 ifmd = 0; + u32 vnmc; int ret;
ret = pm_runtime_get_sync(vin->dev); @@ -1332,9 +1334,26 @@ int rvin_set_channel_routing(struct rvin_dev *vin, u8 chsel) vnmc = rvin_read(vin, VNMC_REG); rvin_write(vin, vnmc & ~VNMC_VUP, VNMC_REG);
- ifmd = VNCSI_IFMD_DES1 | VNCSI_IFMD_DES0 | VNCSI_IFMD_CSI_CHSEL(chsel); + /* + * Set data expansion mode to "pad with 0s" by inspecting the routes + * table to find out which bit fields are available in the IFMD + * register. IFMD_DES1 controls data expansion mode for CSI20/21, + * IFMD_DES0 controls data expansion mode for CSI40/41. + */ + for (route = vin->info->routes; route->mask; route++) { + if (route->csi == RVIN_CSI20 || route->csi == RVIN_CSI21) + ifmd |= VNCSI_IFMD_DES1; + else + ifmd |= VNCSI_IFMD_DES0;
- rvin_write(vin, ifmd, VNCSI_IFMD_REG); + if (ifmd == (VNCSI_IFMD_DES0 | VNCSI_IFMD_DES1)) + break; + } + + if (ifmd) { + ifmd |= VNCSI_IFMD_CSI_CHSEL(chsel); + rvin_write(vin, ifmd, VNCSI_IFMD_REG); + }
vin_dbg(vin, "Set IFMD 0x%x\n", ifmd);
From: Niklas Söderlund niklas.soderlund+renesas@ragnatech.se
[ Upstream commit 8ae954caf49ac403c177d117fb8e05cbc866aa3c ]
The ch->lock is used to protect the whole enable() and read() of sh_cmt's implementation of struct clocksource. The enable() implementation calls pm_runtime_get_sync() which may result in the clock source to be read() triggering a cyclic lockdep warning for the ch->lock.
The sh_cmt driver implement its own balancing of calls to sh_cmt_{enable,disable}() with flags in sh_cmt_{start,stop}(). It does this to deal with that start and stop are shared between the clock source and clock event providers. While this could be improved on verifying corner cases based on any substantial rework on all devices this driver supports might prove hard.
As a first step separate the PM handling for clock event and clock source. Always put/get the device when enabling/disabling the clock source but keep the clock event logic unchanged. This allows the sh_cmt implementation of struct clocksource to call PM without holding the ch->lock and avoiding the deadlock.
Triggering and log of the deadlock warning,
# echo e60f0000.timer > /sys/devices/system/clocksource/clocksource0/current_clocksource [ 46.948370] ====================================================== [ 46.954730] WARNING: possible circular locking dependency detected [ 46.961094] 5.10.0-rc6-arm64-renesas-00001-g0e5fd7414e8b #36 Not tainted [ 46.967985] ------------------------------------------------------ [ 46.974342] migration/0/11 is trying to acquire lock: [ 46.979543] ffff0000403ed220 (&dev->power.lock){-...}-{2:2}, at: __pm_runtime_resume+0x40/0x74 [ 46.988445] [ 46.988445] but task is already holding lock: [ 46.994441] ffff000040ad0298 (&ch->lock){....}-{2:2}, at: sh_cmt_start+0x28/0x210 [ 47.002173] [ 47.002173] which lock already depends on the new lock. [ 47.002173] [ 47.010573] [ 47.010573] the existing dependency chain (in reverse order) is: [ 47.018262] [ 47.018262] -> #3 (&ch->lock){....}-{2:2}: [ 47.024033] lock_acquire.part.0+0x120/0x330 [ 47.028970] lock_acquire+0x64/0x80 [ 47.033105] _raw_spin_lock_irqsave+0x7c/0xc4 [ 47.038130] sh_cmt_start+0x28/0x210 [ 47.042352] sh_cmt_clocksource_enable+0x28/0x50 [ 47.047644] change_clocksource+0x9c/0x160 [ 47.052402] multi_cpu_stop+0xa4/0x190 [ 47.056799] cpu_stopper_thread+0x90/0x154 [ 47.061557] smpboot_thread_fn+0x244/0x270 [ 47.066310] kthread+0x154/0x160 [ 47.070175] ret_from_fork+0x10/0x20 [ 47.074390] [ 47.074390] -> #2 (tk_core.seq.seqcount){----}-{0:0}: [ 47.081136] lock_acquire.part.0+0x120/0x330 [ 47.086070] lock_acquire+0x64/0x80 [ 47.090203] seqcount_lockdep_reader_access.constprop.0+0x74/0x100 [ 47.097096] ktime_get+0x28/0xa0 [ 47.100960] hrtimer_start_range_ns+0x210/0x2dc [ 47.106164] generic_sched_clock_init+0x70/0x88 [ 47.111364] sched_clock_init+0x40/0x64 [ 47.115853] start_kernel+0x494/0x524 [ 47.120156] [ 47.120156] -> #1 (hrtimer_bases.lock){-.-.}-{2:2}: [ 47.126721] lock_acquire.part.0+0x120/0x330 [ 47.136042] lock_acquire+0x64/0x80 [ 47.144461] _raw_spin_lock_irqsave+0x7c/0xc4 [ 47.153721] hrtimer_start_range_ns+0x68/0x2dc [ 47.163054] rpm_suspend+0x308/0x5dc [ 47.171473] rpm_idle+0xc4/0x2a4 [ 47.179550] pm_runtime_work+0x98/0xc0 [ 47.188209] process_one_work+0x294/0x6f0 [ 47.197142] worker_thread+0x70/0x45c [ 47.205661] kthread+0x154/0x160 [ 47.213673] ret_from_fork+0x10/0x20 [ 47.221957] [ 47.221957] -> #0 (&dev->power.lock){-...}-{2:2}: [ 47.236292] check_noncircular+0x128/0x140 [ 47.244907] __lock_acquire+0x13b0/0x204c [ 47.253332] lock_acquire.part.0+0x120/0x330 [ 47.262033] lock_acquire+0x64/0x80 [ 47.269826] _raw_spin_lock_irqsave+0x7c/0xc4 [ 47.278430] __pm_runtime_resume+0x40/0x74 [ 47.286758] sh_cmt_start+0x84/0x210 [ 47.294537] sh_cmt_clocksource_enable+0x28/0x50 [ 47.303449] change_clocksource+0x9c/0x160 [ 47.311783] multi_cpu_stop+0xa4/0x190 [ 47.319720] cpu_stopper_thread+0x90/0x154 [ 47.328022] smpboot_thread_fn+0x244/0x270 [ 47.336298] kthread+0x154/0x160 [ 47.343708] ret_from_fork+0x10/0x20 [ 47.351445] [ 47.351445] other info that might help us debug this: [ 47.351445] [ 47.370225] Chain exists of: [ 47.370225] &dev->power.lock --> tk_core.seq.seqcount --> &ch->lock [ 47.370225] [ 47.392003] Possible unsafe locking scenario: [ 47.392003] [ 47.405314] CPU0 CPU1 [ 47.413569] ---- ---- [ 47.421768] lock(&ch->lock); [ 47.428425] lock(tk_core.seq.seqcount); [ 47.438701] lock(&ch->lock); [ 47.447930] lock(&dev->power.lock); [ 47.455172] [ 47.455172] *** DEADLOCK *** [ 47.455172] [ 47.471433] 3 locks held by migration/0/11: [ 47.479099] #0: ffff8000113c9278 (timekeeper_lock){-.-.}-{2:2}, at: change_clocksource+0x2c/0x160 [ 47.491834] #1: ffff8000113c8f88 (tk_core.seq.seqcount){----}-{0:0}, at: multi_cpu_stop+0xa4/0x190 [ 47.504727] #2: ffff000040ad0298 (&ch->lock){....}-{2:2}, at: sh_cmt_start+0x28/0x210 [ 47.516541] [ 47.516541] stack backtrace: [ 47.528480] CPU: 0 PID: 11 Comm: migration/0 Not tainted 5.10.0-rc6-arm64-renesas-00001-g0e5fd7414e8b #36 [ 47.542147] Hardware name: Renesas Salvator-X 2nd version board based on r8a77965 (DT) [ 47.554241] Call trace: [ 47.560832] dump_backtrace+0x0/0x190 [ 47.568670] show_stack+0x14/0x30 [ 47.576144] dump_stack+0xe8/0x130 [ 47.583670] print_circular_bug+0x1f0/0x200 [ 47.592015] check_noncircular+0x128/0x140 [ 47.600289] __lock_acquire+0x13b0/0x204c [ 47.608486] lock_acquire.part.0+0x120/0x330 [ 47.616953] lock_acquire+0x64/0x80 [ 47.624582] _raw_spin_lock_irqsave+0x7c/0xc4 [ 47.633114] __pm_runtime_resume+0x40/0x74 [ 47.641371] sh_cmt_start+0x84/0x210 [ 47.649115] sh_cmt_clocksource_enable+0x28/0x50 [ 47.657916] change_clocksource+0x9c/0x160 [ 47.666165] multi_cpu_stop+0xa4/0x190 [ 47.674056] cpu_stopper_thread+0x90/0x154 [ 47.682308] smpboot_thread_fn+0x244/0x270 [ 47.690560] kthread+0x154/0x160 [ 47.697927] ret_from_fork+0x10/0x20 [ 47.708447] clocksource: Switched to clocksource e60f0000.timer
Signed-off-by: Niklas Söderlund niklas.soderlund+renesas@ragnatech.se Reviewed-by: Geert Uytterhoeven geert+renesas@glider.be Signed-off-by: Daniel Lezcano daniel.lezcano@linaro.org Link: https://lore.kernel.org/r/20201205021921.1456190-2-niklas.soderlund+renesas@... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clocksource/sh_cmt.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index cec90a4c79b34..8eeaaaa4b6e32 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c @@ -323,7 +323,6 @@ static int sh_cmt_enable(struct sh_cmt_channel *ch) { int k, ret;
- pm_runtime_get_sync(&ch->cmt->pdev->dev); dev_pm_syscore_device(&ch->cmt->pdev->dev, true);
/* enable clock */ @@ -398,7 +397,6 @@ static void sh_cmt_disable(struct sh_cmt_channel *ch) clk_disable(ch->cmt->clk);
dev_pm_syscore_device(&ch->cmt->pdev->dev, false); - pm_runtime_put(&ch->cmt->pdev->dev); }
/* private flags */ @@ -566,10 +564,16 @@ static int sh_cmt_start(struct sh_cmt_channel *ch, unsigned long flag) int ret = 0; unsigned long flags;
+ if (flag & FLAG_CLOCKSOURCE) + pm_runtime_get_sync(&ch->cmt->pdev->dev); + raw_spin_lock_irqsave(&ch->lock, flags);
- if (!(ch->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE))) + if (!(ch->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE))) { + if (flag & FLAG_CLOCKEVENT) + pm_runtime_get_sync(&ch->cmt->pdev->dev); ret = sh_cmt_enable(ch); + }
if (ret) goto out; @@ -594,14 +598,20 @@ static void sh_cmt_stop(struct sh_cmt_channel *ch, unsigned long flag) f = ch->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE); ch->flags &= ~flag;
- if (f && !(ch->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE))) + if (f && !(ch->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE))) { sh_cmt_disable(ch); + if (flag & FLAG_CLOCKEVENT) + pm_runtime_put(&ch->cmt->pdev->dev); + }
/* adjust the timeout to maximum if only clocksource left */ if ((flag == FLAG_CLOCKEVENT) && (ch->flags & FLAG_CLOCKSOURCE)) __sh_cmt_set_next(ch, ch->max_match_value);
raw_spin_unlock_irqrestore(&ch->lock, flags); + + if (flag & FLAG_CLOCKSOURCE) + pm_runtime_put(&ch->cmt->pdev->dev); }
static struct sh_cmt_channel *cs_to_sh_cmt(struct clocksource *cs)
From: Zhang Xiaohui ruc_zhangxiaohui@163.com
[ Upstream commit 5c455c5ab332773464d02ba17015acdca198f03d ]
mwifiex_cmd_802_11_ad_hoc_start() calls memcpy() without checking the destination size may trigger a buffer overflower, which a local user could use to cause denial of service or the execution of arbitrary code. Fix it by putting the length check before calling memcpy().
Signed-off-by: Zhang Xiaohui ruc_zhangxiaohui@163.com Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20201206084801.26479-1-ruc_zhangxiaohui@163.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/marvell/mwifiex/join.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/net/wireless/marvell/mwifiex/join.c b/drivers/net/wireless/marvell/mwifiex/join.c index d87aeff70cefb..c2cb1e711c06e 100644 --- a/drivers/net/wireless/marvell/mwifiex/join.c +++ b/drivers/net/wireless/marvell/mwifiex/join.c @@ -877,6 +877,8 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,
memset(adhoc_start->ssid, 0, IEEE80211_MAX_SSID_LEN);
+ if (req_ssid->ssid_len > IEEE80211_MAX_SSID_LEN) + req_ssid->ssid_len = IEEE80211_MAX_SSID_LEN; memcpy(adhoc_start->ssid, req_ssid->ssid, req_ssid->ssid_len);
mwifiex_dbg(adapter, INFO, "info: ADHOC_S_CMD: SSID = %s\n",
From: Chris Chiu chiu@endlessos.org
[ Upstream commit 1bea2256aa96a2d7b1b576eb74e29d79edc9bea8 ]
Tha ARCHOS Cesium 140 tablet has problem with the jack-sensing, thus the heaset functions are not working.
Add quirk for this model to select the correct input map, jack-detect options and channel map to enable jack sensing and headset microphone. This device uses IN1 for its internal MIC and JD2 for jack-detect.
Signed-off-by: Chris Chiu chiu@endlessos.org Acked-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Link: https://lore.kernel.org/r/20201208060414.27646-1-chiu@endlessos.org Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/intel/boards/bytcr_rt5640.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c index ec630127ef2f3..f23ddb9f810ae 100644 --- a/sound/soc/intel/boards/bytcr_rt5640.c +++ b/sound/soc/intel/boards/bytcr_rt5640.c @@ -431,6 +431,18 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { BYT_RT5640_SSP0_AIF1 | BYT_RT5640_MCLK_EN), }, + { + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ARCHOS"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ARCHOS 140 CESIUM"), + }, + .driver_data = (void *)(BYT_RT5640_IN1_MAP | + BYT_RT5640_JD_SRC_JD2_IN4N | + BYT_RT5640_OVCD_TH_2000UA | + BYT_RT5640_OVCD_SF_0P75 | + BYT_RT5640_SSP0_AIF1 | + BYT_RT5640_MCLK_EN), + }, { .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
From: Michal Simek michal.simek@xilinx.com
[ Upstream commit 38d1985fdfcf20dc246b552580479ae602f735d1 ]
Fix the leds subnode names to match (^led-[0-9a-f]$|led).
Similar change has been also done by commit 9a19a39ee48b ("arm64: dts: zynqmp: Fix leds subnode name for zcu100/ultra96 v1").
The patch is fixing these warnings: .../zynq-zc702.dt.yaml: leds: 'ds23' does not match any of the regexes: '(^led-[0-9a-f]$|led)', 'pinctrl-[0-9]+'
From schema: .../Documentation/devicetree/bindings/leds/leds-gpio.yaml
.../zynq-zybo-z7.dt.yaml: gpio-leds: 'ld4' does not match any of the regexes: '(^led-[0-9a-f]$|led)', 'pinctrl-[0-9]+'
From schema: .../Documentation/devicetree/bindings/leds/leds-gpio.yaml
Signed-off-by: Michal Simek michal.simek@xilinx.com Link: https://lore.kernel.org/r/607a66783b129294364abf09a6fc8abd241ff4ee.160639710... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/zynq-zc702.dts | 2 +- arch/arm/boot/dts/zynq-zybo-z7.dts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/zynq-zc702.dts b/arch/arm/boot/dts/zynq-zc702.dts index 27cd6cb52f1ba..10a7d0b8cf8b9 100644 --- a/arch/arm/boot/dts/zynq-zc702.dts +++ b/arch/arm/boot/dts/zynq-zc702.dts @@ -49,7 +49,7 @@ sw13 { leds { compatible = "gpio-leds";
- ds23 { + led-ds23 { label = "ds23"; gpios = <&gpio0 10 0>; linux,default-trigger = "heartbeat"; diff --git a/arch/arm/boot/dts/zynq-zybo-z7.dts b/arch/arm/boot/dts/zynq-zybo-z7.dts index 357b78a5c11b1..7b87e10d3953b 100644 --- a/arch/arm/boot/dts/zynq-zybo-z7.dts +++ b/arch/arm/boot/dts/zynq-zybo-z7.dts @@ -25,7 +25,7 @@ chosen { gpio-leds { compatible = "gpio-leds";
- ld4 { + led-ld4 { label = "zynq-zybo-z7:green:ld4"; gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>; };
From: Filipe Manana fdmanana@suse.com
[ Upstream commit 639bd575b7c7fa326abadd2ef3e374a5a24eb40b ]
When logging an inode we may often have to fallback to a full transaction commit, either because a new block group was allocated, there is some case we can not deal with without a transaction commit or some error like an ENOMEM happened. However after we fallback to a transaction commit, we have a time window where we can make the next attempt to log any inode commit the next transaction unnecessarily, adding additional overhead and increasing latency.
A sequence of steps that leads to this issue is the following:
1) The current open transaction has a generation of 1000;
2) A new block group is allocated, and as a consequence we must make sure any attempts to commit a log fallback to a transaction commit, so btrfs_set_log_full_commit() is called from btrfs_make_block_group(). This sets fs_info->last_trans_log_full_commit to 1000;
3) Task A is holding a handle on transaction 1000 and tries to log inode X. Once it gets to start_log_trans(), it calls btrfs_need_log_full_commit() which returns true, since fs_info->last_trans_log_full_commit has a value of 1000. So we end up returning EAGAIN and propagating it up to btrfs_sync_file(), where we commit transaction 1000;
4) The transaction commit task (task A) sets the transaction state to unblocked (TRANS_STATE_UNBLOCKED);
5) Some other task, task B, starts a new transaction with a generation of 1001;
6) Some stuff is done with transaction 1001, some btree blocks COWed, etc;
7) Transaction 1000 has not fully committed yet, we are still writing all the extent buffers it created;
8) Some new task, task C, starts an fsync of inode Y, gets a handle for transaction 1001, and it gets to btrfs_log_inode_parent() which does the following check:
if (fs_info->last_trans_log_full_commit > last_committed) { ret = 1; goto end_no_trans; }
At that point last_trans_log_full_commit has a value of 1000 and last_committed (value of fs_info->last_trans_committed) has a value of 999, since transaction 1000 has not yet committed - it is either still writing out dirty extent buffers, its super blocks or unpinning extents.
As a consequence we return 1, which gets propagated up to btrfs_sync_file(), which will then call btrfs_commit_transaction() for transaction 1001.
As a consequence we have an unnecessary second transaction commit, we previously committed transaction 1000 and now commit transaction 1001 as well, resulting in more overhead and increased latency.
So fix this double transaction commit issue simply by removing that check, because all we need to do is wait for the previous transaction to finish its commit, which we already do later when starting the log transaction at start_log_trans(), because there we acquire the tree_log_mutex lock, which is held by a transaction commit and only released after the transaction commits its super blocks.
Another issue that check has is that it reads last_trans_log_full_commit without using READ_ONCE(), which is incorrect since that member of struct btrfs_fs_info is always updated with WRITE_ONCE() through the helper btrfs_set_log_full_commit().
This double transaction commit issue can actually be triggered quite often in long runs of dbench, since besides the creation of new block groups that force inode logging to fallback to a transaction commit, there are cases where dbench asks to fsync a directory which had files in it that were previously renamed or subdirectories that were removed, resulting in the inode logging to fallback to a full transaction commit.
This patch belongs to a patch set that is comprised of the following patches:
btrfs: fix race causing unnecessary inode logging during link and rename btrfs: fix race that results in logging old extents during a fast fsync btrfs: fix race that causes unnecessary logging of ancestor inodes btrfs: fix race that makes inode logging fallback to transaction commit btrfs: fix race leading to unnecessary transaction commit when logging inode btrfs: do not block inode logging for so long during transaction commit
Performance results are mentioned in the change log of the last patch.
Signed-off-by: Filipe Manana fdmanana@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/btrfs/tree-log.c | 10 ---------- 1 file changed, 10 deletions(-)
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 7b940264c7b9d..865e1e6bf3d9a 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -5616,16 +5616,6 @@ static int btrfs_log_inode_parent(struct btrfs_trans_handle *trans, goto end_no_trans; }
- /* - * The prev transaction commit doesn't complete, we need do - * full commit by ourselves. - */ - if (fs_info->last_trans_log_full_commit > - fs_info->last_trans_committed) { - ret = 1; - goto end_no_trans; - } - if (btrfs_root_refs(&root->root_item) == 0) { ret = 1; goto end_no_trans;
From: Thierry Reding treding@nvidia.com
[ Upstream commit 5b6164d3465fcc13b5679c860c452963443172a7 ]
Device drivers usually depend on the fact that the devices that they control are suspended in the same order that they were probed in. In most cases this is already guaranteed via deferred probe.
However, there's one case where this can still break: if a device is instantiated before a dependency (for example if it appears before the dependency in device tree) but gets probed only after the dependency is probed. Instantiation order would cause the dependency to get probed later, in which case probe of the original device would be deferred and the suspend/resume queue would get reordered properly. However, if the dependency is provided by a built-in driver and the device depending on that driver is controlled by a loadable module, which may only get loaded after the root filesystem has become available, we can be faced with a situation where the probe order ends up being different from the suspend/resume order.
One example where this happens is on Tegra186, where the ACONNECT is listed very early in device tree (sorted by unit-address) and depends on BPMP (listed very late because it has no unit-address) for power domains and clocks/resets. If the ACONNECT driver is built-in, there is no problem because it will be probed before BPMP, causing a probe deferral and that in turn reorders the suspend/resume queue. However, if built as a module, it will end up being probed after BPMP, and therefore not result in a probe deferral, and therefore the suspend/resume queue will stay in the instantiation order. This in turn causes problems because ACONNECT will be resumed before BPMP, which will result in a hang because the ACONNECT's power domain cannot be powered on as long as the BPMP is still suspended.
Fix this by always reordering devices on successful probe. This ensures that the suspend/resume queue is always in probe order and hence meets the natural expectations of drivers vs. their dependencies.
Reported-by: Jonathan Hunter jonathanh@nvidia.com Acked-by: Rafael. J. Wysocki rafael@kernel.org Signed-off-by: Thierry Reding treding@nvidia.com Link: https://lore.kernel.org/r/20201203175756.1405564-1-thierry.reding@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/base/dd.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 4ba9231a6be80..bbb2f72819184 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -334,6 +334,13 @@ static void driver_bound(struct device *dev)
device_pm_check_callbacks(dev);
+ /* + * Reorder successfully probed devices to the end of the device list. + * This ensures that suspend/resume order matches probe order, which + * is usually what drivers rely on. + */ + device_pm_move_to_tail(dev); + /* * Make sure the device is no longer in one of the deferred lists and * kick off retrying all pending devices
From: Anant Thazhemadam anant.thazhemadam@gmail.com
[ Upstream commit 31dcb6c30a26d32650ce134820f27de3c675a45a ]
A kernel-infoleak was reported by syzbot, which was caused because dbells was left uninitialized. Using kzalloc() instead of kmalloc() fixes this issue.
Reported-by: syzbot+a79e17c39564bedf0930@syzkaller.appspotmail.com Tested-by: syzbot+a79e17c39564bedf0930@syzkaller.appspotmail.com Signed-off-by: Anant Thazhemadam anant.thazhemadam@gmail.com Link: https://lore.kernel.org/r/20201122224534.333471-1-anant.thazhemadam@gmail.co... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/misc/vmw_vmci/vmci_context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/misc/vmw_vmci/vmci_context.c b/drivers/misc/vmw_vmci/vmci_context.c index bc089e634a751..26e20b091160a 100644 --- a/drivers/misc/vmw_vmci/vmci_context.c +++ b/drivers/misc/vmw_vmci/vmci_context.c @@ -751,7 +751,7 @@ static int vmci_ctx_get_chkpt_doorbells(struct vmci_ctx *context, return VMCI_ERROR_MORE_DATA; }
- dbells = kmalloc(data_size, GFP_ATOMIC); + dbells = kzalloc(data_size, GFP_ATOMIC); if (!dbells) return VMCI_ERROR_NO_MEM;
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit df72138de4bc4e85e427aabc60fc51be6cc57fc7 ]
Validate the maximum RX descriptor length against the size of the buffers we gave the device - if it doesn't fit then the hardware messed up.
Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Luca Coelho luciano.coelho@intel.com Link: https://lore.kernel.org/r/iwlwifi.20201209231352.6378fb435cc0.Ib07485f3dc599... Signed-off-by: Luca Coelho luciano.coelho@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c index 80a1a50f5da51..ebdb143b1b5a1 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c @@ -1256,6 +1256,13 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans,
len = iwl_rx_packet_len(pkt); len += sizeof(u32); /* account for status word */ + + offset += ALIGN(len, FH_RSCSR_FRAME_ALIGN); + + /* check that what the device tells us made sense */ + if (offset > max_len) + break; + trace_iwlwifi_dev_rx(trans->dev, trans, pkt, len); trace_iwlwifi_dev_rx_data(trans->dev, trans, pkt, len);
@@ -1313,7 +1320,6 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans, page_stolen |= rxcb._page_stolen; if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) break; - offset += ALIGN(len, FH_RSCSR_FRAME_ALIGN); }
/* page was stolen from us -- free our reference */
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit 152fdc0f698896708f9d7889a4ba4da6944b74f7 ]
If we get an error, no longer consider the firmware to be in IWL_TRANS_FW_ALIVE state.
Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Luca Coelho luciano.coelho@intel.com Link: https://lore.kernel.org/r/iwlwifi.20201209231352.a9d01e79c1c7.Ib2deb076b392f... Signed-off-by: Luca Coelho luciano.coelho@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/intel/iwlwifi/iwl-trans.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h index 0b8cf7f3af933..675fffb39b729 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h @@ -1189,8 +1189,10 @@ static inline void iwl_trans_fw_error(struct iwl_trans *trans) return;
/* prevent double restarts due to the same erroneous FW */ - if (!test_and_set_bit(STATUS_FW_ERROR, &trans->status)) + if (!test_and_set_bit(STATUS_FW_ERROR, &trans->status)) { iwl_op_mode_nic_error(trans->op_mode); + trans->state = IWL_TRANS_NO_FW; + } }
/*****************************************************
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit b2ed841ed070ccbe908016537f429a3a8f0221bf ]
Start tracking not just if the firmware is dead or alive, but also if it's starting.
Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Luca Coelho luciano.coelho@intel.com Link: https://lore.kernel.org/r/iwlwifi.20201209231352.33e50d40b688.I8bbd41af7aa5e... Signed-off-by: Luca Coelho luciano.coelho@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/intel/iwlwifi/iwl-trans.h | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h index 675fffb39b729..b633555b0f58e 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h @@ -619,12 +619,14 @@ struct iwl_trans_ops { /** * enum iwl_trans_state - state of the transport layer * - * @IWL_TRANS_NO_FW: no fw has sent an alive response - * @IWL_TRANS_FW_ALIVE: a fw has sent an alive response + * @IWL_TRANS_NO_FW: firmware wasn't started yet, or crashed + * @IWL_TRANS_FW_STARTED: FW was started, but not alive yet + * @IWL_TRANS_FW_ALIVE: FW has sent an alive response */ enum iwl_trans_state { - IWL_TRANS_NO_FW = 0, - IWL_TRANS_FW_ALIVE = 1, + IWL_TRANS_NO_FW, + IWL_TRANS_FW_STARTED, + IWL_TRANS_FW_ALIVE, };
/** @@ -833,12 +835,18 @@ static inline int iwl_trans_start_fw(struct iwl_trans *trans, const struct fw_img *fw, bool run_in_rfkill) { + int ret; + might_sleep();
WARN_ON_ONCE(!trans->rx_mpdu_cmd);
clear_bit(STATUS_FW_ERROR, &trans->status); - return trans->ops->start_fw(trans, fw, run_in_rfkill); + ret = trans->ops->start_fw(trans, fw, run_in_rfkill); + if (ret == 0) + trans->state = IWL_TRANS_FW_STARTED; + + return ret; }
static inline void _iwl_trans_stop_device(struct iwl_trans *trans,
From: Kyle Tso kyletso@google.com
[ Upstream commit 301a633c1b5b2caa4c4b97a83270d4a1d60c53bf ]
PD rev3.0 8.3.3.16.3.6 PE_PRS_SRC_SNK_Wait_Source_on State The Policy Enging Shall transition to the ErrorRecovery state when the PSSourceOnTimer times out ...
Cc: Guenter Roeck linux@roeck-us.net Cc: Heikki Krogerus heikki.krogerus@linux.intel.com Cc: Badhri Jagan Sridharan badhri@google.com Reviewed-by: Guenter Roeck linux@roeck-us.net Acked-by: Heikki Krogerus heikki.krogerus@linux.intel.com Signed-off-by: Kyle Tso kyletso@google.com Signed-off-by: Will McVicker willmcvicker@google.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Link: https://lore.kernel.org/r/20201210160521.3417426-4-gregkh@linuxfoundation.or... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/typec/tcpm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/usb/typec/tcpm.c b/drivers/usb/typec/tcpm.c index af41d4dce3adb..9c901e3b17472 100644 --- a/drivers/usb/typec/tcpm.c +++ b/drivers/usb/typec/tcpm.c @@ -3455,7 +3455,7 @@ static void run_state_machine(struct tcpm_port *port) tcpm_set_state(port, ERROR_RECOVERY, 0); break; } - tcpm_set_state_cond(port, SNK_UNATTACHED, PD_T_PS_SOURCE_ON); + tcpm_set_state(port, ERROR_RECOVERY, PD_T_PS_SOURCE_ON); break; case PR_SWAP_SRC_SNK_SINK_ON: tcpm_set_state(port, SNK_STARTUP, 0);
From: Kyle Tso kyletso@google.com
[ Upstream commit fe79d5de77204dd946cfad76a9bec23354b1a500 ]
TCPM state machine needs 20-25ms to enter the ErrorRecovery state after tPSSourceOn timer timeouts. Change the timer from max 480ms to 450ms to ensure that the timer complies with the Spec. In order to keep the flexibility for other usecases using tPSSourceOn, add another timer only for PR_SWAP.
Cc: Guenter Roeck linux@roeck-us.net Cc: Heikki Krogerus heikki.krogerus@linux.intel.com Cc: Badhri Jagan Sridharan badhri@google.com Reviewed-by: Guenter Roeck linux@roeck-us.net Acked-by: Heikki Krogerus heikki.krogerus@linux.intel.com Signed-off-by: Kyle Tso kyletso@google.com Signed-off-by: Will McVicker willmcvicker@google.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Link: https://lore.kernel.org/r/20201210160521.3417426-5-gregkh@linuxfoundation.or... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/typec/tcpm.c | 2 +- include/linux/usb/pd.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/typec/tcpm.c b/drivers/usb/typec/tcpm.c index 9c901e3b17472..95e4725eaf3f7 100644 --- a/drivers/usb/typec/tcpm.c +++ b/drivers/usb/typec/tcpm.c @@ -3455,7 +3455,7 @@ static void run_state_machine(struct tcpm_port *port) tcpm_set_state(port, ERROR_RECOVERY, 0); break; } - tcpm_set_state(port, ERROR_RECOVERY, PD_T_PS_SOURCE_ON); + tcpm_set_state(port, ERROR_RECOVERY, PD_T_PS_SOURCE_ON_PRS); break; case PR_SWAP_SRC_SNK_SINK_ON: tcpm_set_state(port, SNK_STARTUP, 0); diff --git a/include/linux/usb/pd.h b/include/linux/usb/pd.h index bdf4c88d2aa0a..1a29a7351fbed 100644 --- a/include/linux/usb/pd.h +++ b/include/linux/usb/pd.h @@ -441,6 +441,7 @@ static inline unsigned int rdo_max_power(u32 rdo) #define PD_T_DRP_SRC 30 #define PD_T_PS_SOURCE_OFF 920 #define PD_T_PS_SOURCE_ON 480 +#define PD_T_PS_SOURCE_ON_PRS 450 /* 390 - 480ms */ #define PD_T_PS_HARD_RESET 30 #define PD_T_SRC_RECOVER 760 #define PD_T_SRC_RECOVER_MAX 1000
From: Avraham Stern avraham.stern@intel.com
[ Upstream commit c837cbad40d949feaff86734d637c7602ae0b56b ]
Accept a scan request with the duration set even if the driver does not support setting the scan dwell. The duration can be used as a hint to the driver, but the driver may use its internal logic for setting the scan dwell.
Signed-off-by: Avraham Stern avraham.stern@intel.com Signed-off-by: Luca Coelho luciano.coelho@intel.com Link: https://lore.kernel.org/r/iwlwifi.20201129172929.9491a12f9226.Ia9c5b24fcefc5... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/wireless/nl80211.c | 6 ------ 1 file changed, 6 deletions(-)
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index fbc8875502c3e..a5383de7a796d 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -7289,12 +7289,6 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) }
if (info->attrs[NL80211_ATTR_MEASUREMENT_DURATION]) { - if (!wiphy_ext_feature_isset(wiphy, - NL80211_EXT_FEATURE_SET_SCAN_DWELL)) { - err = -EOPNOTSUPP; - goto out_free; - } - request->duration = nla_get_u16(info->attrs[NL80211_ATTR_MEASUREMENT_DURATION]); request->duration_mandatory =
From: Ilan Peer ilan.peer@intel.com
[ Upstream commit beee246951571cc5452176f3dbfe9aa5a10ba2b9 ]
When custom regulatory was set, only the channels setting was updated, but the regulatory domain was not saved. Fix it by saving it.
Signed-off-by: Ilan Peer ilan.peer@intel.com Signed-off-by: Luca Coelho luciano.coelho@intel.com Link: https://lore.kernel.org/r/iwlwifi.20201129172929.290fa5c5568a.Ic5732aa64de6e... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/wireless/reg.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index c7825b951f725..3427e6e4ce41c 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -2332,6 +2332,7 @@ static void handle_band_custom(struct wiphy *wiphy, void wiphy_apply_custom_regulatory(struct wiphy *wiphy, const struct ieee80211_regdomain *regd) { + const struct ieee80211_regdomain *new_regd, *tmp; enum nl80211_band band; unsigned int bands_set = 0;
@@ -2351,6 +2352,13 @@ void wiphy_apply_custom_regulatory(struct wiphy *wiphy, * on your device's supported bands. */ WARN_ON(!bands_set); + new_regd = reg_copy_regd(regd); + if (IS_ERR(new_regd)) + return; + + tmp = get_wiphy_regdom(wiphy); + rcu_assign_pointer(wiphy->regd, new_regd); + rcu_free_regdom(tmp); } EXPORT_SYMBOL(wiphy_apply_custom_regulatory);
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit 3660944a37ce73890292571f44f04891834f9044 ]
If the AP advertises a band switch during CSA, we will not have the right information to continue working with it, since it will likely (have to) change its capabilities and we don't track any capability changes at all. Additionally, we store e.g. supported rates per band, and that information would become invalid.
Since this is a fringe scenario, just disconnect explicitly.
Signed-off-by: Luca Coelho luciano.coelho@intel.com Link: https://lore.kernel.org/r/iwlwifi.20201129172929.0e2327107c06.I461adb07704e0... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/mac80211/mlme.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index c53a332f7d65a..eb711475cb140 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1261,6 +1261,17 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, if (res) return;
+ if (sdata->vif.bss_conf.chandef.chan->band != + csa_ie.chandef.chan->band) { + sdata_info(sdata, + "AP %pM switches to different band (%d MHz, width:%d, CF1/2: %d/%d MHz), disconnecting\n", + ifmgd->associated->bssid, + csa_ie.chandef.chan->center_freq, + csa_ie.chandef.width, csa_ie.chandef.center_freq1, + csa_ie.chandef.center_freq2); + goto lock_and_drop_connection; + } + if (!cfg80211_chandef_usable(local->hw.wiphy, &csa_ie.chandef, IEEE80211_CHAN_DISABLED)) { sdata_info(sdata, @@ -1269,9 +1280,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, csa_ie.chandef.chan->center_freq, csa_ie.chandef.width, csa_ie.chandef.center_freq1, csa_ie.chandef.center_freq2); - ieee80211_queue_work(&local->hw, - &ifmgd->csa_connection_drop_work); - return; + goto lock_and_drop_connection; }
if (cfg80211_chandef_identical(&csa_ie.chandef, @@ -1361,6 +1370,9 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, TU_TO_EXP_TIME((csa_ie.count - 1) * cbss->beacon_interval)); return; + lock_and_drop_connection: + mutex_lock(&local->mtx); + mutex_lock(&local->chanctx_mtx); drop_connection: /* * This is just so that the disconnect flow will know that
From: Avraham Stern avraham.stern@intel.com
[ Upstream commit da3882331a55ba8c8eda0cfc077ad3b88c257e22 ]
Add support for calculating the Rx timestamp for HE frames. Since now all frame types are supported, allow setting the Rx timestamp regardless of the frame type.
Signed-off-by: Avraham Stern avraham.stern@intel.com Signed-off-by: Luca Coelho luciano.coelho@intel.com Link: https://lore.kernel.org/r/iwlwifi.20201206145305.4786559af475.Ia54486bb0a12e... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/mac80211/ieee80211_i.h | 9 ++---- net/mac80211/util.c | 66 +++++++++++++++++++++++++++++++++++++- 2 files changed, 67 insertions(+), 8 deletions(-)
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index a879d8071712b..43edb903be693 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1529,13 +1529,8 @@ ieee80211_have_rx_timestamp(struct ieee80211_rx_status *status) { WARN_ON_ONCE(status->flag & RX_FLAG_MACTIME_START && status->flag & RX_FLAG_MACTIME_END); - if (status->flag & (RX_FLAG_MACTIME_START | RX_FLAG_MACTIME_END)) - return true; - /* can't handle non-legacy preamble yet */ - if (status->flag & RX_FLAG_MACTIME_PLCP_START && - status->encoding == RX_ENC_LEGACY) - return true; - return false; + return !!(status->flag & (RX_FLAG_MACTIME_START | RX_FLAG_MACTIME_END | + RX_FLAG_MACTIME_PLCP_START)); }
void ieee80211_vif_inc_num_mcast(struct ieee80211_sub_if_data *sdata); diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 7fa9871b1db9f..0234fae673ec2 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -2897,6 +2897,7 @@ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local, u64 ts = status->mactime; struct rate_info ri; u16 rate; + u8 n_ltf;
if (WARN_ON(!ieee80211_have_rx_timestamp(status))) return 0; @@ -2907,11 +2908,58 @@ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local,
/* Fill cfg80211 rate info */ switch (status->encoding) { + case RX_ENC_HE: + ri.flags |= RATE_INFO_FLAGS_HE_MCS; + ri.mcs = status->rate_idx; + ri.nss = status->nss; + ri.he_ru_alloc = status->he_ru; + if (status->enc_flags & RX_ENC_FLAG_SHORT_GI) + ri.flags |= RATE_INFO_FLAGS_SHORT_GI; + + /* + * See P802.11ax_D6.0, section 27.3.4 for + * VHT PPDU format. + */ + if (status->flag & RX_FLAG_MACTIME_PLCP_START) { + mpdu_offset += 2; + ts += 36; + + /* + * TODO: + * For HE MU PPDU, add the HE-SIG-B. + * For HE ER PPDU, add 8us for the HE-SIG-A. + * For HE TB PPDU, add 4us for the HE-STF. + * Add the HE-LTF durations - variable. + */ + } + + break; case RX_ENC_HT: ri.mcs = status->rate_idx; ri.flags |= RATE_INFO_FLAGS_MCS; if (status->enc_flags & RX_ENC_FLAG_SHORT_GI) ri.flags |= RATE_INFO_FLAGS_SHORT_GI; + + /* + * See P802.11REVmd_D3.0, section 19.3.2 for + * HT PPDU format. + */ + if (status->flag & RX_FLAG_MACTIME_PLCP_START) { + mpdu_offset += 2; + if (status->enc_flags & RX_ENC_FLAG_HT_GF) + ts += 24; + else + ts += 32; + + /* + * Add Data HT-LTFs per streams + * TODO: add Extension HT-LTFs, 4us per LTF + */ + n_ltf = ((ri.mcs >> 3) & 3) + 1; + n_ltf = n_ltf == 3 ? 4 : n_ltf; + ts += n_ltf * 4; + } + break; case RX_ENC_VHT: ri.flags |= RATE_INFO_FLAGS_VHT_MCS; @@ -2919,6 +2967,23 @@ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local, ri.nss = status->nss; if (status->enc_flags & RX_ENC_FLAG_SHORT_GI) ri.flags |= RATE_INFO_FLAGS_SHORT_GI; + + /* + * See P802.11REVmd_D3.0, section 21.3.2 for + * VHT PPDU format. + */ + if (status->flag & RX_FLAG_MACTIME_PLCP_START) { + mpdu_offset += 2; + ts += 36; + + /* + * Add VHT-LTFs per streams + */ + n_ltf = (ri.nss != 1) && (ri.nss % 2) ? + ri.nss + 1 : ri.nss; + ts += 4 * n_ltf; + } + break; default: WARN_ON(1); @@ -2942,7 +3007,6 @@ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local, ri.legacy = DIV_ROUND_UP(bitrate, (1 << shift));
if (status->flag & RX_FLAG_MACTIME_PLCP_START) { - /* TODO: handle HT/VHT preambles */ if (status->band == NL80211_BAND_5GHZ) { ts += 20 << shift; mpdu_offset += 2;
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit db8ebd06ccb87b7bea8e50f3d4ba5dc0142093b8 ]
Use the appropriate bitfield helpers for encoding and decoding the capability field in the BA session action frames instead of open-coding the shifts/masks.
Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Luca Coelho luciano.coelho@intel.com Link: https://lore.kernel.org/r/iwlwifi.20201206145305.0c46e5097cc0.I06e75706770c4... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/mac80211/agg-rx.c | 8 ++++---- net/mac80211/agg-tx.c | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index 6a4f154c99f6b..dd2e421bda6e5 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c @@ -216,10 +216,10 @@ static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *d mgmt->u.action.u.addba_resp.action_code = WLAN_ACTION_ADDBA_RESP; mgmt->u.action.u.addba_resp.dialog_token = dialog_token;
- capab = (u16)(amsdu << 0); /* bit 0 A-MSDU support */ - capab |= (u16)(policy << 1); /* bit 1 aggregation policy */ - capab |= (u16)(tid << 2); /* bit 5:2 TID number */ - capab |= (u16)(buf_size << 6); /* bit 15:6 max size of aggregation */ + capab = u16_encode_bits(amsdu, IEEE80211_ADDBA_PARAM_AMSDU_MASK); + capab |= u16_encode_bits(policy, IEEE80211_ADDBA_PARAM_POLICY_MASK); + capab |= u16_encode_bits(tid, IEEE80211_ADDBA_PARAM_TID_MASK); + capab |= u16_encode_bits(buf_size, IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK);
mgmt->u.action.u.addba_resp.capab = cpu_to_le16(capab); mgmt->u.action.u.addba_resp.timeout = cpu_to_le16(timeout); diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index 54821fb1a960d..4cb7695a208ac 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c @@ -98,10 +98,10 @@ static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata, mgmt->u.action.u.addba_req.action_code = WLAN_ACTION_ADDBA_REQ;
mgmt->u.action.u.addba_req.dialog_token = dialog_token; - capab = (u16)(1 << 0); /* bit 0 A-MSDU support */ - capab |= (u16)(1 << 1); /* bit 1 aggregation policy */ - capab |= (u16)(tid << 2); /* bit 5:2 TID number */ - capab |= (u16)(agg_size << 6); /* bit 15:6 max size of aggergation */ + capab = IEEE80211_ADDBA_PARAM_AMSDU_MASK; + capab |= IEEE80211_ADDBA_PARAM_POLICY_MASK; + capab |= u16_encode_bits(tid, IEEE80211_ADDBA_PARAM_TID_MASK); + capab |= u16_encode_bits(agg_size, IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK);
mgmt->u.action.u.addba_req.capab = cpu_to_le16(capab);
@@ -924,8 +924,8 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab); amsdu = capab & IEEE80211_ADDBA_PARAM_AMSDU_MASK; - tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2; - buf_size = (capab & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) >> 6; + tid = u16_get_bits(capab, IEEE80211_ADDBA_PARAM_TID_MASK); + buf_size = u16_get_bits(capab, IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK); buf_size = min(buf_size, local->hw.max_tx_aggregation_subframes);
txq = sta->sta.txq[tid];
From: Ilan Peer ilan.peer@intel.com
[ Upstream commit bbf31e88df2f5da20ce613c340ce508d732046b3 ]
When calculating the minimal channel width for channel context, the current operation Rx channel width of a station was used and not the overall channel width capability of the station, i.e., both for Tx and Rx.
Fix ieee80211_get_sta_bw() to use the maximal channel width the station is capable. While at it make the function static.
Signed-off-by: Ilan Peer ilan.peer@intel.com Signed-off-by: Luca Coelho luciano.coelho@intel.com Link: https://lore.kernel.org/r/iwlwifi.20201206145305.4387040b99a0.I74bcf19238f75... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/mac80211/chan.c | 10 ++++++---- net/mac80211/ieee80211_i.h | 1 - 2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index d9558ffb8acf7..b58813568c9ff 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c @@ -190,11 +190,13 @@ ieee80211_find_reservation_chanctx(struct ieee80211_local *local, return NULL; }
-enum nl80211_chan_width ieee80211_get_sta_bw(struct ieee80211_sta *sta) +static enum nl80211_chan_width ieee80211_get_sta_bw(struct sta_info *sta) { - switch (sta->bandwidth) { + enum ieee80211_sta_rx_bandwidth width = ieee80211_sta_cap_rx_bw(sta); + + switch (width) { case IEEE80211_STA_RX_BW_20: - if (sta->ht_cap.ht_supported) + if (sta->sta.ht_cap.ht_supported) return NL80211_CHAN_WIDTH_20; else return NL80211_CHAN_WIDTH_20_NOHT; @@ -231,7 +233,7 @@ ieee80211_get_max_required_bw(struct ieee80211_sub_if_data *sdata) !(sta->sdata->bss && sta->sdata->bss == sdata->bss)) continue;
- max_bw = max(max_bw, ieee80211_get_sta_bw(&sta->sta)); + max_bw = max(max_bw, ieee80211_get_sta_bw(sta)); } rcu_read_unlock();
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 43edb903be693..285a541549aaa 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -2165,7 +2165,6 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata, enum ieee80211_chanctx_mode chanmode, u8 radar_detect); int ieee80211_max_num_channels(struct ieee80211_local *local); -enum nl80211_chan_width ieee80211_get_sta_bw(struct ieee80211_sta *sta); void ieee80211_recalc_chanctx_chantype(struct ieee80211_local *local, struct ieee80211_chanctx *ctx);
From: Emmanuel Grumbach emmanuel.grumbach@intel.com
[ Upstream commit 189a164d0fc6c59a22c4486d641d0a0a0d33387a ]
I hit a bug in which we started a CSA with an action frame, but the AP changed its mind and didn't change the beacon. The CSA wasn't cancelled and we lost the connection.
The beacons were ignored because they never changed: they never contained any CSA IE. Because they never changed, the CRC of the beacon didn't change either which made us ignore the beacons instead of processing them.
Now what happens is: 1) beacon has CRC X and it is valid. No CSA IE in the beacon 2) as long as beacon's CRC X, don't process their IEs 3) rx action frame with CSA 4) invalidate the beacon's CRC 5) rx beacon, CRC is still X, but now it is invalid 6) process the beacon, detect there is no CSA IE 7) abort CSA
Signed-off-by: Emmanuel Grumbach emmanuel.grumbach@intel.com Signed-off-by: Luca Coelho luciano.coelho@intel.com Link: https://lore.kernel.org/r/iwlwifi.20201206145305.83470b8407e6.I739b907598001... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/mac80211/mlme.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index eb711475cb140..75d791bceb1c6 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1347,6 +1347,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, sdata->csa_chandef = csa_ie.chandef; sdata->csa_block_tx = csa_ie.mode; ifmgd->csa_ignored_same_chan = false; + ifmgd->beacon_crc_valid = false;
if (sdata->csa_block_tx) ieee80211_stop_vif_queues(local, sdata,
From: Ilan Peer ilan.peer@intel.com
[ Upstream commit 44b72ca8163b8cf94384a11fdec716f5478411bf ]
A channel change or a channel bandwidth change can impact the rate control logic. However, the rate control logic was not updated before/after such a change, which might result in unexpected behavior.
Fix this by updating the stations rate control logic when the corresponding channel context changes.
Signed-off-by: Ilan Peer ilan.peer@intel.com Signed-off-by: Luca Coelho luciano.coelho@intel.com Link: https://lore.kernel.org/r/iwlwifi.20201206145305.600d967fe3c9.I48305f25cfcc9... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/mac80211/chan.c | 61 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+)
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index b58813568c9ff..cc693ec0777d5 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c @@ -8,6 +8,7 @@ #include <net/cfg80211.h> #include "ieee80211_i.h" #include "driver-ops.h" +#include "rate.h"
static int ieee80211_chanctx_num_assigned(struct ieee80211_local *local, struct ieee80211_chanctx *ctx) @@ -339,10 +340,42 @@ void ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local, drv_change_chanctx(local, ctx, IEEE80211_CHANCTX_CHANGE_MIN_WIDTH); }
+static void ieee80211_chan_bw_change(struct ieee80211_local *local, + struct ieee80211_chanctx *ctx) +{ + struct sta_info *sta; + struct ieee80211_supported_band *sband = + local->hw.wiphy->bands[ctx->conf.def.chan->band]; + + rcu_read_lock(); + list_for_each_entry_rcu(sta, &local->sta_list, + list) { + enum ieee80211_sta_rx_bandwidth new_sta_bw; + + if (!ieee80211_sdata_running(sta->sdata)) + continue; + + if (rcu_access_pointer(sta->sdata->vif.chanctx_conf) != + &ctx->conf) + continue; + + new_sta_bw = ieee80211_sta_cur_vht_bw(sta); + if (new_sta_bw == sta->sta.bandwidth) + continue; + + sta->sta.bandwidth = new_sta_bw; + rate_control_rate_update(local, sband, sta, + IEEE80211_RC_BW_CHANGED); + } + rcu_read_unlock(); +} + static void ieee80211_change_chanctx(struct ieee80211_local *local, struct ieee80211_chanctx *ctx, const struct cfg80211_chan_def *chandef) { + enum nl80211_chan_width width; + if (cfg80211_chandef_identical(&ctx->conf.def, chandef)) { ieee80211_recalc_chanctx_min_def(local, ctx); return; @@ -350,7 +383,25 @@ static void ieee80211_change_chanctx(struct ieee80211_local *local,
WARN_ON(!cfg80211_chandef_compatible(&ctx->conf.def, chandef));
+ width = ctx->conf.def.width; ctx->conf.def = *chandef; + + /* expected to handle only 20/40/80/160 channel widths */ + switch (chandef->width) { + case NL80211_CHAN_WIDTH_20_NOHT: + case NL80211_CHAN_WIDTH_20: + case NL80211_CHAN_WIDTH_40: + case NL80211_CHAN_WIDTH_80: + case NL80211_CHAN_WIDTH_80P80: + case NL80211_CHAN_WIDTH_160: + break; + default: + WARN_ON(1); + } + + if (chandef->width < width) + ieee80211_chan_bw_change(local, ctx); + drv_change_chanctx(local, ctx, IEEE80211_CHANCTX_CHANGE_WIDTH); ieee80211_recalc_chanctx_min_def(local, ctx);
@@ -358,6 +409,9 @@ static void ieee80211_change_chanctx(struct ieee80211_local *local, local->_oper_chandef = *chandef; ieee80211_hw_config(local, 0); } + + if (chandef->width > width) + ieee80211_chan_bw_change(local, ctx); }
static struct ieee80211_chanctx * @@ -1040,8 +1094,14 @@ ieee80211_vif_use_reserved_reassign(struct ieee80211_sub_if_data *sdata) if (WARN_ON(!chandef)) return -EINVAL;
+ if (old_ctx->conf.def.width > new_ctx->conf.def.width) + ieee80211_chan_bw_change(local, new_ctx); + ieee80211_change_chanctx(local, new_ctx, chandef);
+ if (old_ctx->conf.def.width < new_ctx->conf.def.width) + ieee80211_chan_bw_change(local, new_ctx); + vif_chsw[0].vif = &sdata->vif; vif_chsw[0].old_ctx = &old_ctx->conf; vif_chsw[0].new_ctx = &new_ctx->conf; @@ -1432,6 +1492,7 @@ static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local) ieee80211_recalc_smps_chanctx(local, ctx); ieee80211_recalc_radar_chanctx(local, ctx); ieee80211_recalc_chanctx_min_def(local, ctx); + ieee80211_chan_bw_change(local, ctx);
list_for_each_entry_safe(sdata, sdata_tmp, &ctx->reserved_vifs, reserved_chanctx_list) {
From: Kai Vehmanen kai.vehmanen@linux.intel.com
[ Upstream commit 46c3bbd9827952f92e250fa6ee30a797a4c4e17e ]
The check for infoframe transmit status in hdmi_infoframe_uptodate() makes the assumption that packet buffer index is set to zero.
Align code with specification and explicitly set the index before AC_VERB_GET_HDMI_DIP_XMIT. The packet index setting affects both DIP-Data and DIP-XmitCtrl verbs.
There are no known cases where the old implementation has caused driver to work incorrectly. This change is purely based on code review against the specification (HDA spec rev1.0a).
Signed-off-by: Kai Vehmanen kai.vehmanen@linux.intel.com Link: https://lore.kernel.org/r/20201211131613.3271407-1-kai.vehmanen@linux.intel.... Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- sound/pci/hda/patch_hdmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index f86b9b0a0607e..88d7b10375221 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -642,11 +642,11 @@ static bool hdmi_infoframe_uptodate(struct hda_codec *codec, hda_nid_t pin_nid, u8 val; int i;
+ hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0); if (snd_hda_codec_read(codec, pin_nid, 0, AC_VERB_GET_HDMI_DIP_XMIT, 0) != AC_DIPXMIT_BEST) return false;
- hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0); for (i = 0; i < size; i++) { val = snd_hda_codec_read(codec, pin_nid, 0, AC_VERB_GET_HDMI_DIP_DATA, 0);
From: Sebastian Andrzej Siewior bigeasy@linutronix.de
[ Upstream commit b5f32555567cfe0a5d5dbe7c1e85ebe37b3f545a ]
In v2.4.0-test2pre2 mmc_ioctl_cdrom_read_data() was extended by issuing a MODE_SELECT opcode to change the sector size and READ_10 to perform the actual read if the READ_CD opcode is not support. The sector size is never changed back to the previous value of 2048 bytes which is however denoted by the comment for version 3.09 of the cdrom.c file.
Use cdrom_switch_blocksize() to change the sector size only if the requested size deviates from 2048. Change it back to 2048 after the read operation if a change was mode.
Link: https://lkml.kernel.org/r/20201204164803.ovwurzs3257em2rp@linutronix.de Signed-off-by: Sebastian Andrzej Siewior bigeasy@linutronix.de Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cdrom/cdrom.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index d3947388a3ef3..f379fb00f1773 100644 --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c @@ -2996,13 +2996,15 @@ static noinline int mmc_ioctl_cdrom_read_data(struct cdrom_device_info *cdi, * SCSI-II devices are not required to support * READ_CD, so let's try switching block size */ - /* FIXME: switch back again... */ - ret = cdrom_switch_blocksize(cdi, blocksize); - if (ret) - goto out; + if (blocksize != CD_FRAMESIZE) { + ret = cdrom_switch_blocksize(cdi, blocksize); + if (ret) + goto out; + } cgc->sshdr = NULL; ret = cdrom_read_cd(cdi, cgc, lba, blocksize, 1); - ret |= cdrom_switch_blocksize(cdi, blocksize); + if (blocksize != CD_FRAMESIZE) + ret |= cdrom_switch_blocksize(cdi, CD_FRAMESIZE); } if (!ret && copy_to_user(arg, cgc->buffer, blocksize)) ret = -EFAULT;
From: Bjorn Helgaas bhelgaas@google.com
[ Upstream commit 059983790a4c963d92943e55a61fca55be427d55 ]
Add function 1 DMA alias quirk for Marvell 88SS9215 PCIe SSD Controller.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=42679#c135 Link: https://lore.kernel.org/r/20201110220516.697934-1-helgaas@kernel.org Reported-by: John Smith LK7S2ED64JHGLKj75shg9klejHWG49h5hk@protonmail.com Signed-off-by: Bjorn Helgaas bhelgaas@google.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/quirks.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index af2149632102a..70f05595da60d 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -3961,6 +3961,9 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9183, /* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c46 */ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x91a0, quirk_dma_func1_alias); +/* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c135 */ +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9215, + quirk_dma_func1_alias); /* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c127 */ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9220, quirk_dma_func1_alias);
linux-stable-mirror@lists.linaro.org