5.15.58-rc1 review
Subsystems (3)
Greg Kroah-Hartman
maintainerPATCH 135/201 mm/mempolicy: fix uninit-value in mpol_rebind_policy()
In reply to Greg Kroah-HartmanFrom: Wang Cheng <[email protected]>
commit 018160ad314d75b1409129b2247b614a9f35894c upstream.
mpol_set_nodemask()(mm/mempolicy.c) does not set up nodemask when pol->mode is MPOL_LOCAL. Check pol->mode before access pol->w.cpuset_mems_allowed in mpol_rebind_policy()(mm/mempolicy.c).
BUG: KMSAN: uninit-value in mpol_rebind_policy mm/mempolicy.c:352 [inline] BUG: KMSAN: uninit-value in mpol_rebind_task+0x2ac/0x2c0 mm/mempolicy.c:368 mpol_rebind_policy mm/mempolicy.c:352 [inline] mpol_rebind_task+0x2ac/0x2c0 mm/mempolicy.c:368 cpuset_change_task_nodemask kernel/cgroup/cpuset.c:1711 [inline] cpuset_attach+0x787/0x15e0 kernel/cgroup/cpuset.c:2278 cgroup_migrate_execute+0x1023/0x1d20 kernel/cgroup/cgroup.c:2515 cgroup_migrate kernel/cgroup/cgroup.c:2771 [inline] cgroup_attach_task+0x540/0x8b0 kernel/cgroup/cgroup.c:2804 __cgroup1_procs_write+0x5cc/0x7a0 kernel/cgroup/cgroup-v1.c:520 cgroup1_tasks_write+0x94/0xb0 kernel/cgroup/cgroup-v1.c:539 cgroup_file_write+0x4c2/0x9e0 kernel/cgroup/cgroup.c:3852 kernfs_fop_write_iter+0x66a/0x9f0 fs/kernfs/file.c:296 call_write_iter include/linux/fs.h:2162 [inline] new_sync_write fs/read_write.c:503 [inline] vfs_write+0x1318/0x2030 fs/read_write.c:590 ksys_write+0x28b/0x510 fs/read_write.c:643 __do_sys_write fs/read_write.c:655 [inline] __se_sys_write fs/read_write.c:652 [inline] __x64_sys_write+0xdb/0x120 fs/read_write.c:652 do_syscall_x64 arch/x86/entry/common.c:51 [inline] do_syscall_64+0x54/0xd0 arch/x86/entry/common.c:82 entry_SYSCALL_64_after_hwframe+0x44/0xae
Uninit was created at:
slab_post_alloc_hook mm/slab.h:524 [inline] slab_alloc_node mm/slub.c:3251 [inline] slab_alloc mm/slub.c:3259 [inline] kmem_cache_alloc+0x902/0x11c0 mm/slub.c:3264 mpol_new mm/mempolicy.c:293 [inline] do_set_mempolicy+0x421/0xb70 mm/mempolicy.c:853 kernel_set_mempolicy mm/mempolicy.c:1504 [inline] __do_sys_set_mempolicy mm/mempolicy.c:1510 [inline] __se_sys_set_mempolicy+0x44c/0xb60 mm/mempolicy.c:1507 __x64_sys_set_mempolicy+0xd8/0x110 mm/mempolicy.c:1507 do_syscall_x64 arch/x86/entry/common.c:51 [inline] do_syscall_64+0x54/0xd0 arch/x86/entry/common.c:82 entry_SYSCALL_64_after_hwframe+0x44/0xae
KMSAN: uninit-value in mpol_rebind_task (2)
https://syzkaller.appspot.com/bug?id=d6eb90f952c2a5de9ea718a1b873c55cb13b59dc
This patch seems to fix below bug too.
KMSAN: uninit-value in mpol_rebind_mm (2)
https://syzkaller.appspot.com/bug?id=f2fecd0d7013f54ec4162f60743a2b28df40926b
The uninit-value is pol->w.cpuset_mems_allowed in mpol_rebind_policy(). When syzkaller reproducer runs to the beginning of mpol_new(),
mpol_new() mm/mempolicy.c
do_mbind() mm/mempolicy.c
kernel_mbind() mm/mempolicy.c
mode is 1(MPOL_PREFERRED), nodes_empty(*nodes) is true and flags is 0. Then
mode = MPOL_LOCAL; ... policy->mode = mode; policy->flags = flags;
will be executed. So in mpol_set_nodemask(),
mpol_set_nodemask() mm/mempolicy.c do_mbind() kernel_mbind()
pol->mode is 4 (MPOL_LOCAL), that nodemask in pol is not initialized, which will be accessed in mpol_rebind_policy().
--- mm/mempolicy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
mm/mempolicy.c +1 -1
@@ -347,7 +347,7 @@ static void mpol_rebind_preferred(struct*/ static void mpol_rebind_policy (struct mempolicy *pol,const nodemask_t *newmask) { -if (!pol) +if (!pol || pol->mode ==MPOL_LOCAL )return ;if (!mpol_store_user_nodemask (pol) &&nodes_equal (pol->w.cpuset_mems_allowed, *newmask))
Greg Kroah-Hartman
maintainerPATCH 136/201 bpf: Make sure mac_header was set before using it
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
commit 0326195f523a549e0a9d7fd44c70b26fd7265090 upstream.
Classic BPF has a way to load bytes starting from the mac header.
Some skbs do not have a mac header, and skb_mac_header() in this case is returning a pointer that 65535 bytes after skb->head.
Existing range check in bpf_internal_load_pointer_neg_helper() was properly kicking and no illegal access was happening.
New sanity check in skb_mac_header() is firing, so we need to avoid it.
WARNING: CPU: 1 PID: 28990 at include/linux/skbuff.h:2785 skb_mac_header include/linux/skbuff.h:2785 [inline] WARNING: CPU: 1 PID: 28990 at include/linux/skbuff.h:2785 bpf_internal_load_pointer_neg_helper+0x1b1/0x1c0 kernel/bpf/core.c:74 Modules linked in: CPU: 1 PID: 28990 Comm: syz-executor.0 Not tainted 5.19.0-rc4-syzkaller-00865-g4874fb9484be #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 06/29/2022 RIP: 0010:skb_mac_header include/linux/skbuff.h:2785 [inline] RIP: 0010:bpf_internal_load_pointer_neg_helper+0x1b1/0x1c0 kernel/bpf/core.c:74 Code: ff ff 45 31 f6 e9 5a ff ff ff e8 aa 27 40 00 e9 3b ff ff ff e8 90 27 40 00 e9 df fe ff ff e8 86 27 40 00 eb 9e e8 2f 2c f3 ff <0f> 0b eb b1 e8 96 27 40 00 e9 79 fe ff ff 90 41 57 41 56 41 55 41 RSP: 0018:ffffc9000309f668 EFLAGS: 00010216 RAX: 0000000000000118 RBX: ffffffffffeff00c RCX: ffffc9000e417000 RDX: 0000000000040000 RSI: ffffffff81873f21 RDI: 0000000000000003 RBP: ffff8880842878c0 R08: 0000000000000003 R09: 000000000000ffff R10: 000000000000ffff R11: 0000000000000001 R12: 0000000000000004 R13: ffff88803ac56c00 R14: 000000000000ffff R15: dffffc0000000000 FS: 00007f5c88a16700(0000) GS:ffff8880b9b00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007fdaa9f6c058 CR3: 000000003a82c000 CR4: 00000000003506e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> ____bpf_skb_load_helper_32 net/core/filter.c:276 [inline] bpf_skb_load_helper_32+0x191/0x220 net/core/filter.c:264
--- kernel/bpf/core.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
kernel/bpf/core.c +5 -3
@@ -66,11 +66,13 @@ void *bpf_internal_load_pointer_neg_help {u8 *ptr =NULL ; -if (k >=SKF_NET_OFF ) +if (k >=SKF_NET_OFF ) { ptr =skb_network_header (skb) + k -SKF_NET_OFF ; -else if (k >=SKF_LL_OFF ) + }else if (k >=SKF_LL_OFF ) { +if (unlikely (!skb_mac_header_was_set (skb))) +return NULL ; ptr =skb_mac_header (skb) + k -SKF_LL_OFF ; - + }if (ptr >= skb->head && ptr + size <=skb_tail_pointer (skb))return ptr;
Greg Kroah-Hartman
maintainerPATCH 137/201 sched/deadline: Fix BUG_ON condition for deboosted tasks
In reply to Greg Kroah-HartmanFrom: Juri Lelli <[email protected]>
commit ddfc710395cccc61247348df9eb18ea50321cbed upstream.
Tasks the are being deboosted from SCHED_DEADLINE might enter enqueue_task_dl() one last time and hit an erroneous BUG_ON condition:
since they are not boosted anymore, the if (is_dl_boosted()) branch is not taken, but the else if (!dl_prio) is and inside this one we BUG_ON(!is_dl_boosted), which is of course false (BUG_ON triggered) otherwise we had entered the if branch above. Long story short, the current condition doesn't make sense and always leads to triggering of a BUG.
Fix this by only checking enqueue flags, properly: ENQUEUE_REPLENISH has to be present, but additional flags are not a problem.
--- kernel/sched/deadline.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
kernel/sched/deadline.c +4 -1
@@ -1561,7 +1561,10 @@ static void enqueue_task_dl(struct rq *r* the throttle. */ p->dl.dl_throttled =0 ; -BUG_ON (!is_dl_boosted (&p->dl) || flags !=ENQUEUE_REPLENISH ); +if (!(flags &ENQUEUE_REPLENISH )) +printk_deferred_once ("sched: DL de-boosted task PID %d: REPLENISH flag missing\n" , +task_pid_nr (p)); +return ; }
Greg Kroah-Hartman
maintainerPATCH 138/201 x86/bugs: Warn when "ibrs" mitigation is selected on Enhanced IBRS parts
In reply to Greg Kroah-HartmanFrom: Pawan Gupta <[email protected]>
commit eb23b5ef9131e6d65011de349a4d25ef1b3d4314 upstream.
IBRS mitigation for spectre_v2 forces write to MSR_IA32_SPEC_CTRL at every kernel entry/exit. On Enhanced IBRS parts setting MSR_IA32_SPEC_CTRL[IBRS] only once at boot is sufficient. MSR writes at every kernel entry/exit incur unnecessary performance loss.
When Enhanced IBRS feature is present, print a warning about this unnecessary performance loss.
--- arch/x86/kernel/cpu/bugs.c | 3 +++ 1 file changed, 3 insertions(+)
arch/x86/kernel/cpu/bugs.c +3 -0
@@ -968,6 +968,7 @@ static inline const char *spectre_v2_mod#define SPECTRE_V2_LFENCE_MSG "WARNING: LFENCE mitigation is not recommended for this CPU, data leaks possible!\n"#define SPECTRE_V2_EIBRS_EBPF_MSG "WARNING: Unprivileged eBPF is enabled with eIBRS on, data leaks possible via Spectre v2 BHB attacks!\n"#define SPECTRE_V2_EIBRS_LFENCE_EBPF_SMT_MSG "WARNING: Unprivileged eBPF is enabled with eIBRS+LFENCE mitigation and SMT, data leaks possible via Spectre v2 BHB attacks!\n" +#define SPECTRE_V2_IBRS_PERF_MSG "WARNING: IBRS mitigation selected on Enhanced IBRS CPU, this may cause unnecessary performance loss\n"#ifdef CONFIG_BPF_SYSCALL void unpriv_ebpf_notify (int new_state)
@@ -1408,6 +1409,8 @@ static void __init spectre_v2_select_mitcase SPECTRE_V2_IBRS :setup_force_cpu_cap (X86_FEATURE_KERNEL_IBRS ); +if (boot_cpu_has (X86_FEATURE_IBRS_ENHANCED )) +pr_warn (SPECTRE_V2_IBRS_PERF_MSG );break ;case SPECTRE_V2_LFENCE :
Greg Kroah-Hartman
maintainerPATCH 139/201 dlm: fix pending remove if msg allocation fails
In reply to Greg Kroah-HartmanFrom: Alexander Aring <[email protected]>
[ Upstream commit ba58995909b5098ca4003af65b0ccd5a8d13dd25 ]
This patch unsets ls_remove_len and ls_remove_name if a message allocation of a remove messages fails. In this case we never send a remove message out but set the per ls ls_remove_len ls_remove_name variable for a pending remove. Unset those variable should indicate possible waiters in wait_pending_remove() that no pending remove is going on at this moment.
--- fs/dlm/lock.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/dlm/lock.c +2 -1
@@ -4065,13 +4065,14 @@ static void send_repeat_remove(struct dlm_ls *ls, char *ms_name, int len) rv =_create_message (ls,sizeof (struct dlm_message ) + len, dir_nodeid,DLM_MSG_REMOVE , &ms, &mh);if (rv) -return ; + goto out;memcpy (ms->m_extra, name, len); ms->m_hash = hash;send_message (mh, ms); +out:spin_lock (&ls->ls_remove_spin); ls->ls_remove_len =0 ;memset (ls->ls_remove_name,0 ,DLM_RESNAME_MAXLEN );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 140/201 x86/uaccess: Implement macros for CMPXCHG on user addresses
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
[ Upstream commit 989b5db215a2f22f89d730b607b071d964780f10 ]
Add support for CMPXCHG loops on userspace addresses. Provide both an "unsafe" version for tight loops that do their own uaccess begin/end, as well as a "safe" version for use cases where the CMPXCHG is not buried in a loop, e.g. KVM will resume the guest instead of looping when emulation of a guest atomic accesses fails the CMPXCHG.
Provide 8-byte versions for 32-bit kernels so that KVM can do CMPXCHG on guest PAE PTEs, which are accessed via userspace addresses.
Guard the asm_volatile_goto() variation with CC_HAS_ASM_GOTO_TIED_OUTPUT, the "+m" constraint fails on some compilers that otherwise support CC_HAS_ASM_GOTO_OUTPUT.
Message-Id: <[email protected]>
--- arch/x86/include/asm/uaccess.h | 142 +++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+)
arch/x86/include/asm/uaccess.h +142 -0
@@ -414,6 +414,103 @@ do { \#endif // CONFIG_CC_ASM_GOTO_OUTPUT +#ifdef CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT +#define __try_cmpxchg_user_asm (itype, ltype, _ptr, _pold, _new, label) ({ \ + bool success; \ + __typeof__(_ptr) _old = (__typeof__(_ptr))(_pold); \ + __typeof__(*(_ptr)) __old = *_old; \ + __typeof__(*(_ptr)) __new = (_new); \ + asm_volatile_goto("\n" \ + "1: " LOCK_PREFIX "cmpxchg"itype" %[new], %[ptr]\n"\ + _ASM_EXTABLE_UA(1b, %l[label]) \ + : CC_OUT(z) (success), \ + [ptr] "+m" (*_ptr), \ + [old] "+a" (__old) \ + : [new] ltype (__new) \ + : "memory" \ + : label); \ + if (unlikely(!success)) \ + *_old = __old; \ + likely(success); }) + +#ifdef CONFIG_X86_32 +#define __try_cmpxchg64_user_asm (_ptr, _pold, _new, label) ({ \ + bool success; \ + __typeof__(_ptr) _old = (__typeof__(_ptr))(_pold); \ + __typeof__(*(_ptr)) __old = *_old; \ + __typeof__(*(_ptr)) __new = (_new); \ + asm_volatile_goto("\n" \ + "1: " LOCK_PREFIX "cmpxchg8b %[ptr]\n" \ + _ASM_EXTABLE_UA(1b, %l[label]) \ + : CC_OUT(z) (success), \ + "+A" (__old), \ + [ptr] "+m" (*_ptr) \ + : "b" ((u32)__new), \ + "c" ((u32)((u64)__new >> 32)) \ + : "memory" \ + : label); \ + if (unlikely(!success)) \ + *_old = __old; \ + likely(success); }) +#endif // CONFIG_X86_32 +#else // !CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT +#define __try_cmpxchg_user_asm (itype, ltype, _ptr, _pold, _new, label) ({ \ + int __err = 0; \ + bool success; \ + __typeof__(_ptr) _old = (__typeof__(_ptr))(_pold); \ + __typeof__(*(_ptr)) __old = *_old; \ + __typeof__(*(_ptr)) __new = (_new); \ + asm volatile("\n" \ + "1: " LOCK_PREFIX "cmpxchg"itype" %[new], %[ptr]\n"\ + CC_SET(z) \ + "2:\n" \ + _ASM_EXTABLE_TYPE_REG(1b, 2b, EX_TYPE_EFAULT_REG, \ + %[errout]) \ + : CC_OUT(z) (success), \ + [errout] "+r" (__err), \ + [ptr] "+m" (*_ptr), \ + [old] "+a" (__old) \ + : [new] ltype (__new) \ + : "memory", "cc"); \ + if (unlikely(__err)) \ + goto label; \ + if (unlikely(!success)) \ + *_old = __old; \ + likely(success); }) + +#ifdef CONFIG_X86_32 +/* +* Unlike the normal CMPXCHG, hardcode ECX for both success/fail and error. +* There are only six GPRs available and four (EAX, EBX, ECX, and EDX) are +* hardcoded by CMPXCHG8B, leaving only ESI and EDI. If the compiler uses +* both ESI and EDI for the memory operand, compilation will fail if the error +* is an input+output as there will be no register available for input. +*/ +#define __try_cmpxchg64_user_asm (_ptr, _pold, _new, label) ({ \ + int __result; \ + __typeof__(_ptr) _old = (__typeof__(_ptr))(_pold); \ + __typeof__(*(_ptr)) __old = *_old; \ + __typeof__(*(_ptr)) __new = (_new); \ + asm volatile("\n" \ + "1: " LOCK_PREFIX "cmpxchg8b %[ptr]\n" \ + "mov $0, %%ecx\n\t" \ + "setz %%cl\n" \ + "2:\n" \ + _ASM_EXTABLE_TYPE_REG(1b, 2b, EX_TYPE_EFAULT_REG, %%ecx) \ + : [result]"=c" (__result), \ + "+A" (__old), \ + [ptr] "+m" (*_ptr) \ + : "b" ((u32)__new), \ + "c" ((u32)((u64)__new >> 32)) \ + : "memory", "cc"); \ + if (unlikely(__result < 0)) \ + goto label; \ + if (unlikely(!__result)) \ + *_old = __old; \ + likely(__result); }) +#endif // CONFIG_X86_32 +#endif // CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT +/* FIXME: this hack is definitely wrong -AK */ struct __large_struct {unsigned long buf[100 ]; };#define __m (x) (*(struct __large_struct __user *)(x))
@@ -506,6 +603,51 @@ do { \ } while (0)#endif // CONFIG_CC_HAS_ASM_GOTO_OUTPUT +extern void __try_cmpxchg_user_wrong_size (void ); + +#ifndef CONFIG_X86_32 +#define __try_cmpxchg64_user_asm (_ptr, _oldp, _nval, _label) \ + __try_cmpxchg_user_asm("q", "r", (_ptr), (_oldp), (_nval), _label) +#endif + +/* +* Force the pointer to u<size> to match the size expected by the asm helper. +* clang/LLVM compiles all cases and only discards the unused paths after +* processing errors, which breaks i386 if the pointer is an 8-byte value. +*/ +#define unsafe_try_cmpxchg_user (_ptr, _oldp, _nval, _label) ({ \ + bool __ret; \ + __chk_user_ptr(_ptr); \ + switch (sizeof(*(_ptr))) { \ + case 1: __ret = __try_cmpxchg_user_asm("b", "q", \ + (__force u8 *)(_ptr), (_oldp), \ + (_nval), _label); \ + break; \ + case 2: __ret = __try_cmpxchg_user_asm("w", "r", \ + (__force u16 *)(_ptr), (_oldp), \ + (_nval), _label); \ + break; \ + case 4: __ret = __try_cmpxchg_user_asm("l", "r", \ + (__force u32 *)(_ptr), (_oldp), \ + (_nval), _label); \ + break; \ + case 8: __ret = __try_cmpxchg64_user_asm((__force u64 *)(_ptr), (_oldp),\ + (_nval), _label); \ + break; \ + default: __try_cmpxchg_user_wrong_size(); \ + } \ + __ret; }) + +/* "Returns" 0 on success, 1 on failure, -EFAULT if the access faults. */ +#define __try_cmpxchg_user (_ptr, _oldp, _nval, _label) ({ \ + int __ret = -EFAULT; \ + __uaccess_begin_nospec(); \ + __ret = !unsafe_try_cmpxchg_user(_ptr, _oldp, _nval, _label); \ +_label: \ + __uaccess_end(); \ + __ret; \ + }) +/* * We want the unsafe accessors to always be inlined and use * the error labels - thus the macro games.
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 141/201 x86/extable: Tidy up redundant handler functions
In reply to Greg Kroah-HartmanFrom: Thomas Gleixner <[email protected]>
[ Upstream commit 326b567f82df0c4c8f50092b9af9a3014616fb3c ]
No need to have the same code all over the place.
--- arch/x86/mm/extable.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-)
arch/x86/mm/extable.c +5 -11
@@ -39,9 +39,8 @@ __visible bool ex_handler_fault(const struct exception_table_entry *fixup,unsigned long error_code, unsigned long fault_addr) { - regs->ip = ex_fixup_addr(fixup); regs->ax = trapnr; -return true; +return ex_handler_default (fixup, regs, trapnr, error_code, fault_addr); }EXPORT_SYMBOL_GPL (ex_handler_fault);
@@ -76,8 +75,7 @@ __visible bool ex_handler_uaccess(const struct exception_table_entry *fixup, unsigned long fault_addr) {WARN_ONCE (trapnr ==X86_TRAP_GP ,"General protection fault in user access. Non-canonical address?" ); - regs->ip =ex_fixup_addr (fixup); -return true; +return ex_handler_default (fixup, regs, trapnr, error_code, fault_addr); }EXPORT_SYMBOL (ex_handler_uaccess);
@@ -87,9 +85,7 @@ __visible bool ex_handler_copy(const struct exception_table_entry *fixup, unsigned long fault_addr) {WARN_ONCE (trapnr ==X86_TRAP_GP ,"General protection fault in user access. Non-canonical address?" ); - regs->ip =ex_fixup_addr (fixup); - regs->ax = trapnr; -return true; +return ex_handler_fault (fixup, regs, trapnr, error_code, fault_addr); }EXPORT_SYMBOL (ex_handler_copy);
@@ -103,10 +99,9 @@ __visible bool ex_handler_rdmsr_unsafe(const struct exception_table_entry *fixupshow_stack_regs (regs);/* Pretend that the read succeeded and returned 0. */ - regs->ip =ex_fixup_addr (fixup); regs->ax =0 ; regs->dx =0 ; -return true; +return ex_handler_default (fixup, regs, trapnr, error_code, fault_addr); }EXPORT_SYMBOL (ex_handler_rdmsr_unsafe);
@@ -121,8 +116,7 @@ __visible bool ex_handler_wrmsr_unsafe(const struct exception_table_entry *fixupshow_stack_regs (regs);/* Pretend that the write succeeded. */ - regs->ip =ex_fixup_addr (fixup); -return true; +return ex_handler_default (fixup, regs, trapnr, error_code, fault_addr); }EXPORT_SYMBOL (ex_handler_wrmsr_unsafe);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 142/201 x86/extable: Get rid of redundant macros
In reply to Greg Kroah-HartmanFrom: Thomas Gleixner <[email protected]>
[ Upstream commit 32fd8b59f91fcd3bf9459aa72d90345735cc2588 ]
No point in defining the identical macros twice depending on C or assembly mode. They are still identical.
--- arch/x86/include/asm/asm.h | 36 ++++++++++++------------------------ 1 file changed, 12 insertions(+), 24 deletions(-)
arch/x86/include/asm/asm.h +12 -24
@@ -132,18 +132,6 @@ .long (handler) - . ; \ .popsection -# define _ASM_EXTABLE (from, to) \ - _ASM_EXTABLE_HANDLE(from, to, ex_handler_default) - -# define _ASM_EXTABLE_UA (from, to) \ - _ASM_EXTABLE_HANDLE(from, to, ex_handler_uaccess) - -# define _ASM_EXTABLE_CPY (from, to) \ - _ASM_EXTABLE_HANDLE(from, to, ex_handler_copy) - -# define _ASM_EXTABLE_FAULT (from, to) \ - _ASM_EXTABLE_HANDLE(from, to, ex_handler_fault) -# ifdef CONFIG_KPROBES # define _ASM_NOKPROBE (entry) \ .pushsection "_kprobe_blacklist","aw" ; \
@@ -164,18 +152,6 @@ " .long (" _EXPAND_EXTABLE_HANDLE(handler) ") - .\n" \" .popsection\n" -# define _ASM_EXTABLE (from, to) \ - _ASM_EXTABLE_HANDLE(from, to, ex_handler_default) - -# define _ASM_EXTABLE_UA (from, to) \ - _ASM_EXTABLE_HANDLE(from, to, ex_handler_uaccess) - -# define _ASM_EXTABLE_CPY (from, to) \ - _ASM_EXTABLE_HANDLE(from, to, ex_handler_copy) - -# define _ASM_EXTABLE_FAULT (from, to) \ - _ASM_EXTABLE_HANDLE(from, to, ex_handler_fault) -/* For C file, we already have NOKPROBE_SYMBOL macro */ /*
@@ -188,6 +164,18 @@ register unsigned long current_stack_pointer asm(_ASM_SP);#define ASM_CALL_CONSTRAINT "+r" (current_stack_pointer)#endif /* __ASSEMBLY__ */ +#define _ASM_EXTABLE (from, to) \ + _ASM_EXTABLE_HANDLE(from, to, ex_handler_default) + +#define _ASM_EXTABLE_UA (from, to) \ + _ASM_EXTABLE_HANDLE(from, to, ex_handler_uaccess) + +#define _ASM_EXTABLE_CPY (from, to) \ + _ASM_EXTABLE_HANDLE(from, to, ex_handler_copy) + +#define _ASM_EXTABLE_FAULT (from, to) \ + _ASM_EXTABLE_HANDLE(from, to, ex_handler_fault) +#endif /* __KERNEL__ */ #endif /* _ASM_X86_ASM_H */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 143/201 x86/mce: Deduplicate exception handling
In reply to Greg Kroah-HartmanFrom: Thomas Gleixner <[email protected]>
[ Upstream commit e42404afc4ca856c48f1e05752541faa3587c472 ]
Prepare code for further simplification. No functional change.
--- arch/x86/kernel/cpu/mce/core.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-)
arch/x86/kernel/cpu/mce/core.c +17 -17
@@ -382,13 +382,16 @@ static int msr_to_offset(u32 msr)return -1 ; } -__visible bool ex_handler_rdmsr_fault(const struct exception_table_entry *fixup, -struct pt_regs *regs,int trapnr, -unsigned long error_code, -unsigned long fault_addr) +static void ex_handler_msr_mce (struct pt_regs *regs,bool wrmsr) { -pr_emerg ("MSR access error: RDMSR from 0x%x at rIP: 0x%lx (%pS)\n" , - (unsigned int )regs->cx, regs->ip, (void *)regs->ip); +if (wrmsr) { +pr_emerg ("MSR access error: WRMSR to 0x%x (tried to write 0x%08x%08x) at rIP: 0x%lx (%pS)\n" , + (unsigned int )regs->cx, (unsigned int )regs->dx, (unsigned int )regs->ax, + regs->ip, (void *)regs->ip); + }else { +pr_emerg ("MSR access error: RDMSR from 0x%x at rIP: 0x%lx (%pS)\n" , + (unsigned int )regs->cx, regs->ip, (void *)regs->ip); + }show_stack_regs (regs);
@@ -396,7 +399,14 @@ __visible bool ex_handler_rdmsr_fault(const struct exception_table_entry *fixup,while (true)cpu_relax (); +} +__visible bool ex_handler_rdmsr_fault(const struct exception_table_entry *fixup, +struct pt_regs *regs,int trapnr, +unsigned long error_code, +unsigned long fault_addr) +{ +ex_handler_msr_mce (regs, false);return true; }
@@ -441,17 +451,7 @@ __visible bool ex_handler_wrmsr_fault(const struct exception_table_entry *fixup,unsigned long error_code, unsigned long fault_addr) { - pr_emerg("MSR access error: WRMSR to 0x%x (tried to write 0x%08x%08x) at rIP: 0x%lx (%pS)\n", - (unsigned int )regs->cx, (unsigned int )regs->dx, (unsigned int )regs->ax, - regs->ip, (void *)regs->ip); - -show_stack_regs (regs); - -panic ("MCA architectural violation!\n" ); - -while (true) -cpu_relax (); - +ex_handler_msr_mce (regs ,true );return true; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 144/201 x86/extable: Rework the exception table mechanics
In reply to Greg Kroah-HartmanFrom: Thomas Gleixner <[email protected]>
[ Upstream commit 46d28947d9876fc0f8f93d3c69813ef6e9852595 ]
The exception table entries contain the instruction address, the fixup address and the handler address. All addresses are relative. Storing the handler address has a few downsides:
1) Most handlers need to be exported
2) Handlers can be defined everywhere and there is no overview about the handler types
3) MCE needs to check the handler type to decide whether an in kernel #MC can be recovered. The functionality of the handler itself is not in any way special, but for these checks there need to be separate functions which in the worst case have to be exported.
Some of these 'recoverable' exception fixups are pretty obscure and just reuse some other handler to spare code. That obfuscates e.g. the #MC safe copy functions. Cleaning that up would require more handlers and exports
Rework the exception fixup mechanics by storing a fixup type number instead of the handler address and invoke the proper handler for each fixup type. Also teach the extable sort to leave the type field alone.
This makes most handlers static except for special cases like the MCE MSR fixup and the BPF fixup. This allows to add more types for cleaning up the obscure places without adding more handler code and exports.
There is a marginal code size reduction for a production config and it removes _eight_ exported symbols.
--- arch/x86/include/asm/asm.h | 22 ++-- arch/x86/include/asm/extable.h | 44 +++++--- arch/x86/include/asm/extable_fixup_types.h | 19 ++++ arch/x86/include/asm/fpu/internal.h | 4 +- arch/x86/include/asm/msr.h | 4 +- arch/x86/include/asm/segment.h | 2 +- arch/x86/kernel/cpu/mce/core.c | 24 +--- arch/x86/kernel/cpu/mce/internal.h | 10 -- arch/x86/kernel/cpu/mce/severity.c | 21 ++-- arch/x86/mm/extable.c | 123 +++++++++------------ arch/x86/net/bpf_jit_comp.c | 11 +- scripts/sorttable.c | 4 +- 12 files changed, 133 insertions(+), 155 deletions(-) create mode 100644 arch/x86/include/asm/extable_fixup_types.h
arch/x86/include/asm/asm.h +12 -10
@@ -122,14 +122,17 @@#ifdef __KERNEL__ +# include <asm/extable_fixup_types.h> +/* Exception table entry */ #ifdef __ASSEMBLY__ -# define _ASM_EXTABLE_HANDLE (from, to, handler) \ + +# define _ASM_EXTABLE_TYPE (from, to, type) \ .pushsection "__ex_table","a" ; \ .balign 4 ; \ .long (from) - . ; \ .long (to) - . ; \ - .long (handler) - . ; \ + .long type ; \ .popsection# ifdef CONFIG_KPROBES
@@ -143,13 +146,13 @@# endif #else /* ! __ASSEMBLY__ */ -# define _EXPAND_EXTABLE_HANDLE (x) #x -# define _ASM_EXTABLE_HANDLE (from, to, handler) \ + +# define _ASM_EXTABLE_TYPE (from, to, type) \ " .pushsection \"__ex_table\",\"a\"\n" \ " .balign 4\n" \ " .long (" #from ") - .\n" \ " .long (" #to ") - .\n" \ - " .long (" _EXPAND_EXTABLE_HANDLE(handler) ") - .\n" \ + " .long " __stringify(type) " \n" \ " .popsection\n"/* For C file, we already have NOKPROBE_SYMBOL macro */
@@ -165,17 +168,16 @@ register unsigned long current_stack_pointer asm(_ASM_SP);#endif /* __ASSEMBLY__ */ #define _ASM_EXTABLE (from, to) \ - _ASM_EXTABLE_HANDLE(from, to, ex_handler_default) + _ASM_EXTABLE_TYPE(from, to, EX_TYPE_DEFAULT)#define _ASM_EXTABLE_UA (from, to) \ - _ASM_EXTABLE_HANDLE(from, to, ex_handler_uaccess) + _ASM_EXTABLE_TYPE(from, to, EX_TYPE_UACCESS)#define _ASM_EXTABLE_CPY (from, to) \ - _ASM_EXTABLE_HANDLE(from, to, ex_handler_copy) + _ASM_EXTABLE_TYPE(from, to, EX_TYPE_COPY)#define _ASM_EXTABLE_FAULT (from, to) \ - _ASM_EXTABLE_HANDLE(from, to, ex_handler_fault) + _ASM_EXTABLE_TYPE(from, to, EX_TYPE_FAULT)#endif /* __KERNEL__ */ -#endif /* _ASM_X86_ASM_H */
arch/x86/include/asm/extable.h +28 -16
68 lines not on this page · raw message
arch/x86/include/asm/extable_fixup_types.h new file +19 -0
@@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_X86_EXTABLE_FIXUP_TYPES_H +#define _ASM_X86_EXTABLE_FIXUP_TYPES_H + +#define EX_TYPE_NONE 0 +#define EX_TYPE_DEFAULT 1 +#define EX_TYPE_FAULT 2 +#define EX_TYPE_UACCESS 3 +#define EX_TYPE_COPY 4 +#define EX_TYPE_CLEAR_FS 5 +#define EX_TYPE_FPU_RESTORE 6 +#define EX_TYPE_WRMSR 7 +#define EX_TYPE_RDMSR 8 +#define EX_TYPE_BPF 9 + +#define EX_TYPE_WRMSR_IN_MCE 10 +#define EX_TYPE_RDMSR_IN_MCE 11 + +#endif
arch/x86/include/asm/fpu/internal.h +2 -2
@@ -126,7 +126,7 @@ extern void save_fpregs_to_fpstate(struct fpu *fpu); #define kernel_insn(insn, output, input...) \ asm volatile("1:" #insn "\n\t" \ "2:\n" \ - _ASM_EXTABLE_HANDLE(1b, 2b, ex_handler_fprestore) \ + _ASM_EXTABLE_TYPE(1b, 2b, EX_TYPE_FPU_RESTORE) \ : output : input)static inline int fnsave_to_user_sigframe (struct fregs_state __user *fx)
@@ -253,7 +253,7 @@ static inline void fxsave(struct fxregs_state *fx) XRSTORS, X86_FEATURE_XSAVES) \ "\n" \ "3:\n" \ -_ASM_EXTABLE_HANDLE(661b, 3b, ex_handler_fprestore)\ +_ASM_EXTABLE_TYPE(661b, 3b, EX_TYPE_FPU_RESTORE) \ : \ : " D " (st), " m" (*st), " a" (lmask), " d" (hmask) \ : "memory")
arch/x86/include/asm/msr.h +2 -2
@@ -92,7 +92,7 @@ static __always_inline unsigned long long __rdmsr(unsigned int msr) asm volatile("1: rdmsr\n" "2:\n" - _ASM_EXTABLE_HANDLE(1b, 2b, ex_handler_rdmsr_unsafe) + _ASM_EXTABLE_TYPE(1b, 2b, EX_TYPE_RDMSR) : EAX_EDX_RET(val, low, high) : "c" (msr));return EAX_EDX_VAL (val, low, high);
@@ -102,7 +102,7 @@ static __always_inline void __wrmsr(unsigned int msr, u32 low, u32 high) { asm volatile("1: wrmsr\n" "2:\n" - _ASM_EXTABLE_HANDLE(1b, 2b, ex_handler_wrmsr_unsafe) + _ASM_EXTABLE_TYPE(1b, 2b, EX_TYPE_WRMSR) : : "c" (msr), "a"(low), "d" (high) : "memory"); }
arch/x86/include/asm/segment.h +1 -1
@@ -339,7 +339,7 @@ static inline void __loadsegment_fs(unsigned short value) "1: movw %0, %%fs \n" "2: \n" - _ASM_EXTABLE_HANDLE(1b, 2b, ex_handler_clear_fs) + _ASM_EXTABLE_TYPE(1b, 2b, EX_TYPE_CLEAR_FS) : : "rm" (value) : "memory"); }
arch/x86/kernel/cpu/mce/core.c +3 -21
@@ -382,7 +382,7 @@ static int msr_to_offset(u32 msr)return -1 ; } -static void ex_handler_msr_mce (struct pt_regs *regs,bool wrmsr) +void ex_handler_msr_mce (struct pt_regs *regs,bool wrmsr) {if (wrmsr) { pr_emerg("MSR access error: WRMSR to 0x%x (tried to write 0x%08x%08x) at rIP: 0x%lx (%pS)\n",
@@ -401,15 +401,6 @@ static void ex_handler_msr_mce(struct pt_regs *regs, bool wrmsr)cpu_relax (); } -__visible bool ex_handler_rdmsr_fault(const struct exception_table_entry *fixup, -struct pt_regs *regs,int trapnr, -unsigned long error_code, -unsigned long fault_addr) -{ -ex_handler_msr_mce (regs, false); -return true; -} -/* MSR access wrappers used for error injection */ static noinstr u64 mce_rdmsrl(u32 msr) {
@@ -439,22 +430,13 @@ static noinstr u64 mce_rdmsrl(u32 msr)*/ asm volatile("1: rdmsr\n" "2:\n" - _ASM_EXTABLE_HANDLE(1b, 2b, ex_handler_rdmsr_fault) + _ASM_EXTABLE_TYPE(1b, 2b, EX_TYPE_RDMSR_IN_MCE) : EAX_EDX_RET(val, low, high) : "c" (msr));return EAX_EDX_VAL (val, low, high); } -__visible bool ex_handler_wrmsr_fault(const struct exception_table_entry *fixup, -struct pt_regs *regs,int trapnr, -unsigned long error_code, -unsigned long fault_addr) -{ -ex_handler_msr_mce (regs, true); -return true; -} - static noinstr void mce_wrmsrl(u32 msr, u64 v) {u32 low, high;
@@ -479,7 +461,7 @@ static noinstr void mce_wrmsrl(u32 msr, u64 v)/* See comment in mce_rdmsrl() */ asm volatile("1: wrmsr\n" "2:\n" - _ASM_EXTABLE_HANDLE(1b, 2b, ex_handler_wrmsr_fault) + _ASM_EXTABLE_TYPE(1b, 2b, EX_TYPE_WRMSR_IN_MCE) : : "c" (msr), "a"(low), "d" (high) : "memory"); }
arch/x86/kernel/cpu/mce/internal.h +0 -10
@@ -186,14 +186,4 @@ extern bool amd_filter_mce(struct mce *m);static inline bool amd_filter_mce (struct mce *m) {return false; };#endif -__visible bool ex_handler_rdmsr_fault(const struct exception_table_entry *fixup, -struct pt_regs *regs,int trapnr, -unsigned long error_code, -unsigned long fault_addr); - -__visible bool ex_handler_wrmsr_fault(const struct exception_table_entry *fixup, -struct pt_regs *regs,int trapnr, -unsigned long error_code, -unsigned long fault_addr); -#endif /* __X86_MCE_INTERNAL_H__ */
arch/x86/kernel/cpu/mce/severity.c +10 -11
@@ -265,25 +265,24 @@ static bool is_copy_from_user(struct pt_regs *regs)*/ static int error_context (struct mce *m,struct pt_regs *regs) { -enum handler_type t; -if ((m->cs &3 ) ==3 )return IN_USER ;if (!mc_recoverable (m->mcgstatus))return IN_KERNEL ; - t =ex_get_fault_handler_type (m->ip); -if (t ==EX_HANDLER_FAULT ) { - m->kflags |=MCE_IN_KERNEL_RECOV ; -return IN_KERNEL_RECOV ; - } -if (t ==EX_HANDLER_UACCESS && regs &&is_copy_from_user (regs)) { - m->kflags |=MCE_IN_KERNEL_RECOV ; +switch (ex_get_fixup_type (m->ip)) { +case EX_TYPE_UACCESS : +case EX_TYPE_COPY : +if (!regs || !is_copy_from_user (regs)) +return IN_KERNEL ; m->kflags |=MCE_IN_KERNEL_COPYIN ; + fallthrough; +case EX_TYPE_FAULT : + m->kflags |=MCE_IN_KERNEL_RECOV ;return IN_KERNEL_RECOV ; +default : +return IN_KERNEL ; } - -return IN_KERNEL ; }static int mce_severity_amd_smca (struct mce *m,enum context err_ctx)
arch/x86/mm/extable.c +52 -71
200 lines not on this page · raw message
arch/x86/net/bpf_jit_comp.c +2 -9
@@ -832,9 +832,7 @@ static int emit_atomic(u8 **pprog, u8 atomic_op,return 0 ; } -static bool ex_handler_bpf (const struct exception_table_entry *x, -struct pt_regs *regs,int trapnr, -unsigned long error_code,unsigned long fault_addr) +bool ex_handler_bpf (const struct exception_table_entry *x,struct pt_regs *regs) {u32 reg = x->fixup >>8 ;
@@ -1344,12 +1342,7 @@ st: if (is_imm8(insn->off)) } ex->insn = delta; - delta = (u8 *)ex_handler_bpf - (u8 *)&ex->handler; -if (!is_simm32 (delta)) { -pr_err ("extable->handler doesn't fit into 32-bit\n" ); -return -EFAULT ; - } - ex->handler = delta; + ex->type =EX_TYPE_BPF ;if (dst_reg >BPF_REG_9 ) {pr_err ("verifier error\n" );
scripts/sorttable.c +2 -2
@@ -240,7 +240,7 @@ static void x86_sort_relative_table(char *extab_image, int image_size)w (r (loc) + i, loc);w (r (loc +1 ) + i +4 , loc +1 ); -w (r (loc +2 ) + i +8 , loc +2 ); +/* Don't touch the fixup type */ i +=sizeof (uint32_t ) *3 ; }
@@ -253,7 +253,7 @@ static void x86_sort_relative_table(char *extab_image, int image_size)w (r (loc) - i, loc);w (r (loc +1 ) - (i +4 ), loc +1 ); -w (r (loc +2 ) - (i +8 ), loc +2 ); +/* Don't touch the fixup type */ i +=sizeof (uint32_t ) *3 ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 145/201 x86/extable: Provide EX_TYPE_DEFAULT_MCE_SAFE and EX_TYPE_FAULT_MCE_SAFE
In reply to Greg Kroah-HartmanFrom: Thomas Gleixner <[email protected]>
[ Upstream commit 2cadf5248b9316d3c8af876e795d61c55476f6e9 ]
Provide exception fixup types which can be used to identify fixups which allow in kernel #MC recovery and make them invoke the existing handlers.
These will be used at places where #MC recovery is handled correctly by the caller.
--- arch/x86/include/asm/extable_fixup_types.h | 3 +++ arch/x86/kernel/cpu/mce/severity.c | 2 ++ arch/x86/mm/extable.c | 2 ++ 3 files changed, 7 insertions(+)
arch/x86/include/asm/extable_fixup_types.h +3 -0
@@ -16,4 +16,7 @@#define EX_TYPE_WRMSR_IN_MCE 10#define EX_TYPE_RDMSR_IN_MCE 11 +#define EX_TYPE_DEFAULT_MCE_SAFE 12 +#define EX_TYPE_FAULT_MCE_SAFE 13 +#endif
arch/x86/kernel/cpu/mce/severity.c +2 -0
@@ -278,6 +278,8 @@ static int error_context(struct mce *m, struct pt_regs *regs) m->kflags |=MCE_IN_KERNEL_COPYIN ; fallthrough;case EX_TYPE_FAULT : +case EX_TYPE_FAULT_MCE_SAFE : +case EX_TYPE_DEFAULT_MCE_SAFE : m->kflags |=MCE_IN_KERNEL_RECOV ;return IN_KERNEL_RECOV ;default :
arch/x86/mm/extable.c +2 -0
@@ -131,8 +131,10 @@ int fixup_exception(struct pt_regs *regs, int trapnr, unsigned long error_code,switch (e->type) {case EX_TYPE_DEFAULT : +case EX_TYPE_DEFAULT_MCE_SAFE :return ex_handler_default (e, regs);case EX_TYPE_FAULT : +case EX_TYPE_FAULT_MCE_SAFE :return ex_handler_fault (e, regs, trapnr);case EX_TYPE_UACCESS :return ex_handler_uaccess (e, regs, trapnr);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 146/201 bitfield.h: Fix "type of reg too small for mask" test
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
[ Upstream commit bff8c3848e071d387d8b0784dc91fa49cd563774 ]
The test: 'mask > (typeof(_reg))~0ull' only works correctly when both sides are unsigned, consider:
- 0xff000000 vs (int)~0ull
- 0x000000ff vs (int)~0ull
--- include/linux/bitfield.h | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-)
include/linux/bitfield.h +18 -1
@@ -41,6 +41,22 @@#define __bf_shf (x) (__builtin_ffsll(x) - 1) +#define __scalar_type_to_unsigned_cases (type) \ + unsigned type: (unsigned type)0, \ + signed type: (unsigned type)0 + +#define __unsigned_scalar_typeof (x) typeof( \ + _Generic((x), \ + char: (unsigned char)0, \ + __scalar_type_to_unsigned_cases(char), \ + __scalar_type_to_unsigned_cases(short), \ + __scalar_type_to_unsigned_cases(int), \ + __scalar_type_to_unsigned_cases(long), \ + __scalar_type_to_unsigned_cases(long long), \ + default: (x))) + +#define __bf_cast_unsigned (type, x) ((__unsigned_scalar_typeof(type))(x)) +#define __BF_FIELD_CHECK (_mask, _reg, _val, _pfx) \ ({ \ BUILD_BUG_ON_MSG(!__builtin_constant_p(_mask), \
@@ -49,7 +65,8 @@BUILD_BUG_ON_MSG (__builtin_constant_p (_val) ? \ ~((_mask) >>__bf_shf (_mask)) & (_val) :0 , \ _pfx"value too large for the field" ); \ -BUILD_BUG_ON_MSG ((_mask) > (typeof (_reg ))~0ull , \ +BUILD_BUG_ON_MSG (__bf_cast_unsigned (_mask, _mask) > \ +__bf_cast_unsigned (_reg, ~0ull ), \ _pfx"type of reg too small for mask" ); \__BUILD_BUG_ON_NOT_POWER_OF_2 ((_mask) + \ (1ULL <<__bf_shf (_mask))); \
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 147/201 x86/entry_32: Remove .fixup usage
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
[ Upstream commit aa93e2ad7464ffb90155a5ffdde963816f86d5dc ]
Where possible, push the .fixup into code, at the tail of functions.
This is hard for macros since they're used in multiple functions, therefore introduce a new extable handler to pop zeros.
--- arch/x86/entry/entry_32.S | 28 +++++++--------------- arch/x86/include/asm/extable_fixup_types.h | 2 ++ arch/x86/mm/extable.c | 14 +++++++++++ 3 files changed, 24 insertions(+), 20 deletions(-)
arch/x86/entry/entry_32.S +8 -20
@@ -270,17 +270,9 @@ 3: popl %fs addl $(4 + \pop), %esp /* pop the unused "gs" slot */ IRET_FRAME -.pushsection .fixup, "ax" -4: movl $0, (%esp) - jmp 1b -5: movl $0, (%esp) - jmp 2b -6: movl $0, (%esp) - jmp 3b -.popsection - _ASM_EXTABLE(1b, 4b) - _ASM_EXTABLE(2b, 5b) - _ASM_EXTABLE(3b, 6b) + _ASM_EXTABLE_TYPE(1b, 1b, EX_TYPE_POP_ZERO) + _ASM_EXTABLE_TYPE(2b, 2b, EX_TYPE_POP_ZERO) + _ASM_EXTABLE_TYPE(3b, 3b, EX_TYPE_POP_ZERO) .endm .macro RESTORE_ALL_NMI cr3_reg:req pop=0
@@ -923,10 +915,8 @@ SYM_FUNC_START(entry_SYSENTER_32) sti sysexit -.pushsection .fixup, "ax" -2: movl $0, PT_FS(%esp) - jmp 1b -.popsection +2: movl $0, PT_FS(%esp) + jmp 1b _ASM_EXTABLE(1b, 2b) .Lsysenter_fix_flags:
@@ -994,8 +984,7 @@ restore_all_switch_stack: */ iret -.section .fixup, "ax" -SYM_CODE_START(asm_iret_error) +.Lasm_iret_error: pushl $0 # no error code pushl $iret_error
@@ -1012,9 +1001,8 @@ SYM_CODE_START(asm_iret_error) #endif jmp handle_exception -SYM_CODE_END(asm_iret_error) -.previous - _ASM_EXTABLE(.Lirq_return, asm_iret_error) + + _ASM_EXTABLE(.Lirq_return, .Lasm_iret_error) SYM_FUNC_END(entry_INT80_32) .macro FIXUP_ESPFIX_STACK
arch/x86/include/asm/extable_fixup_types.h +2 -0
@@ -19,4 +19,6 @@#define EX_TYPE_DEFAULT_MCE_SAFE 12#define EX_TYPE_FAULT_MCE_SAFE 13 +#define EX_TYPE_POP_ZERO 14 +#endif
arch/x86/mm/extable.c +14 -0
@@ -99,6 +99,18 @@ static bool ex_handler_clear_fs(const struct exception_table_entry *fixup,return ex_handler_default (fixup, regs); } +static bool ex_handler_pop_zero (const struct exception_table_entry *fixup, +struct pt_regs *regs) +{ +/* +* Typically used for when "pop %seg" traps, in which case we'll clear +* the stack slot and re-try the instruction, which will then succeed +* to pop zero. +*/ + *((unsigned long *)regs->sp) =0 ; +return ex_handler_default (fixup, regs); +} +int ex_get_fixup_type (unsigned long ip) {const struct exception_table_entry *e =search_exception_tables (ip);
@@ -156,6 +168,8 @@ int fixup_exception(struct pt_regs *regs, int trapnr, unsigned long error_code,case EX_TYPE_WRMSR_IN_MCE :ex_handler_msr_mce (regs, true);break ; +case EX_TYPE_POP_ZERO : +return ex_handler_pop_zero (e, regs); }BUG (); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 148/201 x86/extable: Extend extable functionality
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
[ Upstream commit 4b5305decc8436bfe363d1c1773e8fa1c828b14d ]
In order to remove further .fixup usage, extend the extable infrastructure to take additional information from the extable entry sites.
Specifically add _ASM_EXTABLE_TYPE_REG() and EX_TYPE_IMM_REG that extend the existing _ASM_EXTABLE_TYPE() by taking an additional register argument and encoding that and an s16 immediate into the existing s32 type field. This limits the actual types to the first byte, 255 seem plenty.
Also add a few flags into the type word, specifically CLEAR_AX and CLEAR_DX which clear the return and extended return register.
Notes:
- due to the % in our register names it's hard to make it more generally usable as arm64 did.
- the s16 is far larger than used in these patches, future extentions can easily shrink this to get more bits.
- without the bitfield fix this will not compile, because: 0xFF > -1 and we can't even extract the TYPE field.
[nathanchance: Build fix for clang-lto builds:
https://lkml.kernel.org/r/[email protected]
]
--- arch/x86/include/asm/asm.h | 37 ++++++++++++ arch/x86/include/asm/extable.h | 6 +- arch/x86/include/asm/extable_fixup_types.h | 24 ++++++++ arch/x86/include/asm/insn-eval.h | 2 + arch/x86/lib/insn-eval.c | 66 ++++++++++++++-------- arch/x86/mm/extable.c | 40 +++++++++++-- arch/x86/net/bpf_jit_comp.c | 2 +- 7 files changed, 145 insertions(+), 32 deletions(-)
arch/x86/include/asm/asm.h +37 -0
@@ -147,6 +147,33 @@#else /* ! __ASSEMBLY__ */ +# define DEFINE_EXTABLE_TYPE_REG \ + ".macro extable_type_reg type:req reg:req\n" \ + ".set found, 0\n" \ + ".set regnr, 0\n" \ + ".irp rs,rax,rcx,rdx,rbx,rsp,rbp,rsi,rdi,r8,r9,r10,r11,r12,r13,r14,r15\n" \ + ".ifc \\reg, %%\\rs\n" \ + ".set found, found+1\n" \ + ".long \\type + (regnr << 8)\n" \ + ".endif\n" \ + ".set regnr, regnr+1\n" \ + ".endr\n" \ + ".set regnr, 0\n" \ + ".irp rs,eax,ecx,edx,ebx,esp,ebp,esi,edi,r8d,r9d,r10d,r11d,r12d,r13d,r14d,r15d\n" \ + ".ifc \\reg, %%\\rs\n" \ + ".set found, found+1\n" \ + ".long \\type + (regnr << 8)\n" \ + ".endif\n" \ + ".set regnr, regnr+1\n" \ + ".endr\n" \ + ".if (found != 1)\n" \ + ".error \"extable_type_reg: bad register argument\"\n" \ + ".endif\n" \ + ".endm\n" + +# define UNDEFINE_EXTABLE_TYPE_REG \ + ".purgem extable_type_reg\n" +# define _ASM_EXTABLE_TYPE (from, to, type) \ " .pushsection \"__ex_table\",\"a\"\n" \ " .balign 4\n" \
@@ -155,6 +182,16 @@ " .long " __stringify(type) " \n" \ " .popsection\n" +# define _ASM_EXTABLE_TYPE_REG (from, to, type, reg) \ + " .pushsection \"__ex_table\",\"a\"\n" \ + " .balign 4\n" \ + " .long (" #from ") - .\n" \ + " .long (" #to ") - .\n" \ + DEFINE_EXTABLE_TYPE_REG \ + "extable_type_reg reg=" __stringify(reg) ", type=" __stringify(type) " \n"\ + UNDEFINE_EXTABLE_TYPE_REG \ + " .popsection\n" +/* For C file, we already have NOKPROBE_SYMBOL macro */ /*
arch/x86/include/asm/extable.h +3 -3
@@ -21,7 +21,7 @@*/ struct exception_table_entry { -int insn, fixup, type; +int insn, fixup, data; };struct pt_regs ;
@@ -31,8 +31,8 @@ struct pt_regs;do { \ (a)->fixup = (b)->fixup + (delta); \ (b)->fixup = (tmp).fixup - (delta); \ - (a)->type = (b)->type; \ - (b)->type = (tmp).type; \ + (a)->data = (b)->data; \ + (b)->data = (tmp).data; \ } while (0) extern int fixup_exception(struct pt_regs *regs, int trapnr,
arch/x86/include/asm/extable_fixup_types.h +24 -0
@@ -2,6 +2,29 @@#ifndef _ASM_X86_EXTABLE_FIXUP_TYPES_H#define _ASM_X86_EXTABLE_FIXUP_TYPES_H +/* +* Our IMM is signed, as such it must live at the top end of the word. Also, +* since C99 hex constants are of ambigious type, force cast the mask to 'int' +* so that FIELD_GET() will DTRT and sign extend the value when it extracts it. +*/ +#define EX_DATA_TYPE_MASK ((int)0x000000FF) +#define EX_DATA_REG_MASK ((int)0x00000F00) +#define EX_DATA_FLAG_MASK ((int)0x0000F000) +#define EX_DATA_IMM_MASK ((int)0xFFFF0000) + +#define EX_DATA_REG_SHIFT 8 +#define EX_DATA_FLAG_SHIFT 12 +#define EX_DATA_IMM_SHIFT 16 + +#define EX_DATA_FLAG (flag) ((flag) << EX_DATA_FLAG_SHIFT) +#define EX_DATA_IMM (imm) ((imm) << EX_DATA_IMM_SHIFT) + +/* flags */ +#define EX_FLAG_CLEAR_AX EX_DATA_FLAG(1) +#define EX_FLAG_CLEAR_DX EX_DATA_FLAG(2) +#define EX_FLAG_CLEAR_AX_DX EX_DATA_FLAG(3) + +/* types */ #define EX_TYPE_NONE 0#define EX_TYPE_DEFAULT 1#define EX_TYPE_FAULT 2
@@ -20,5 +43,6 @@#define EX_TYPE_FAULT_MCE_SAFE 13#define EX_TYPE_POP_ZERO 14 +#define EX_TYPE_IMM_REG 15/* reg := (long)imm */ #endif
arch/x86/include/asm/insn-eval.h +2 -0
@@ -15,6 +15,8 @@#define INSN_CODE_SEG_OPND_SZ (params) (params & 0xf)#define INSN_CODE_SEG_PARAMS (oper_sz, addr_sz) (oper_sz | (addr_sz << 4)) +int pt_regs_offset (struct pt_regs *regs,int regno); +bool insn_has_rep_prefix (struct insn *insn);void __user *insn_get_addr_ref (struct insn *insn,struct pt_regs *regs);int insn_get_modrm_rm_off (struct insn *insn,struct pt_regs *regs);
arch/x86/lib/insn-eval.c +42 -24
81 lines not on this page · raw message
arch/x86/mm/extable.c +36 -4
@@ -2,12 +2,25 @@#include <linux/extable.h> #include <linux/uaccess.h> #include <linux/sched/debug.h> +#include <linux/bitfield.h> #include <xen/xen.h> #include <asm/fpu/internal.h> #include <asm/sev.h> #include <asm/traps.h> #include <asm/kdebug.h> +#include <asm/insn-eval.h> + +static inline unsigned long *pt_regs_nr (struct pt_regs *regs,int nr) +{ +int reg_offset =pt_regs_offset (regs, nr); +static unsigned long __dummy; + +if (WARN_ON_ONCE (reg_offset <0 )) +return &__dummy; + +return (unsigned long *)((unsigned long )regs + reg_offset); +}static inline unsigned long ex_fixup_addr (const struct exception_table_entry *x)
@@ -15,10 +28,15 @@ ex_fixup_addr(const struct exception_table_entry *x)return (unsigned long )&x->fixup + x->fixup; } -static bool ex_handler_default (const struct exception_table_entry *fixup, +static bool ex_handler_default (const struct exception_table_entry *e,struct pt_regs *regs) { - regs->ip =ex_fixup_addr (fixup); +if (e->data &EX_FLAG_CLEAR_AX ) + regs->ax =0 ; +if (e->data &EX_FLAG_CLEAR_DX ) + regs->dx =0 ; + + regs->ip =ex_fixup_addr (e);return true; }
@@ -111,17 +129,25 @@ static bool ex_handler_pop_zero(const struct exception_table_entry *fixup,return ex_handler_default (fixup, regs); } +static bool ex_handler_imm_reg (const struct exception_table_entry *fixup, +struct pt_regs *regs,int reg,int imm) +{ + *pt_regs_nr (regs, reg) = (long )imm; +return ex_handler_default (fixup, regs); +} +int ex_get_fixup_type (unsigned long ip) {const struct exception_table_entry *e =search_exception_tables (ip); -return e ? e->type :EX_TYPE_NONE ; +return e ?FIELD_GET (EX_DATA_TYPE_MASK , e->data) :EX_TYPE_NONE ; }int fixup_exception (struct pt_regs *regs,int trapnr,unsigned long error_code,unsigned long fault_addr) {const struct exception_table_entry *e; +int type, reg, imm;#ifdef CONFIG_PNPBIOS if (unlikely (SEGMENT_IS_PNP_CODE (regs->cs))) {
@@ -141,7 +167,11 @@ int fixup_exception(struct pt_regs *regs, int trapnr, unsigned long error_code,if (!e)return 0 ; -switch (e->type) { + type =FIELD_GET (EX_DATA_TYPE_MASK , e->data); + reg =FIELD_GET (EX_DATA_REG_MASK , e->data); + imm =FIELD_GET (EX_DATA_IMM_MASK , e->data); + +switch (type) {case EX_TYPE_DEFAULT :case EX_TYPE_DEFAULT_MCE_SAFE :return ex_handler_default (e, regs);
@@ -170,6 +200,8 @@ int fixup_exception(struct pt_regs *regs, int trapnr, unsigned long error_code,break ;case EX_TYPE_POP_ZERO :return ex_handler_pop_zero (e, regs); +case EX_TYPE_IMM_REG : +return ex_handler_imm_reg (e, regs, reg, imm); }BUG (); }
arch/x86/net/bpf_jit_comp.c +1 -1
@@ -1342,7 +1342,7 @@ st: if (is_imm8(insn->off)) } ex->insn = delta; - ex->type =EX_TYPE_BPF ; + ex->data =EX_TYPE_BPF ;if (dst_reg >BPF_REG_9 ) {pr_err ("verifier error\n" );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 149/201 x86/msr: Remove .fixup usage
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
[ Upstream commit d52a7344bdfa9c3442d3f86fb3501d9343726c76 ]
Rework the MSR accessors to remove .fixup usage. Add two new extable types (to the 4 already existing msr ones) using the new register infrastructure to record which register should get the error value.
--- arch/x86/include/asm/extable_fixup_types.h | 23 +++++----- arch/x86/include/asm/msr.h | 26 ++++------- arch/x86/mm/extable.c | 51 ++++++++++++---------- 3 files changed, 47 insertions(+), 53 deletions(-)
arch/x86/include/asm/extable_fixup_types.h +11 -12
@@ -32,17 +32,16 @@#define EX_TYPE_COPY 4#define EX_TYPE_CLEAR_FS 5#define EX_TYPE_FPU_RESTORE 6 -#define EX_TYPE_WRMSR 7 -#define EX_TYPE_RDMSR 8 -#define EX_TYPE_BPF 9 - -#define EX_TYPE_WRMSR_IN_MCE 10 -#define EX_TYPE_RDMSR_IN_MCE 11 - -#define EX_TYPE_DEFAULT_MCE_SAFE 12 -#define EX_TYPE_FAULT_MCE_SAFE 13 - -#define EX_TYPE_POP_ZERO 14 -#define EX_TYPE_IMM_REG 15/* reg := (long)imm */ +#define EX_TYPE_BPF 7 +#define EX_TYPE_WRMSR 8 +#define EX_TYPE_RDMSR 9 +#define EX_TYPE_WRMSR_SAFE 10/* reg := -EIO */ +#define EX_TYPE_RDMSR_SAFE 11/* reg := -EIO */ +#define EX_TYPE_WRMSR_IN_MCE 12 +#define EX_TYPE_RDMSR_IN_MCE 13 +#define EX_TYPE_DEFAULT_MCE_SAFE 14 +#define EX_TYPE_FAULT_MCE_SAFE 15 +#define EX_TYPE_POP_ZERO 16 +#define EX_TYPE_IMM_REG 17/* reg := (long)imm */ #endif
arch/x86/include/asm/msr.h +8 -18
@@ -137,17 +137,11 @@ static inline unsigned long long native_read_msr_safe(unsigned int msr, {DECLARE_ARGS (val, low, high); - asmvolatile ("2: rdmsr ; xor %[err],%[err]\n" -"1:\n\t" -".section .fixup,\"ax\"\n\t" -"3: mov %[fault],%[err]\n\t" -"xorl %%eax, %%eax\n\t" -"xorl %%edx, %%edx\n\t" -"jmp 1b\n\t" -".previous\n\t" - _ASM_EXTABLE(2b, 3b) + asmvolatile ("1: rdmsr ; xor %[err],%[err]\n" +"2:\n\t" + _ASM_EXTABLE_TYPE_REG(1b, 2b, EX_TYPE_RDMSR_SAFE, %[err]) : [err] "=r" (*err), EAX_EDX_RET(val, low, high) - : "c" (msr), [fault] "i" (-EIO)); + : "c" (msr)); if (tracepoint_enabled(read_msr))do_trace_read_msr (msr,EAX_EDX_VAL (val, low, high), *err);return EAX_EDX_VAL (val, low, high);
@@ -169,15 +163,11 @@ native_write_msr_safe(unsigned int msr, u32 low, u32 high) {int err; - asmvolatile ("2: wrmsr ; xor %[err],%[err]\n" -"1:\n\t" -".section .fixup,\"ax\"\n\t" -"3: mov %[fault],%[err] ; jmp 1b\n\t" -".previous\n\t" - _ASM_EXTABLE(2b, 3b) + asmvolatile ("1: wrmsr ; xor %[err],%[err]\n" +"2:\n\t" + _ASM_EXTABLE_TYPE_REG(1b, 2b, EX_TYPE_WRMSR_SAFE, %[err]) : [err] "=a" (err) - : "c" (msr), "0" (low), "d" (high), - [fault] "i" (-EIO) + : "c" (msr), "0" (low), "d" (high) : "memory"); if (tracepoint_enabled(write_msr))do_trace_write_msr (msr, ((u64 )high <<32 | low), err);
arch/x86/mm/extable.c +28 -23
74 lines not on this page · raw message
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 150/201 x86/futex: Remove .fixup usage
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
[ Upstream commit 4c132d1d844a53fc4e4b5c34e36ef10d6124b783 ]
Use the new EX_TYPE_IMM_REG to store -EFAULT into the designated 'ret' register, this removes the need for anonymous .fixup code.
--- arch/x86/include/asm/extable_fixup_types.h | 2 ++ arch/x86/include/asm/futex.h | 28 +++++++--------------- 2 files changed, 10 insertions(+), 20 deletions(-)
arch/x86/include/asm/extable_fixup_types.h +2 -0
@@ -42,6 +42,8 @@#define EX_TYPE_DEFAULT_MCE_SAFE 14#define EX_TYPE_FAULT_MCE_SAFE 15#define EX_TYPE_POP_ZERO 16 +#define EX_TYPE_IMM_REG 17/* reg := (long)imm */ +#define EX_TYPE_EFAULT_REG (EX_TYPE_IMM_REG | EX_DATA_IMM(-EFAULT))#endif
arch/x86/include/asm/futex.h +8 -20
@@ -17,13 +17,9 @@ do { \int oldval =0 , ret; \ asmvolatile ("1:\t" insn"\n" \"2:\n" \ -"\t.section .fixup,\"ax\"\n" \ -"3:\tmov\t%3, %1\n" \ -"\tjmp\t2b\n" \ -"\t.previous\n" \ - _ASM_EXTABLE_UA(1b, 3b) \ + _ASM_EXTABLE_TYPE_REG(1b, 2b, EX_TYPE_EFAULT_REG, %1) \ : "=r" (oldval), "=r" (ret), "+m" (*uaddr) \ - : "i" (-EFAULT), "0" (oparg), "1" (0)); \ + : "0" (oparg), "1" (0)); \if (ret) \ goto label; \ *oval = oldval; \
@@ -39,15 +35,11 @@ do { \"3:\t" LOCK_PREFIX "cmpxchgl %3, %2\n" \"\tjnz\t2b\n" \"4:\n" \ -"\t.section .fixup,\"ax\"\n" \ -"5:\tmov\t%5, %1\n" \ -"\tjmp\t4b\n" \ -"\t.previous\n" \ - _ASM_EXTABLE_UA(1b, 5b) \ -_ASM_EXTABLE_UA (3b ,5b ) \ + _ASM_EXTABLE_TYPE_REG(1b, 4b, EX_TYPE_EFAULT_REG, %1) \ + _ASM_EXTABLE_TYPE_REG(3b, 4b, EX_TYPE_EFAULT_REG, %1) \ : "=&a" (oldval), "=&r" (ret), \ "+m" (*uaddr), "=&r" (tem) \ - : "r" (oparg), "i" (-EFAULT), "1" (0)); \ + : "r" (oparg), "1" (0)); \if (ret) \ goto label; \ *oval = oldval; \
@@ -95,15 +87,11 @@ static inline int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,if (!user_access_begin (uaddr,sizeof (u32)))return -EFAULT ; asmvolatile ("\n" -"1:\t" LOCK_PREFIX "cmpxchgl %4, %2\n" +"1:\t" LOCK_PREFIX "cmpxchgl %3, %2\n" "2:\n" -"\t.section .fixup, \"ax\"\n" -"3:\tmov %3, %0\n" -"\tjmp 2b\n" -"\t.previous\n" - _ASM_EXTABLE_UA(1b, 3b) + _ASM_EXTABLE_TYPE_REG(1b, 2b, EX_TYPE_EFAULT_REG, %0) \ : "+r" (ret), "=a" (oldval), "+m" (*uaddr) - : "i" (-EFAULT), "r" (newval), "1" (oldval) + : "r" (newval), "1" (oldval) : "memory" );user_access_end ();
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 151/201 KVM: x86: Use __try_cmpxchg_user() to emulate atomic accesses
In reply to Greg Kroah-HartmanFrom: Sean Christopherson <[email protected]>
[ Upstream commit 1c2361f667f3648855ceae25f1332c18413fdb9f ]
Use the recently introduce __try_cmpxchg_user() to emulate atomic guest accesses via the associated userspace address instead of mapping the backing pfn into kernel address space. Using kvm_vcpu_map() is unsafe as it does not coordinate with KVM's mmu_notifier to ensure the hva=>pfn translation isn't changed/unmapped in the memremap() path, i.e. when there's no struct page and thus no elevated refcount.
Message-Id: <[email protected]>
--- arch/x86/kvm/x86.c | 35 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 21 deletions(-)
arch/x86/kvm/x86.c +14 -21
@@ -6894,15 +6894,8 @@ static int emulator_write_emulated(struct x86_emulate_ctxt *ctxt, exception, &write_emultor); } -#define CMPXCHG_TYPE (t, ptr, old, new) \ - (cmpxchg((t *)(ptr), *(t *)(old), *(t *)(new)) == *(t *)(old)) - -#ifdef CONFIG_X86_64 -# define CMPXCHG64 (ptr, old, new) CMPXCHG_TYPE(u64, ptr, old, new) -#else -# define CMPXCHG64 (ptr, old, new) \ - (cmpxchg64((u64 *)(ptr), *(u64 *)(old), *(u64 *)(new)) == *(u64 *)(old)) -#endif +#define emulator_try_cmpxchg_user (t, ptr, old, new) \ + (__try_cmpxchg_user((t __user *)(ptr), (t *)(old), *(t *)(new), efault ## t)) static int emulator_cmpxchg_emulated(struct x86_emulate_ctxt *ctxt, unsigned long addr,
@@ -6911,12 +6904,11 @@ static int emulator_cmpxchg_emulated(struct x86_emulate_ctxt *ctxt,unsigned int bytes, struct x86_exception *exception) { - struct kvm_host_map map; struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);u64 page_line_mask; +unsigned long hva;gpa_t gpa; -char *kaddr; -bool exchanged; +int r;/* guests cmpxchg8b have to be emulated atomically */ if (bytes >8 || (bytes & (bytes -1 )))
@@ -6940,31 +6932,32 @@ static int emulator_cmpxchg_emulated(struct x86_emulate_ctxt *ctxt,if (((gpa + bytes -1 ) & page_line_mask) != (gpa & page_line_mask)) goto emul_write; -if (kvm_vcpu_map (vcpu,gpa_to_gfn (gpa), &map)) + hva =kvm_vcpu_gfn_to_hva (vcpu,gpa_to_gfn (gpa)); +if (kvm_is_error_hva (addr)) goto emul_write; - kaddr = map.hva +offset_in_page (gpa); + hva +=offset_in_page (gpa);switch (bytes) {case 1 : - exchanged =CMPXCHG_TYPE (u8, kaddr, old, new); + r =emulator_try_cmpxchg_user (u8, hva, old, new);break ;case 2 : - exchanged =CMPXCHG_TYPE (u16, kaddr, old, new); + r =emulator_try_cmpxchg_user (u16, hva, old, new);break ;case 4 : - exchanged =CMPXCHG_TYPE (u32, kaddr, old, new); + r =emulator_try_cmpxchg_user (u32, hva, old, new);break ;case 8 : - exchanged =CMPXCHG64 (kaddr, old, new); + r =emulator_try_cmpxchg_user (u64, hva, old, new);break ;default :BUG (); } -kvm_vcpu_unmap (vcpu, &map, true); - -if (!exchanged) +if (r <0 ) + goto emul_write; +if (r)return X86EMUL_CMPXCHG_FAILED ;kvm_page_track_write (vcpu, gpa, new, bytes);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 152/201 xhci: dbc: refactor xhci_dbc_init()
In reply to Greg Kroah-HartmanFrom: Mathias Nyman <[email protected]>
[ Upstream commit 534675942e901959b5d8dc11ea526c4e48817d8e ]
Refactor xhci_dbc_init(), splitting it into logical parts closer to the Linux device model.
- Create the fake dbc device, depends on xhci strucure
- Allocate a dbc structure, xhci agnostic
- Call xhci_dbc_tty_probe(), similar to actual probe.
Adjustments to xhci_dbc_exit and xhci_dbc_remove are also needed as a result to the xhci_dbc_init() changes
Mostly non-functional changes, except for creating the dbc sysfs entry earlier, together with the dbc structure.
--- drivers/usb/host/xhci-dbgcap.c | 124 ++++++++++++++++++--------------- 1 file changed, 66 insertions(+), 58 deletions(-)
drivers/usb/host/xhci-dbgcap.c +66 -58
@@ -924,49 +924,6 @@ static void xhci_do_dbc_exit(struct xhci_hcd *xhci)spin_unlock_irqrestore (&xhci->lock, flags); } -static int xhci_do_dbc_init (struct xhci_hcd *xhci) -{ -u32 reg; -struct xhci_dbc *dbc; -unsigned long flags; -void __iomem *base; -int dbc_cap_offs; - - base = &xhci->cap_regs->hc_capbase; - dbc_cap_offs =xhci_find_next_ext_cap (base,0 ,XHCI_EXT_CAPS_DEBUG ); -if (!dbc_cap_offs) -return -ENODEV ; - - dbc =kzalloc (sizeof (*dbc),GFP_KERNEL ); -if (!dbc) -return -ENOMEM ; - - dbc->regs = base + dbc_cap_offs; - -/* We will avoid using DbC in xhci driver if it's in use. */ - reg =readl (&dbc->regs->control); -if (reg &DBC_CTRL_DBC_ENABLE ) { -kfree (dbc); -return -EBUSY ; - } - -spin_lock_irqsave (&xhci->lock, flags); -if (xhci->dbc) { -spin_unlock_irqrestore (&xhci->lock, flags); -kfree (dbc); -return -EBUSY ; - } - xhci->dbc = dbc; -spin_unlock_irqrestore (&xhci->lock, flags); - - dbc->xhci = xhci; - dbc->dev =xhci_to_hcd (xhci)->self.sysdev; -INIT_DELAYED_WORK (&dbc->event_work, xhci_dbc_handle_events); -spin_lock_init (&dbc->lock); - -return 0 ; -} -static ssize_t dbc_show (struct device *dev,struct device_attribute *attr,char *buf)
@@ -1026,44 +983,95 @@ static ssize_t dbc_store(struct device *dev,static DEVICE_ATTR_RW (dbc); -int xhci_dbc_init (struct xhci_hcd *xhci) +struct xhci_dbc * +xhci_alloc_dbc (struct device *dev,void __iomem *base) { +struct xhci_dbc *dbc;int ret; -struct device *dev =xhci_to_hcd (xhci)->self.controller; - ret =xhci_do_dbc_init (xhci); + dbc =kzalloc (sizeof (*dbc),GFP_KERNEL ); +if (!dbc) +return NULL ; + + dbc->regs = base; + dbc->dev = dev; + +if (readl (&dbc->regs->control) &DBC_CTRL_DBC_ENABLE ) +return NULL ; + +INIT_DELAYED_WORK (&dbc->event_work, xhci_dbc_handle_events); +spin_lock_init (&dbc->lock); + + ret =device_create_file (dev, &dev_attr_dbc);if (ret) - goto init_err3; + goto err; + +return dbc; +err: +kfree (dbc); +return NULL ; +} + +/* undo what xhci_alloc_dbc() did */ +void xhci_dbc_remove (struct xhci_dbc *dbc) +{ +if (!dbc) +return ; +/* stop hw, stop wq and call dbc->ops->stop() */ +xhci_dbc_stop (dbc); + +/* remove sysfs files */ +device_remove_file (dbc->dev, &dev_attr_dbc); + +kfree (dbc); +} + +int xhci_dbc_init (struct xhci_hcd *xhci) +{ +struct device *dev; +void __iomem *base; +int ret; +int dbc_cap_offs; + +/* create all parameters needed resembling a dbc device */ + dev =xhci_to_hcd (xhci)->self.controller; + base = &xhci->cap_regs->hc_capbase; + + dbc_cap_offs =xhci_find_next_ext_cap (base,0 ,XHCI_EXT_CAPS_DEBUG ); +if (!dbc_cap_offs) +return -ENODEV ; + +/* already allocated and in use */ +if (xhci->dbc) +return -EBUSY ; + + xhci->dbc =xhci_alloc_dbc (dev, base); +if (!xhci->dbc) +return -ENOMEM ; ret =xhci_dbc_tty_probe (xhci);if (ret) goto init_err2; - ret =device_create_file (dev, &dev_attr_dbc); -if (ret) - goto init_err1; -return 0 ; -init_err1: -xhci_dbc_tty_remove (xhci->dbc); init_err2:xhci_do_dbc_exit (xhci); -init_err3:return ret; }void xhci_dbc_exit (struct xhci_hcd *xhci) { -struct device *dev =xhci_to_hcd (xhci)->self.controller; +unsigned long flags;if (!xhci->dbc)return ; -device_remove_file (dev, &dev_attr_dbc);xhci_dbc_tty_remove (xhci->dbc); -xhci_dbc_stop (xhci->dbc); -xhci_do_dbc_exit (xhci); +xhci_dbc_remove (xhci->dbc); +spin_lock_irqsave (&xhci->lock, flags); + xhci->dbc =NULL ; +spin_unlock_irqrestore (&xhci->lock, flags); }#ifdef CONFIG_PM
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 153/201 xhci: dbc: create and remove dbc structure in dbgtty driver.
In reply to Greg Kroah-HartmanFrom: Mathias Nyman <[email protected]>
[ Upstream commit 5ce036b98dd3301fc43bb06a6383ef07b6c776bc ]
Turn the dbgtty closer to a device driver by allocating the dbc structure in its own xhci_dbc_tty_probe() function, and freeing it in xhci_dbc_tty_remove()
Remove xhci_do_dbc_exit() as its no longer needed.
allocate and create the dbc strcuture in xhci_dbc_tty_probe()
--- drivers/usb/host/xhci-dbgcap.c | 26 +++----------------------- drivers/usb/host/xhci-dbgcap.h | 5 ++++- drivers/usb/host/xhci-dbgtty.c | 22 +++++++++++++++------- 3 files changed, 22 insertions(+), 31 deletions(-)
drivers/usb/host/xhci-dbgcap.c +3 -23
@@ -914,16 +914,6 @@ static void xhci_dbc_handle_events(struct work_struct *work)mod_delayed_work (system_wq, &dbc->event_work,1 ); } -static void xhci_do_dbc_exit (struct xhci_hcd *xhci) -{ -unsigned long flags; - -spin_lock_irqsave (&xhci->lock, flags); -kfree (xhci->dbc); - xhci->dbc =NULL ; -spin_unlock_irqrestore (&xhci->lock, flags); -} -static ssize_t dbc_show (struct device *dev,struct device_attribute *attr,char *buf)
@@ -984,7 +974,7 @@ static ssize_t dbc_store(struct device *dev,static DEVICE_ATTR_RW (dbc);struct xhci_dbc * -xhci_alloc_dbc (struct device *dev,void __iomem *base) +xhci_alloc_dbc (struct device *dev,void __iomem *base,const struct dbc_driver *driver) {struct xhci_dbc *dbc;int ret;
@@ -995,6 +985,7 @@ xhci_alloc_dbc(struct device *dev, void __iomem *base) dbc->regs = base; dbc->dev = dev; + dbc->driver = driver;if (readl (&dbc->regs->control) &DBC_CTRL_DBC_ENABLE )return NULL ;
@@ -1045,18 +1036,8 @@ int xhci_dbc_init(struct xhci_hcd *xhci)if (xhci->dbc)return -EBUSY ; - xhci->dbc =xhci_alloc_dbc (dev, base); -if (!xhci->dbc) -return -ENOMEM ; - - ret =xhci_dbc_tty_probe (xhci); -if (ret) - goto init_err2; - -return 0 ; + ret =xhci_dbc_tty_probe (dev, base + dbc_cap_offs, xhci); -init_err2: -xhci_do_dbc_exit (xhci);return ret; }
@@ -1068,7 +1049,6 @@ void xhci_dbc_exit(struct xhci_hcd *xhci)return ;xhci_dbc_tty_remove (xhci->dbc); -xhci_dbc_remove (xhci->dbc);spin_lock_irqsave (&xhci->lock, flags); xhci->dbc =NULL ;spin_unlock_irqrestore (&xhci->lock, flags);
drivers/usb/host/xhci-dbgcap.h +4 -1
@@ -196,8 +196,11 @@ static inline struct dbc_ep *get_out_ep(struct xhci_dbc *dbc)#ifdef CONFIG_USB_XHCI_DBGCAP int xhci_dbc_init (struct xhci_hcd *xhci);void xhci_dbc_exit (struct xhci_hcd *xhci); -int xhci_dbc_tty_probe (struct xhci_hcd *xhci); +int xhci_dbc_tty_probe (struct device *dev,void __iomem *res,struct xhci_hcd *xhci);void xhci_dbc_tty_remove (struct xhci_dbc *dbc); +struct xhci_dbc *xhci_alloc_dbc (struct device *dev,void __iomem *res, +const struct dbc_driver *driver); +void xhci_dbc_remove (struct xhci_dbc *dbc);struct dbc_request *dbc_alloc_request (struct xhci_dbc *dbc,unsigned int direction,gfp_t flags);
drivers/usb/host/xhci-dbgtty.c +15 -7
@@ -468,9 +468,9 @@ static const struct dbc_driver dbc_driver = { .disconnect = xhci_dbc_tty_unregister_device, }; -int xhci_dbc_tty_probe (struct xhci_hcd *xhci) +int xhci_dbc_tty_probe (struct device *dev,void __iomem *base,struct xhci_hcd *xhci) { -struct xhci_dbc *dbc = xhci->dbc; +struct xhci_dbc *dbc;struct dbc_port *port;int status;
@@ -485,13 +485,22 @@ int xhci_dbc_tty_probe(struct xhci_hcd *xhci) goto out; } - dbc->driver = &dbc_driver; - dbc->priv = port; + dbc_tty_driver->driver_state = port; + + dbc =xhci_alloc_dbc (dev, base, &dbc_driver); +if (!dbc) { + status = -ENOMEM ; + goto out2; + } + dbc->priv = port; - dbc_tty_driver->driver_state = port; +/* get rid of xhci once this is a real driver binding to a device */ + xhci->dbc = dbc;return 0 ; +out2: +kfree (port); out:/* dbc_tty_exit will be called by module_exit() in the future */ dbc_tty_exit ();
@@ -506,8 +515,7 @@ void xhci_dbc_tty_remove(struct xhci_dbc *dbc) {struct dbc_port *port =dbc_to_port (dbc); - dbc->driver =NULL ; - dbc->priv =NULL ; +xhci_dbc_remove (dbc);kfree (port);/* dbc_tty_exit will be called by module_exit() in the future */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 154/201 xhci: dbc: Rename xhci_dbc_init and xhci_dbc_exit
In reply to Greg Kroah-HartmanFrom: Mathias Nyman <[email protected]>
[ Upstream commit 5c44d9d7570b244ca08fef817c4c90aa7a1f1b5f ]
These names give the impression the functions are related to module init calls, but are in fact creating and removing the dbc fake device
Rename them to xhci_create_dbc_dev() and xhci_remove_dbc_dev().
We will need the _init and _exit names for actual dbc module init and exit calls.
No functional changes
--- drivers/usb/host/xhci-dbgcap.c | 5 +++-- drivers/usb/host/xhci-dbgcap.h | 8 ++++---- drivers/usb/host/xhci.c | 4 ++-- 3 files changed, 9 insertions(+), 8 deletions(-)
drivers/usb/host/xhci-dbgcap.c +3 -2
@@ -1017,7 +1017,8 @@ void xhci_dbc_remove(struct xhci_dbc *dbc)kfree (dbc); } -int xhci_dbc_init (struct xhci_hcd *xhci) + +int xhci_create_dbc_dev (struct xhci_hcd *xhci) {struct device *dev;void __iomem *base;
@@ -1041,7 +1042,7 @@ int xhci_dbc_init(struct xhci_hcd *xhci)return ret; } -void xhci_dbc_exit (struct xhci_hcd *xhci) +void xhci_remove_dbc_dev (struct xhci_hcd *xhci) {unsigned long flags;
drivers/usb/host/xhci-dbgcap.h +4 -4
@@ -194,8 +194,8 @@ static inline struct dbc_ep *get_out_ep(struct xhci_dbc *dbc) }#ifdef CONFIG_USB_XHCI_DBGCAP -int xhci_dbc_init (struct xhci_hcd *xhci); -void xhci_dbc_exit (struct xhci_hcd *xhci); +int xhci_create_dbc_dev (struct xhci_hcd *xhci); +void xhci_remove_dbc_dev (struct xhci_hcd *xhci);int xhci_dbc_tty_probe (struct device *dev,void __iomem *res,struct xhci_hcd *xhci);void xhci_dbc_tty_remove (struct xhci_dbc *dbc); struct xhci_dbc *xhci_alloc_dbc(struct device *dev, void __iomem *res,
@@ -211,12 +211,12 @@ int xhci_dbc_suspend(struct xhci_hcd *xhci);int xhci_dbc_resume (struct xhci_hcd *xhci);#endif /* CONFIG_PM */ #else -static inline int xhci_dbc_init (struct xhci_hcd *xhci) +static inline int xhci_create_dbc_dev (struct xhci_hcd *xhci) {return 0 ; } -static inline void xhci_dbc_exit (struct xhci_hcd *xhci) +static inline void xhci_remove_dbc_dev (struct xhci_hcd *xhci) { }
drivers/usb/host/xhci.c +2 -2
@@ -693,7 +693,7 @@ int xhci_run(struct usb_hcd *hcd)xhci_dbg_trace (xhci, trace_xhci_dbg_init,"Finished xhci_run for USB2 roothub" ); -xhci_dbc_init (xhci); +xhci_create_dbc_dev (xhci);xhci_debugfs_init (xhci);
@@ -723,7 +723,7 @@ static void xhci_stop(struct usb_hcd *hcd)return ; } -xhci_dbc_exit (xhci); +xhci_remove_dbc_dev (xhci);spin_lock_irq (&xhci->lock); xhci->xhc_state |=XHCI_STATE_HALTED ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 155/201 xhci: Set HCD flag to defer primary roothub registration
In reply to Greg Kroah-HartmanFrom: Kishon Vijay Abraham I <[email protected]>
[ Upstream commit b7a4f9b5d0e4b6dd937678c546c0b322dd1a4054 ]
Set "HCD_FLAG_DEFER_RH_REGISTER" to hcd->flags in xhci_run() to defer registering primary roothub in usb_add_hcd() if xhci has two roothubs. This will make sure both primary roothub and secondary roothub will be registered along with the second HCD.
This is required for cold plugged USB devices to be detected in certain PCIe USB cards (like Inateck USB card connected to AM64 EVM or J7200 EVM).
This patch has been added and reverted earier as it triggered a race in usb device enumeration.
That race is now fixed in 5.16-rc3, and in stable back to 5.4 commit 6cca13de26ee ("usb: hub: Fix locking issues with address0_mutex") commit 6ae6dc22d2d1 ("usb: hub: Fix usb enumeration issue due to address0 race")
[minor rebase change, and commit message update -Mathias]
--- drivers/usb/host/xhci.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/usb/host/xhci.c +2 -0
@@ -693,6 +693,8 @@ int xhci_run(struct usb_hcd *hcd)xhci_dbg_trace (xhci, trace_xhci_dbg_init,"Finished xhci_run for USB2 roothub" ); +set_bit (HCD_FLAG_DEFER_RH_REGISTER , &hcd->flags); +xhci_create_dbc_dev (xhci);xhci_debugfs_init (xhci);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 156/201 mt76: fix use-after-free by removing a non-RCU wcid pointer
In reply to Greg Kroah-HartmanFrom: Felix Fietkau <[email protected]>
[ Upstream commit 51fb1278aa57ae0fc54adaa786e1965362bed4fb ]
Fixes an issue caught by KASAN about use-after-free in mt76_txq_schedule by protecting mtxq->wcid with rcu_lock between mt76_txq_schedule and sta_info_[alloc, free].
[18853.876689] ================================================================== [18853.876751] BUG: KASAN: use-after-free in mt76_txq_schedule+0x204/0xaf8 [mt76] [18853.876773] Read of size 8 at addr ffffffaf989a2138 by task mt76-tx phy0/883 [18853.876786] [18853.876810] CPU: 5 PID: 883 Comm: mt76-tx phy0 Not tainted 5.10.100-fix-510-56778d365941-kasan #5 0b01fbbcf41a530f52043508fec2e31a4215
[18853.876840] Call trace: [18853.876861] dump_backtrace+0x0/0x3ec [18853.876878] show_stack+0x20/0x2c [18853.876899] dump_stack+0x11c/0x1ac [18853.876918] print_address_description+0x74/0x514 [18853.876934] kasan_report+0x134/0x174 [18853.876948] __asan_report_load8_noabort+0x44/0x50 [18853.876976] mt76_txq_schedule+0x204/0xaf8 [mt76 074e03e4640e97fe7405ee1fab547b81c4fa45d2] [18853.877002] mt76_txq_schedule_all+0x2c/0x48 [mt76 074e03e4640e97fe7405ee1fab547b81c4fa45d2] [18853.877030] mt7921_tx_worker+0xa0/0x1cc [mt7921_common f0875ebac9d7b4754e1010549e7db50fbd90a047] [18853.877054] __mt76_worker_fn+0x190/0x22c [mt76 074e03e4640e97fe7405ee1fab547b81c4fa45d2] [18853.877071] kthread+0x2f8/0x3b8 [18853.877087] ret_from_fork+0x10/0x30 [18853.877098] [18853.877112] Allocated by task 941: [18853.877131] kasan_save_stack+0x38/0x68 [18853.877147] __kasan_kmalloc+0xd4/0xfc [18853.877163] kasan_kmalloc+0x10/0x1c [18853.877177] __kmalloc+0x264/0x3c4 [18853.877294] sta_info_alloc+0x460/0xf88 [mac80211] [18853.877410] ieee80211_prep_connection+0x204/0x1ee0 [mac80211] [18853.877523] ieee80211_mgd_auth+0x6c4/0xa4c [mac80211] [18853.877635] ieee80211_auth+0x20/0x2c [mac80211] [18853.877733] rdev_auth+0x7c/0x438 [cfg80211] [18853.877826] cfg80211_mlme_auth+0x26c/0x390 [cfg80211] [18853.877919] nl80211_authenticate+0x6d4/0x904 [cfg80211] [18853.877938] genl_rcv_msg+0x748/0x93c [18853.877954] netlink_rcv_skb+0x160/0x2a8 [18853.877969] genl_rcv+0x3c/0x54 [18853.877985] netlink_unicast_kernel+0x104/0x1ec [18853.877999] netlink_unicast+0x178/0x268 [18853.878015] netlink_sendmsg+0x3cc/0x5f0 [18853.878030] sock_sendmsg+0xb4/0xd8 [18853.878043] ____sys_sendmsg+0x2f8/0x53c [18853.878058] ___sys_sendmsg+0xe8/0x150 [18853.878071] __sys_sendmsg+0xc4/0x1f4 [18853.878087] __arm64_compat_sys_sendmsg+0x88/0x9c [18853.878101] el0_svc_common+0x1b4/0x390 [18853.878115] do_el0_svc_compat+0x8c/0xdc [18853.878131] el0_svc_compat+0x10/0x1c [18853.878146] el0_sync_compat_handler+0xa8/0xcc [18853.878161] el0_sync_compat+0x188/0x1c0 [18853.878171] [18853.878183] Freed by task 10927: [18853.878200] kasan_save_stack+0x38/0x68 [18853.878215] kasan_set_track+0x28/0x3c [18853.878228] kasan_set_free_info+0x24/0x48 [18853.878244] __kasan_slab_free+0x11c/0x154 [18853.878259] kasan_slab_free+0x14/0x24 [18853.878273] slab_free_freelist_hook+0xac/0x1b0 [18853.878287] kfree+0x104/0x390 [18853.878402] sta_info_free+0x198/0x210 [mac80211] [18853.878515] __sta_info_destroy_part2+0x230/0x2d4 [mac80211] [18853.878628] __sta_info_flush+0x300/0x37c [mac80211] [18853.878740] ieee80211_set_disassoc+0x2cc/0xa7c [mac80211] [18853.878851] ieee80211_mgd_deauth+0x4a4/0x10a0 [mac80211] [18853.878962] ieee80211_deauth+0x20/0x2c [mac80211] [18853.879057] rdev_deauth+0x7c/0x438 [cfg80211] [18853.879150] cfg80211_mlme_deauth+0x274/0x414 [cfg80211] [18853.879243] cfg80211_mlme_down+0xe4/0x118 [cfg80211] [18853.879335] cfg80211_disconnect+0x218/0x2d8 [cfg80211] [18853.879427] __cfg80211_leave+0x17c/0x240 [cfg80211] [18853.879519] cfg80211_leave+0x3c/0x58 [cfg80211] [18853.879611] wiphy_suspend+0xdc/0x200 [cfg80211] [18853.879628] dpm_run_callback+0x58/0x408 [18853.879642] __device_suspend+0x4cc/0x864 [18853.879658] async_suspend+0x34/0xf4 [18853.879673] async_run_entry_fn+0xe0/0x37c [18853.879689] process_one_work+0x508/0xb98 [18853.879702] worker_thread+0x7f4/0xcd4 [18853.879717] kthread+0x2f8/0x3b8 [18853.879731] ret_from_fork+0x10/0x30 [18853.879741] [18853.879757] The buggy address belongs to the object at ffffffaf989a2000 [18853.879757] which belongs to the cache kmalloc-8k of size 8192 [18853.879774] The buggy address is located 312 bytes inside of [18853.879774] 8192-byte region [ffffffaf989a2000, ffffffaf989a4000) [18853.879787] The buggy address belongs to the page: [18853.879807] page:000000004bda2a59 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x1d89a0 [18853.879823] head:000000004bda2a59 order:3 compound_mapcount:0 compound_pincount:0 [18853.879839] flags: 0x8000000000010200(slab|head) [18853.879857] raw: 8000000000010200 ffffffffbc89e208 ffffffffb7fb5208 ffffffaec000cc80 [18853.879873] raw: 0000000000000000 0000000000010001 00000001ffffffff 0000000000000000 [18853.879885] page dumped because: kasan: bad access detected [18853.879896] [18853.879907] Memory state around the buggy address: [18853.879922] ffffffaf989a2000: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [18853.879935] ffffffaf989a2080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [18853.879948] >ffffffaf989a2100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [18853.879961] ^ [18853.879973] ffffffaf989a2180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [18853.879986] ffffffaf989a2200: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [18853.879998] ==================================================================
--- drivers/net/wireless/mediatek/mt76/mac80211.c | 2 +- drivers/net/wireless/mediatek/mt76/mt76.h | 2 +- drivers/net/wireless/mediatek/mt76/mt7603/main.c | 2 +- drivers/net/wireless/mediatek/mt76/mt7615/main.c | 2 +- drivers/net/wireless/mediatek/mt76/mt76x02_util.c | 4 +++- drivers/net/wireless/mediatek/mt76/mt7915/main.c | 2 +- drivers/net/wireless/mediatek/mt76/mt7921/main.c | 2 +- drivers/net/wireless/mediatek/mt76/tx.c | 9 ++++----- 8 files changed, 13 insertions(+), 12 deletions(-)
drivers/net/wireless/mediatek/mt76/mac80211.c +1 -1
@@ -1100,7 +1100,7 @@ mt76_sta_add(struct mt76_dev *dev, struct ieee80211_vif *vif,continue ; mtxq = (struct mt76_txq *)sta->txq[i]->drv_priv; - mtxq->wcid = wcid; + mtxq->wcid = wcid->idx; }ewma_signal_init (&wcid->rssi);
drivers/net/wireless/mediatek/mt76/mt76.h +1 -1
@@ -263,7 +263,7 @@ struct mt76_wcid { };struct mt76_txq { -struct mt76_wcid *wcid; +u16 wcid;u16 agg_ssn;bool send_bar;
drivers/net/wireless/mediatek/mt76/mt7603/main.c +1 -1
@@ -74,7 +74,7 @@ mt7603_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)mt7603_wtbl_init (dev, idx, mvif->idx, bc_addr); mtxq = (struct mt76_txq *)vif->txq->drv_priv; - mtxq->wcid = &mvif->sta.wcid; + mtxq->wcid = idx;rcu_assign_pointer (dev->mt76.wcid[idx], &mvif->sta.wcid); out:
drivers/net/wireless/mediatek/mt76/mt7615/main.c +1 -1
@@ -235,7 +235,7 @@ static int mt7615_add_interface(struct ieee80211_hw *hw,rcu_assign_pointer (dev->mt76.wcid[idx], &mvif->sta.wcid);if (vif->txq) { mtxq = (struct mt76_txq *)vif->txq->drv_priv; - mtxq->wcid = &mvif->sta.wcid; + mtxq->wcid = idx; } ret =mt7615_mcu_add_dev_info (phy, vif, true);
drivers/net/wireless/mediatek/mt76/mt76x02_util.c +3 -1
@@ -288,7 +288,8 @@ mt76x02_vif_init(struct mt76x02_dev *dev, struct ieee80211_vif *vif, mvif->group_wcid.idx =MT_VIF_WCID (idx); mvif->group_wcid.hw_key_idx =-1 ; mtxq = (struct mt76_txq *)vif->txq->drv_priv; - mtxq->wcid = &mvif->group_wcid; +rcu_assign_pointer (dev->mt76.wcid[MT_VIF_WCID (idx)], &mvif->group_wcid); + mtxq->wcid =MT_VIF_WCID (idx); }int
@@ -341,6 +342,7 @@ void mt76x02_remove_interface(struct ieee80211_hw *hw,struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv; dev->mt76.vif_mask &= ~BIT (mvif->idx); +rcu_assign_pointer (dev->mt76.wcid[mvif->group_wcid.idx],NULL ); }EXPORT_SYMBOL_GPL (mt76x02_remove_interface);
drivers/net/wireless/mediatek/mt76/mt7915/main.c +1 -1
@@ -243,7 +243,7 @@ static int mt7915_add_interface(struct ieee80211_hw *hw,rcu_assign_pointer (dev->mt76.wcid[idx], &mvif->sta.wcid);if (vif->txq) { mtxq = (struct mt76_txq *)vif->txq->drv_priv; - mtxq->wcid = &mvif->sta.wcid; + mtxq->wcid = idx; } if (vif->type != NL80211_IFTYPE_AP &&
drivers/net/wireless/mediatek/mt76/mt7921/main.c +1 -1
@@ -283,7 +283,7 @@ static int mt7921_add_interface(struct ieee80211_hw *hw,rcu_assign_pointer (dev->mt76.wcid[idx], &mvif->sta.wcid);if (vif->txq) { mtxq = (struct mt76_txq *)vif->txq->drv_priv; - mtxq->wcid = &mvif->sta.wcid; + mtxq->wcid = idx; } out:
drivers/net/wireless/mediatek/mt76/tx.c +4 -5
@@ -406,12 +406,11 @@ mt76_txq_stopped(struct mt76_queue *q)static int mt76_txq_send_burst (struct mt76_phy *phy,struct mt76_queue *q, -struct mt76_txq *mtxq) +struct mt76_txq *mtxq,struct mt76_wcid *wcid) {struct mt76_dev *dev = phy->dev;struct ieee80211_txq *txq =mtxq_to_txq (mtxq);enum mt76_txq_id qid =mt76_txq_get_qid (txq); -struct mt76_wcid *wcid = mtxq->wcid;struct ieee80211_tx_info *info;struct sk_buff *skb;int n_frames =1 ;
@@ -491,8 +490,8 @@ mt76_txq_schedule_list(struct mt76_phy *phy, enum mt76_txq_id qid)break ; mtxq = (struct mt76_txq *)txq->drv_priv; - wcid = mtxq->wcid; -if (wcid &&test_bit (MT_WCID_FLAG_PS , &wcid->flags)) + wcid =rcu_dereference (dev->wcid[mtxq->wcid]); +if (!wcid ||test_bit (MT_WCID_FLAG_PS , &wcid->flags))continue ;spin_lock_bh (&q->lock);
@@ -511,7 +510,7 @@ mt76_txq_schedule_list(struct mt76_phy *phy, enum mt76_txq_id qid) }if (!mt76_txq_stopped (q)) - n_frames =mt76_txq_send_burst (phy, q, mtxq); + n_frames =mt76_txq_send_burst (phy, q, mtxq, wcid);spin_unlock_bh (&q->lock);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 157/201 iwlwifi: fw: uefi: add missing include guards
In reply to Greg Kroah-HartmanFrom: Johannes Berg <[email protected]>
[ Upstream commit 91000fdf82195b66350b4f88413c2e8b5f94d994 ]
We still don't use #pragma once in the kernel, but even if we did it'd be missing. Add the missing include guards.
--- drivers/net/wireless/intel/iwlwifi/fw/uefi.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/net/wireless/intel/iwlwifi/fw/uefi.h +4 -1
@@ -2,7 +2,8 @@/* * Copyright(c) 2021 Intel Corporation */ - +#ifndef __iwl_fw_uefi__ +#define __iwl_fw_uefi__#define IWL_UEFI_OEM_PNVM_NAME L"UefiCnvWlanOemSignedPnvm"#define IWL_UEFI_REDUCED_POWER_NAME L"UefiCnvWlanReducedPower"
@@ -40,3 +41,5 @@ void *iwl_uefi_get_reduced_power(struct iwl_trans *trans, size_t *len)return ERR_PTR (-EOPNOTSUPP ); }#endif /* CONFIG_EFI */ + +#endif /* __iwl_fw_uefi__ */
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 158/201 crypto: qat - set to zero DH parameters before free
In reply to Greg Kroah-HartmanFrom: Giovanni Cabiddu <[email protected]>
[ Upstream commit 1731160ff7c7bbb11bb1aacb14dd25e18d522779 ]
Set to zero the context buffers containing the DH key before they are freed.
This is a defense in depth measure that avoids keys to be recovered from memory in case the system is compromised between the free of the buffer and when that area of memory (containing keys) gets overwritten.
--- drivers/crypto/qat/qat_common/qat_asym_algs.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/crypto/qat/qat_common/qat_asym_algs.c +3 -0
@@ -420,14 +420,17 @@ static int qat_dh_set_params(struct qat_dh_ctx *ctx, struct dh *params)static void qat_dh_clear_ctx (struct device *dev,struct qat_dh_ctx *ctx) {if (ctx->g) { +memset (ctx->g,0 , ctx->p_size);dma_free_coherent (dev, ctx->p_size, ctx->g, ctx->dma_g); ctx->g =NULL ; }if (ctx->xa) { +memset (ctx->xa,0 , ctx->p_size);dma_free_coherent (dev, ctx->p_size, ctx->xa, ctx->dma_xa); ctx->xa =NULL ; }if (ctx->p) { +memset (ctx->p,0 , ctx->p_size);dma_free_coherent (dev, ctx->p_size, ctx->p, ctx->dma_p); ctx->p =NULL ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 159/201 crypto: qat - use pre-allocated buffers in datapath
In reply to Greg Kroah-HartmanFrom: Giovanni Cabiddu <[email protected]>
[ Upstream commit e0831e7af4e03f2715de102e18e9179ec0a81562 ]
In order to do DMAs, the QAT device requires that the scatterlist structures are mapped and translated into a format that the firmware can understand. This is defined as the composition of a scatter gather list (SGL) descriptor header, the struct qat_alg_buf_list, plus a variable number of flat buffer descriptors, the struct qat_alg_buf.
The allocation and mapping of these data structures is done each time a request is received from the skcipher and aead APIs.
In an OOM situation, this behaviour might lead to a dead-lock if an allocation fails.
Based on the conversation in [1], increase the size of the aead and skcipher request contexts to include an SGL descriptor that can handle a maximum of 4 flat buffers.
If requests exceed 4 entries buffers, memory is allocated dynamically.
[1] https://lore.kernel.org/linux-crypto/[email protected]/
--- drivers/crypto/qat/qat_common/qat_algs.c | 64 +++++++++++++--------- drivers/crypto/qat/qat_common/qat_crypto.h | 24 ++++++++ 2 files changed, 61 insertions(+), 27 deletions(-)
drivers/crypto/qat/qat_common/qat_algs.c +37 -27
@@ -46,19 +46,6 @@static DEFINE_MUTEX (algs_lock);static unsigned int active_devs; -struct qat_alg_buf { -u32 len; -u32 resrvd; -u64 addr; -} __packed; - -struct qat_alg_buf_list { -u64 resrvd; -u32 num_bufs; -u32 num_mapped_bufs; -struct qat_alg_buf bufers[]; -} __packed__aligned(64) ; -/* Common content descriptor */ struct qat_alg_cd { union {
@@ -693,7 +680,10 @@ static void qat_alg_free_bufl(struct qat_crypto_instance *inst, bl->bufers[i].len, DMA_BIDIRECTIONAL);dma_unmap_single (dev, blp, sz,DMA_TO_DEVICE ); -kfree (bl); + +if (!qat_req->buf.sgl_src_valid) +kfree (bl); +if (blp != blpout) {/* If out of place operation dma unmap only data */ int bufless = blout->num_bufs - blout->num_mapped_bufs;
@@ -704,7 +694,9 @@ static void qat_alg_free_bufl(struct qat_crypto_instance *inst, DMA_BIDIRECTIONAL); }dma_unmap_single (dev, blpout, sz_out,DMA_TO_DEVICE ); -kfree (blout); + +if (!qat_req->buf.sgl_dst_valid) +kfree (blout); } }
@@ -721,15 +713,24 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst,dma_addr_t blp =DMA_MAPPING_ERROR ;dma_addr_t bloutp =DMA_MAPPING_ERROR ;struct scatterlist *sg; -size_t sz_out, sz =struct_size (bufl, bufers, n +1 ); +size_t sz_out, sz =struct_size (bufl, bufers, n); +int node =dev_to_node (&GET_DEV (inst->accel_dev));if (unlikely (!n))return -EINVAL ; - bufl =kzalloc_node (sz,GFP_ATOMIC , -dev_to_node (&GET_DEV (inst->accel_dev))); -if (unlikely (!bufl)) -return -ENOMEM ; + qat_req->buf.sgl_src_valid = false; + qat_req->buf.sgl_dst_valid = false; + +if (n >QAT_MAX_BUFF_DESC ) { + bufl =kzalloc_node (sz,GFP_ATOMIC , node); +if (unlikely (!bufl)) +return -ENOMEM ; + }else { + bufl = &qat_req->buf.sgl_src.sgl_hdr; +memset (bufl,0 ,sizeof (struct qat_alg_buf_list )); + qat_req->buf.sgl_src_valid = true; + }for_each_sg (sgl, sg, n, i) bufl->bufers[i].addr =DMA_MAPPING_ERROR ;
@@ -760,12 +761,18 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst,struct qat_alg_buf *bufers; n =sg_nents (sglout); - sz_out =struct_size (buflout, bufers, n +1 ); + sz_out =struct_size (buflout, bufers, n); sg_nctr =0 ; - buflout =kzalloc_node (sz_out,GFP_ATOMIC , -dev_to_node (&GET_DEV (inst->accel_dev))); -if (unlikely (!buflout)) - goto err_in; + +if (n >QAT_MAX_BUFF_DESC ) { + buflout =kzalloc_node (sz_out,GFP_ATOMIC , node); +if (unlikely (!buflout)) + goto err_in; + }else { + buflout = &qat_req->buf.sgl_dst.sgl_hdr; +memset (buflout,0 ,sizeof (struct qat_alg_buf_list )); + qat_req->buf.sgl_dst_valid = true; + } bufers = buflout->bufers;for_each_sg (sglout, sg, n, i)
@@ -810,7 +817,9 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst,dma_unmap_single (dev, buflout->bufers[i].addr, buflout->bufers[i].len,DMA_BIDIRECTIONAL ); -kfree (buflout); + +if (!qat_req->buf.sgl_dst_valid) +kfree (buflout); err_in:if (!dma_mapping_error (dev, blp))
@@ -823,7 +832,8 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst, bufl->bufers[i].len, DMA_BIDIRECTIONAL); -kfree (bufl); +if (!qat_req->buf.sgl_src_valid) +kfree (bufl);dev_err (dev,"Failed to map buf for dma\n" );return -ENOMEM ;
drivers/crypto/qat/qat_common/qat_crypto.h +24 -0
@@ -21,6 +21,26 @@ struct qat_crypto_instance {atomic_t refctr; }; +#define QAT_MAX_BUFF_DESC 4 + +struct qat_alg_buf { +u32 len; +u32 resrvd; +u64 addr; +} __packed; + +struct qat_alg_buf_list { +u64 resrvd; +u32 num_bufs; +u32 num_mapped_bufs; +struct qat_alg_buf bufers[]; +} __packed; + +struct qat_alg_fixed_buf_list { +struct qat_alg_buf_list sgl_hdr; +struct qat_alg_buf descriptors[QAT_MAX_BUFF_DESC ]; +} __packed__aligned(64) ; +struct qat_crypto_request_buffs {struct qat_alg_buf_list *bl;dma_addr_t blp;
@@ -28,6 +48,10 @@ struct qat_crypto_request_buffs {dma_addr_t bloutp;size_t sz;size_t sz_out; +bool sgl_src_valid; +bool sgl_dst_valid; +struct qat_alg_fixed_buf_list sgl_src; +struct qat_alg_fixed_buf_list sgl_dst; };struct qat_crypto_request ;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 160/201 crypto: qat - refactor submission logic
In reply to Greg Kroah-HartmanFrom: Giovanni Cabiddu <[email protected]>
[ Upstream commit af88d3c109aa5edfaa11c9a26d9c0ff21ddf501c ]
All the algorithms in qat_algs.c and qat_asym_algs.c use the same pattern to submit messages to the HW queues. Move the submission loop to a new function, qat_alg_send_message(), and share it between the symmetric and the asymmetric algorithms.
As part of this rework, since the number of retries before returning an error is inconsistent between the symmetric and asymmetric implementations, set it to a value that works for both (i.e. 20, was 10 in qat_algs.c and 100 in qat_asym_algs.c)
In addition fix the return code reported when the HW queues are full. In that case return -ENOSPC instead of -EBUSY.
Including stable in CC since (1) the error code returned if the HW queues are full is incorrect and (2) to facilitate the backport of the next fix "crypto: qat - add backlog mechanism".
--- drivers/crypto/qat/qat_common/Makefile | 1 + drivers/crypto/qat/qat_common/qat_algs.c | 68 +++++++++---------- drivers/crypto/qat/qat_common/qat_algs_send.c | 21 ++++++ drivers/crypto/qat/qat_common/qat_algs_send.h | 10 +++ drivers/crypto/qat/qat_common/qat_asym_algs.c | 50 +++++++++----- drivers/crypto/qat/qat_common/qat_crypto.h | 5 ++ 6 files changed, 101 insertions(+), 54 deletions(-) create mode 100644 drivers/crypto/qat/qat_common/qat_algs_send.c create mode 100644 drivers/crypto/qat/qat_common/qat_algs_send.h
drivers/crypto/qat/qat_common/Makefile +1 -0
@@ -15,6 +15,7 @@ intel_qat-objs := adf_cfg.o \ qat_crypto.o \ qat_algs.o \ qat_asym_algs.o \ + qat_algs_send.o \ qat_uclo.o \ qat_hal.o
drivers/crypto/qat/qat_common/qat_algs.c +32 -36
133 lines not on this page · raw message
drivers/crypto/qat/qat_common/qat_algs_send.c new file +21 -0
@@ -0,0 +1,21 @@ +// SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only) +/* Copyright(c) 2022 Intel Corporation */ +#include "adf_transport.h" +#include "qat_algs_send.h" +#include "qat_crypto.h" + +#define ADF_MAX_RETRIES 20 + +int qat_alg_send_message (struct qat_alg_req *req) +{ +int ret =0 , ctr =0 ; + +do { + ret =adf_send_message (req->tx_ring, req->fw_req); + }while (ret == -EAGAIN && ctr++ <ADF_MAX_RETRIES ); + +if (ret == -EAGAIN ) +return -ENOSPC ; + +return -EINPROGRESS ; +}
drivers/crypto/qat/qat_common/qat_algs_send.h new file +10 -0
@@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only) */ +/* Copyright(c) 2022 Intel Corporation */ +#ifndef QAT_ALGS_SEND_H +#define QAT_ALGS_SEND_H + +#include "qat_crypto.h" + +int qat_alg_send_message (struct qat_alg_req *req); + +#endif
drivers/crypto/qat/qat_common/qat_asym_algs.c +32 -18
104 lines not on this page · raw message
drivers/crypto/qat/qat_common/qat_crypto.h +5 -0
@@ -9,6 +9,11 @@#include "adf_accel_devices.h" #include "icp_qat_fw_la.h" +struct qat_alg_req { +u32 *fw_req; +struct adf_etr_ring_data *tx_ring; +}; +struct qat_crypto_instance {struct adf_etr_ring_data *sym_tx;struct adf_etr_ring_data *sym_rx;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 161/201 crypto: qat - add backlog mechanism
In reply to Greg Kroah-HartmanFrom: Giovanni Cabiddu <[email protected]>
[ Upstream commit 38682383973280e5be2802ba8a8d4a636d36cb19 ]
The implementations of the crypto algorithms (aead, skcipher, etc) in the QAT driver do not properly support requests with the CRYPTO_TFM_REQ_MAY_BACKLOG flag set. If the HW queue is full, the driver returns -EBUSY but does not enqueue the request. This can result in applications like dm-crypt waiting indefinitely for the completion of a request that was never submitted to the hardware.
Fix this by adding a software backlog queue: if the ring buffer is more than eighty percent full, then the request is enqueued to a backlog list and the error code -EBUSY is returned back to the caller. Requests in the backlog queue are resubmitted at a later time, in the context of the callback of a previously submitted request. The request for which -EBUSY is returned is then marked as -EINPROGRESS once submitted to the HW queues.
The submission loop inside the function qat_alg_send_message() has been modified to decide which submission policy to use based on the request flags. If the request does not have the CRYPTO_TFM_REQ_MAY_BACKLOG set, the previous behaviour has been preserved.
Based on a patch by
Vishnu Das Ramachandran <[email protected]>
--- drivers/crypto/qat/qat_common/adf_transport.c | 11 +++ drivers/crypto/qat/qat_common/adf_transport.h | 1 + .../qat/qat_common/adf_transport_internal.h | 1 + drivers/crypto/qat/qat_common/qat_algs.c | 24 ++++--- drivers/crypto/qat/qat_common/qat_algs_send.c | 67 ++++++++++++++++++- drivers/crypto/qat/qat_common/qat_algs_send.h | 1 + drivers/crypto/qat/qat_common/qat_asym_algs.c | 23 ++++--- drivers/crypto/qat/qat_common/qat_crypto.c | 3 + drivers/crypto/qat/qat_common/qat_crypto.h | 10 +++ 9 files changed, 123 insertions(+), 18 deletions(-)
drivers/crypto/qat/qat_common/adf_transport.c +11 -0
@@ -8,6 +8,9 @@#include "adf_cfg.h" #include "adf_common_drv.h" +#define ADF_MAX_RING_THRESHOLD 80 +#define ADF_PERCENT (tot, percent) (((tot) * (percent)) / 100) +static inline u32 adf_modulo (u32 data,u32 shift) {u32 div = data >> shift;
@@ -77,6 +80,11 @@ static void adf_disable_ring_irq(struct adf_etr_bank_data *bank, u32 ring) bank->irq_mask); } +bool adf_ring_nearly_full (struct adf_etr_ring_data *ring) +{ +return atomic_read (ring->inflights) > ring->threshold; +} +int adf_send_message (struct adf_etr_ring_data *ring,u32 *msg) {struct adf_hw_csr_ops *csr_ops =GET_CSR_OPS (ring->bank->accel_dev);
@@ -217,6 +225,7 @@ int adf_create_ring(struct adf_accel_dev *accel_dev, const char *section,struct adf_etr_bank_data *bank;struct adf_etr_ring_data *ring;char val[ADF_CFG_MAX_VAL_LEN_IN_BYTES ]; +int max_inflights;u32 ring_num;int ret;
@@ -263,6 +272,8 @@ int adf_create_ring(struct adf_accel_dev *accel_dev, const char *section, ring->ring_size =adf_verify_ring_size (msg_size, num_msgs); ring->head =0 ; ring->tail =0 ; + max_inflights =ADF_MAX_INFLIGHTS (ring->ring_size, ring->msg_size); + ring->threshold =ADF_PERCENT (max_inflights,ADF_MAX_RING_THRESHOLD );atomic_set (ring->inflights,0 ); ret =adf_init_ring (ring);if (ret)
drivers/crypto/qat/qat_common/adf_transport.h +1 -0
@@ -14,6 +14,7 @@ int adf_create_ring(struct adf_accel_dev *accel_dev, const char *section, const char *ring_name, adf_callback_fn callback, int poll_mode, struct adf_etr_ring_data **ring_ptr); +bool adf_ring_nearly_full (struct adf_etr_ring_data *ring);int adf_send_message (struct adf_etr_ring_data *ring,u32 *msg);void adf_remove_ring (struct adf_etr_ring_data *ring);#endif
drivers/crypto/qat/qat_common/adf_transport_internal.h +1 -0
@@ -22,6 +22,7 @@ struct adf_etr_ring_data {spinlock_t lock;/* protects ring data struct */ u16 head;u16 tail; +u32 threshold;u8 ring_number;u8 ring_size;u8 msg_size;
drivers/crypto/qat/qat_common/qat_algs.c +15 -9
@@ -935,19 +935,25 @@ void qat_alg_callback(void *resp)struct icp_qat_fw_la_resp *qat_resp = resp;struct qat_crypto_request *qat_req = (void *)(__force long )qat_resp->opaque_data; +struct qat_instance_backlog *backlog = qat_req->alg_req.backlog; qat_req->cb (qat_resp, qat_req); + +qat_alg_send_backlog (backlog); }static int qat_alg_send_sym_message (struct qat_crypto_request *qat_req, -struct qat_crypto_instance *inst) +struct qat_crypto_instance *inst, +struct crypto_async_request *base) { -struct qat_alg_req req; +struct qat_alg_req *alg_req = &qat_req->alg_req; - req.fw_req = (u32 *)&qat_req->req; - req.tx_ring = inst->sym_tx; + alg_req->fw_req = (u32 *)&qat_req->req; + alg_req->tx_ring = inst->sym_tx; + alg_req->base = base; + alg_req->backlog = &inst->backlog; -return qat_alg_send_message (&req); +return qat_alg_send_message (alg_req); }static int qat_alg_aead_dec (struct aead_request *areq)
@@ -987,7 +993,7 @@ static int qat_alg_aead_dec(struct aead_request *areq) auth_param->auth_off =0 ; auth_param->auth_len = areq->assoclen + cipher_param->cipher_length; - ret =qat_alg_send_sym_message (qat_req, ctx->inst); + ret =qat_alg_send_sym_message (qat_req, ctx->inst, &areq->base);if (ret == -ENOSPC )qat_alg_free_bufl (ctx->inst, qat_req);
@@ -1031,7 +1037,7 @@ static int qat_alg_aead_enc(struct aead_request *areq) auth_param->auth_off =0 ; auth_param->auth_len = areq->assoclen + areq->cryptlen; - ret =qat_alg_send_sym_message (qat_req, ctx->inst); + ret =qat_alg_send_sym_message (qat_req, ctx->inst, &areq->base);if (ret == -ENOSPC )qat_alg_free_bufl (ctx->inst, qat_req);
@@ -1212,7 +1218,7 @@ static int qat_alg_skcipher_encrypt(struct skcipher_request *req)qat_alg_set_req_iv (qat_req); - ret =qat_alg_send_sym_message (qat_req, ctx->inst); + ret =qat_alg_send_sym_message (qat_req, ctx->inst, &req->base);if (ret == -ENOSPC )qat_alg_free_bufl (ctx->inst, qat_req);
@@ -1278,7 +1284,7 @@ static int qat_alg_skcipher_decrypt(struct skcipher_request *req)qat_alg_set_req_iv (qat_req);qat_alg_update_iv (qat_req); - ret =qat_alg_send_sym_message (qat_req, ctx->inst); + ret =qat_alg_send_sym_message (qat_req, ctx->inst, &req->base);if (ret == -ENOSPC )qat_alg_free_bufl (ctx->inst, qat_req);
drivers/crypto/qat/qat_common/qat_algs_send.c +66 -1
76 lines not on this page · raw message
drivers/crypto/qat/qat_common/qat_algs_send.h +1 -0
@@ -6,5 +6,6 @@#include "qat_crypto.h" int qat_alg_send_message (struct qat_alg_req *req); +void qat_alg_send_backlog (struct qat_instance_backlog *backlog);#endif
drivers/crypto/qat/qat_common/qat_asym_algs.c +15 -8
@@ -136,17 +136,21 @@ struct qat_asym_request { } areq;int err;void (*cb)(struct icp_qat_fw_pke_resp *resp); +struct qat_alg_req alg_req; }__aligned(64) ;static int qat_alg_send_asym_message (struct qat_asym_request *qat_req, -struct qat_crypto_instance *inst) +struct qat_crypto_instance *inst, +struct crypto_async_request *base) { -struct qat_alg_req req; +struct qat_alg_req *alg_req = &qat_req->alg_req; - req.fw_req = (u32 *)&qat_req->req; - req.tx_ring = inst->pke_tx; + alg_req->fw_req = (u32 *)&qat_req->req; + alg_req->tx_ring = inst->pke_tx; + alg_req->base = base; + alg_req->backlog = &inst->backlog; -return qat_alg_send_message (&req); +return qat_alg_send_message (alg_req); }static void qat_dh_cb (struct icp_qat_fw_pke_resp *resp)
@@ -350,7 +354,7 @@ static int qat_dh_compute_value(struct kpp_request *req) msg->input_param_count = n_input_params; msg->output_param_count =1 ; - ret =qat_alg_send_asym_message (qat_req, ctx->inst); + ret =qat_alg_send_asym_message (qat_req, inst, &req->base);if (ret == -ENOSPC ) goto unmap_all;
@@ -557,8 +561,11 @@ void qat_alg_asym_callback(void *_resp) {struct icp_qat_fw_pke_resp *resp = _resp;struct qat_asym_request *areq = (void *)(__force long )resp->opaque; +struct qat_instance_backlog *backlog = areq->alg_req.backlog; areq->cb (resp); + +qat_alg_send_backlog (backlog); }#define PKE_RSA_EP_512 0x1c161b21
@@ -748,7 +755,7 @@ static int qat_rsa_enc(struct akcipher_request *req) msg->input_param_count =3 ; msg->output_param_count =1 ; - ret =qat_alg_send_asym_message (qat_req, ctx->inst); + ret =qat_alg_send_asym_message (qat_req, inst, &req->base);if (ret == -ENOSPC ) goto unmap_all;
@@ -901,7 +908,7 @@ static int qat_rsa_dec(struct akcipher_request *req) msg->output_param_count =1 ; - ret =qat_alg_send_asym_message (qat_req, ctx->inst); + ret =qat_alg_send_asym_message (qat_req, inst, &req->base);if (ret == -ENOSPC ) goto unmap_all;
drivers/crypto/qat/qat_common/qat_crypto.c +3 -0
@@ -328,6 +328,9 @@ static int qat_crypto_create_instances(struct adf_accel_dev *accel_dev) &inst->pke_rx);if (ret) goto err; + +INIT_LIST_HEAD (&inst->backlog.list); +spin_lock_init (&inst->backlog.lock); }return 0 ; err:
drivers/crypto/qat/qat_common/qat_crypto.h +10 -0
@@ -9,9 +9,17 @@#include "adf_accel_devices.h" #include "icp_qat_fw_la.h" +struct qat_instance_backlog { +struct list_head list; +spinlock_t lock;/* protects backlog list */ +}; +struct qat_alg_req {u32 *fw_req;struct adf_etr_ring_data *tx_ring; +struct crypto_async_request *base; +struct list_head list; +struct qat_instance_backlog *backlog; };struct qat_crypto_instance {
@@ -24,6 +32,7 @@ struct qat_crypto_instance {unsigned long state;int id;atomic_t refctr; +struct qat_instance_backlog backlog; };#define QAT_MAX_BUFF_DESC 4
@@ -82,6 +91,7 @@ struct qat_crypto_request {u8 iv[AES_BLOCK_SIZE ]; };bool encryption; +struct qat_alg_req alg_req; };static inline bool adf_hw_dev_has_crypto (struct adf_accel_dev *accel_dev)
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 162/201 crypto: qat - fix memory leak in RSA
In reply to Greg Kroah-HartmanFrom: Giovanni Cabiddu <[email protected]>
[ Upstream commit 80a52e1ee7757b742f96bfb0d58f0c14eb6583d0 ]
When an RSA key represented in form 2 (as defined in PKCS #1 V2.1) is used, some components of the private key persist even after the TFM is released.
Replace the explicit calls to free the buffers in qat_rsa_exit_tfm() with a call to qat_rsa_clear_ctx() which frees all buffers referenced in the TFM context.
--- drivers/crypto/qat/qat_common/qat_asym_algs.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-)
drivers/crypto/qat/qat_common/qat_asym_algs.c +1 -11
@@ -1257,18 +1257,8 @@ static void qat_rsa_exit_tfm(struct crypto_akcipher *tfm)struct qat_rsa_ctx *ctx =akcipher_tfm_ctx (tfm);struct device *dev = &GET_DEV (ctx->inst->accel_dev); -if (ctx->n) -dma_free_coherent (dev, ctx->key_sz, ctx->n, ctx->dma_n); -if (ctx->e) -dma_free_coherent (dev, ctx->key_sz, ctx->e, ctx->dma_e); -if (ctx->d) { -memset (ctx->d,'\0' , ctx->key_sz); -dma_free_coherent (dev, ctx->key_sz, ctx->d, ctx->dma_d); - } +qat_rsa_clear_ctx (dev, ctx);qat_crypto_put_instance (ctx->inst); - ctx->n =NULL ; - ctx->e =NULL ; - ctx->d =NULL ; }static struct akcipher_alg rsa = {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 163/201 crypto: qat - remove dma_free_coherent() for RSA
In reply to Greg Kroah-HartmanFrom: Giovanni Cabiddu <[email protected]>
[ Upstream commit 3dfaf0071ed74d7a9c6b3c9ea4df7a6f8e423c2a ]
After commit f5ff79fddf0e ("dma-mapping: remove CONFIG_DMA_REMAP"), if the algorithms are enabled, the driver crashes with a BUG_ON while executing vunmap() in the context of a tasklet. This is due to the fact that the function dma_free_coherent() cannot be called in an interrupt context (see Documentation/core-api/dma-api-howto.rst).
The functions qat_rsa_enc() and qat_rsa_dec() allocate memory with dma_alloc_coherent() if the source or the destination buffers are made of multiple flat buffers or of a size that is not compatible with the hardware.
This memory is then freed with dma_free_coherent() in the context of a tasklet invoked to handle the response for the corresponding request.
Replace allocations with dma_alloc_coherent() in the functions qat_rsa_enc() and qat_rsa_dec() with kmalloc() + dma_map_single().
--- drivers/crypto/qat/qat_common/qat_asym_algs.c | 137 ++++++++---------- 1 file changed, 60 insertions(+), 77 deletions(-)
drivers/crypto/qat/qat_common/qat_asym_algs.c +60 -77
@@ -529,25 +529,22 @@ static void qat_rsa_cb(struct icp_qat_fw_pke_resp *resp) err = (err ==ICP_QAT_FW_COMN_STATUS_FLAG_OK ) ?0 : -EINVAL ; -if (req->src_align) -dma_free_coherent (dev, req->ctx.rsa->key_sz, req->src_align, - req->in.rsa.enc.m); -else -dma_unmap_single (dev, req->in.rsa.enc.m, req->ctx.rsa->key_sz, -DMA_TO_DEVICE ); +kfree_sensitive (req->src_align); + +dma_unmap_single (dev, req->in.rsa.enc.m, req->ctx.rsa->key_sz, +DMA_TO_DEVICE ); areq->dst_len = req->ctx.rsa->key_sz;if (req->dst_align) {scatterwalk_map_and_copy (req->dst_align, areq->dst,0 , areq->dst_len,1 ); -dma_free_coherent (dev, req->ctx.rsa->key_sz, req->dst_align, - req->out.rsa.enc.c); - }else { -dma_unmap_single (dev, req->out.rsa.enc.c, req->ctx.rsa->key_sz, -DMA_FROM_DEVICE ); +kfree_sensitive (req->dst_align); } +dma_unmap_single (dev, req->out.rsa.enc.c, req->ctx.rsa->key_sz, +DMA_FROM_DEVICE ); +dma_unmap_single (dev, req->phy_in,sizeof (struct qat_rsa_input_params ),DMA_TO_DEVICE ); dma_unmap_single(dev, req->phy_out,
@@ -664,6 +661,7 @@ static int qat_rsa_enc(struct akcipher_request *req)struct qat_asym_request *qat_req =PTR_ALIGN (akcipher_request_ctx (req),64 );struct icp_qat_fw_pke_request *msg = &qat_req->req; +u8 *vaddr;int ret;if (unlikely (!ctx->n || !ctx->e))
@@ -701,40 +699,39 @@ static int qat_rsa_enc(struct akcipher_request *req)*/ if (sg_is_last (req->src) && req->src_len == ctx->key_sz) { qat_req->src_align =NULL ; - qat_req->in.rsa.enc.m =dma_map_single (dev,sg_virt (req->src), - req->src_len,DMA_TO_DEVICE ); -if (unlikely (dma_mapping_error (dev, qat_req->in.rsa.enc.m))) -return ret; - + vaddr =sg_virt (req->src); }else {int shift = ctx->key_sz - req->src_len; - qat_req->src_align =dma_alloc_coherent (dev, ctx->key_sz, - &qat_req->in.rsa.enc.m, -GFP_KERNEL ); + qat_req->src_align =kzalloc (ctx->key_sz,GFP_KERNEL );if (unlikely (!qat_req->src_align))return ret;scatterwalk_map_and_copy (qat_req->src_align + shift, req->src,0 , req->src_len,0 ); + vaddr = qat_req->src_align; } -if (sg_is_last (req->dst) && req->dst_len == ctx->key_sz) { - qat_req->dst_align =NULL ; - qat_req->out.rsa.enc.c =dma_map_single (dev,sg_virt (req->dst), - req->dst_len, -DMA_FROM_DEVICE ); -if (unlikely (dma_mapping_error (dev, qat_req->out.rsa.enc.c))) - goto unmap_src; + qat_req->in.rsa.enc.m =dma_map_single (dev, vaddr, ctx->key_sz, +DMA_TO_DEVICE ); +if (unlikely (dma_mapping_error (dev, qat_req->in.rsa.enc.m))) + goto unmap_src; +if (sg_is_last (req->dst) && req->dst_len == ctx->key_sz) { + qat_req->dst_align =NULL ; + vaddr =sg_virt (req->dst); }else { - qat_req->dst_align =dma_alloc_coherent (dev, ctx->key_sz, - &qat_req->out.rsa.enc.c, -GFP_KERNEL ); + qat_req->dst_align =kzalloc (ctx->key_sz,GFP_KERNEL );if (unlikely (!qat_req->dst_align)) goto unmap_src; - + vaddr = qat_req->dst_align; } + + qat_req->out.rsa.enc.c =dma_map_single (dev, vaddr, ctx->key_sz, +DMA_FROM_DEVICE ); +if (unlikely (dma_mapping_error (dev, qat_req->out.rsa.enc.c))) + goto unmap_dst; + qat_req->in.rsa.in_tab[3 ] =0 ; qat_req->out.rsa.out_tab[1 ] =0 ; qat_req->phy_in = dma_map_single(dev, &qat_req->in.rsa.enc.m,
@@ -772,21 +769,15 @@ static int qat_rsa_enc(struct akcipher_request *req)sizeof (struct qat_rsa_input_params ), DMA_TO_DEVICE); unmap_dst: -if (qat_req->dst_align) -dma_free_coherent (dev, ctx->key_sz, qat_req->dst_align, - qat_req->out.rsa.enc.c); -else -if (!dma_mapping_error (dev, qat_req->out.rsa.enc.c)) -dma_unmap_single (dev, qat_req->out.rsa.enc.c, - ctx->key_sz,DMA_FROM_DEVICE ); +if (!dma_mapping_error (dev, qat_req->out.rsa.enc.c)) +dma_unmap_single (dev, qat_req->out.rsa.enc.c, + ctx->key_sz,DMA_FROM_DEVICE ); +kfree_sensitive (qat_req->dst_align); unmap_src: -if (qat_req->src_align) -dma_free_coherent (dev, ctx->key_sz, qat_req->src_align, - qat_req->in.rsa.enc.m); -else -if (!dma_mapping_error (dev, qat_req->in.rsa.enc.m)) -dma_unmap_single (dev, qat_req->in.rsa.enc.m, - ctx->key_sz,DMA_TO_DEVICE ); +if (!dma_mapping_error (dev, qat_req->in.rsa.enc.m)) +dma_unmap_single (dev, qat_req->in.rsa.enc.m, ctx->key_sz, +DMA_TO_DEVICE ); +kfree_sensitive (qat_req->src_align);return ret; }
@@ -799,6 +790,7 @@ static int qat_rsa_dec(struct akcipher_request *req)struct qat_asym_request *qat_req =PTR_ALIGN (akcipher_request_ctx (req),64 );struct icp_qat_fw_pke_request *msg = &qat_req->req; +u8 *vaddr;int ret;if (unlikely (!ctx->n || !ctx->d))
@@ -846,40 +838,37 @@ static int qat_rsa_dec(struct akcipher_request *req)*/ if (sg_is_last (req->src) && req->src_len == ctx->key_sz) { qat_req->src_align =NULL ; - qat_req->in.rsa.dec.c =dma_map_single (dev,sg_virt (req->src), - req->dst_len,DMA_TO_DEVICE ); -if (unlikely (dma_mapping_error (dev, qat_req->in.rsa.dec.c))) -return ret; - + vaddr =sg_virt (req->src); }else {int shift = ctx->key_sz - req->src_len; - qat_req->src_align =dma_alloc_coherent (dev, ctx->key_sz, - &qat_req->in.rsa.dec.c, -GFP_KERNEL ); + qat_req->src_align =kzalloc (ctx->key_sz,GFP_KERNEL );if (unlikely (!qat_req->src_align))return ret;scatterwalk_map_and_copy (qat_req->src_align + shift, req->src,0 , req->src_len,0 ); + vaddr = qat_req->src_align; } -if (sg_is_last (req->dst) && req->dst_len == ctx->key_sz) { - qat_req->dst_align =NULL ; - qat_req->out.rsa.dec.m =dma_map_single (dev,sg_virt (req->dst), - req->dst_len, -DMA_FROM_DEVICE ); -if (unlikely (dma_mapping_error (dev, qat_req->out.rsa.dec.m))) - goto unmap_src; + qat_req->in.rsa.dec.c =dma_map_single (dev, vaddr, ctx->key_sz, +DMA_TO_DEVICE ); +if (unlikely (dma_mapping_error (dev, qat_req->in.rsa.dec.c))) + goto unmap_src; +if (sg_is_last (req->dst) && req->dst_len == ctx->key_sz) { + qat_req->dst_align =NULL ; + vaddr =sg_virt (req->dst); }else { - qat_req->dst_align =dma_alloc_coherent (dev, ctx->key_sz, - &qat_req->out.rsa.dec.m, -GFP_KERNEL ); + qat_req->dst_align =kzalloc (ctx->key_sz,GFP_KERNEL );if (unlikely (!qat_req->dst_align)) goto unmap_src; - + vaddr = qat_req->dst_align; } + qat_req->out.rsa.dec.m =dma_map_single (dev, vaddr, ctx->key_sz, +DMA_FROM_DEVICE ); +if (unlikely (dma_mapping_error (dev, qat_req->out.rsa.dec.m))) + goto unmap_dst;if (ctx->crt_mode) qat_req->in.rsa.in_tab[6 ] =0 ;
@@ -925,21 +914,15 @@ static int qat_rsa_dec(struct akcipher_request *req)sizeof (struct qat_rsa_input_params ), DMA_TO_DEVICE); unmap_dst: -if (qat_req->dst_align) -dma_free_coherent (dev, ctx->key_sz, qat_req->dst_align, - qat_req->out.rsa.dec.m); -else -if (!dma_mapping_error (dev, qat_req->out.rsa.dec.m)) -dma_unmap_single (dev, qat_req->out.rsa.dec.m, - ctx->key_sz,DMA_FROM_DEVICE ); +if (!dma_mapping_error (dev, qat_req->out.rsa.dec.m)) +dma_unmap_single (dev, qat_req->out.rsa.dec.m, + ctx->key_sz,DMA_FROM_DEVICE ); +kfree_sensitive (qat_req->dst_align); unmap_src: -if (qat_req->src_align) -dma_free_coherent (dev, ctx->key_sz, qat_req->src_align, - qat_req->in.rsa.dec.c); -else -if (!dma_mapping_error (dev, qat_req->in.rsa.dec.c)) -dma_unmap_single (dev, qat_req->in.rsa.dec.c, - ctx->key_sz,DMA_TO_DEVICE ); +if (!dma_mapping_error (dev, qat_req->in.rsa.dec.c)) +dma_unmap_single (dev, qat_req->in.rsa.dec.c, ctx->key_sz, +DMA_TO_DEVICE ); +kfree_sensitive (qat_req->src_align);return ret; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 164/201 crypto: qat - remove dma_free_coherent() for DH
In reply to Greg Kroah-HartmanFrom: Giovanni Cabiddu <[email protected]>
[ Upstream commit 029aa4624a7fe35233bdd3d1354dc7be260380bf ]
The functions qat_dh_compute_value() allocates memory with dma_alloc_coherent() if the source or the destination buffers are made of multiple flat buffers or of a size that is not compatible with the hardware.
This memory is then freed with dma_free_coherent() in the context of a tasklet invoked to handle the response for the corresponding request.
According to Documentation/core-api/dma-api-howto.rst, the function dma_free_coherent() cannot be called in an interrupt context.
Replace allocations with dma_alloc_coherent() in the function qat_dh_compute_value() with kmalloc() + dma_map_single().
--- drivers/crypto/qat/qat_common/qat_asym_algs.c | 83 ++++++++----------- 1 file changed, 34 insertions(+), 49 deletions(-)
drivers/crypto/qat/qat_common/qat_asym_algs.c +34 -49
@@ -164,26 +164,21 @@ static void qat_dh_cb(struct icp_qat_fw_pke_resp *resp) err = (err ==ICP_QAT_FW_COMN_STATUS_FLAG_OK ) ?0 : -EINVAL ;if (areq->src) { -if (req->src_align) -dma_free_coherent (dev, req->ctx.dh->p_size, - req->src_align, req->in.dh.in.b); -else -dma_unmap_single (dev, req->in.dh.in.b, - req->ctx.dh->p_size,DMA_TO_DEVICE ); +dma_unmap_single (dev, req->in.dh.in.b, req->ctx.dh->p_size, +DMA_TO_DEVICE ); +kfree_sensitive (req->src_align); } areq->dst_len = req->ctx.dh->p_size;if (req->dst_align) {scatterwalk_map_and_copy (req->dst_align, areq->dst,0 , areq->dst_len,1 ); - -dma_free_coherent (dev, req->ctx.dh->p_size, req->dst_align, - req->out.dh.r); - }else { -dma_unmap_single (dev, req->out.dh.r, req->ctx.dh->p_size, -DMA_FROM_DEVICE ); +kfree_sensitive (req->dst_align); } +dma_unmap_single (dev, req->out.dh.r, req->ctx.dh->p_size, +DMA_FROM_DEVICE ); +dma_unmap_single (dev, req->phy_in,sizeof (struct qat_dh_input_params ),DMA_TO_DEVICE ); dma_unmap_single(dev, req->phy_out,
@@ -231,6 +226,7 @@ static int qat_dh_compute_value(struct kpp_request *req)struct icp_qat_fw_pke_request *msg = &qat_req->req;int ret;int n_input_params =0 ; +u8 *vaddr;if (unlikely (!ctx->xa))return -EINVAL ;
@@ -287,27 +283,24 @@ static int qat_dh_compute_value(struct kpp_request *req)*/ if (sg_is_last (req->src) && req->src_len == ctx->p_size) { qat_req->src_align =NULL ; - qat_req->in.dh.in.b =dma_map_single (dev, -sg_virt (req->src), - req->src_len, -DMA_TO_DEVICE ); -if (unlikely (dma_mapping_error (dev, - qat_req->in.dh.in.b))) -return ret; - + vaddr =sg_virt (req->src); }else {int shift = ctx->p_size - req->src_len; - qat_req->src_align =dma_alloc_coherent (dev, - ctx->p_size, - &qat_req->in.dh.in.b, -GFP_KERNEL ); + qat_req->src_align =kzalloc (ctx->p_size,GFP_KERNEL );if (unlikely (!qat_req->src_align))return ret;scatterwalk_map_and_copy (qat_req->src_align + shift, req->src,0 , req->src_len,0 ); + + vaddr = qat_req->src_align; } + + qat_req->in.dh.in.b =dma_map_single (dev, vaddr, ctx->p_size, +DMA_TO_DEVICE ); +if (unlikely (dma_mapping_error (dev, qat_req->in.dh.in.b))) + goto unmap_src; }/* * dst can be of any size in valid range, but HW expects it to be the
@@ -318,20 +311,18 @@ static int qat_dh_compute_value(struct kpp_request *req)*/ if (sg_is_last (req->dst) && req->dst_len == ctx->p_size) { qat_req->dst_align =NULL ; - qat_req->out.dh.r =dma_map_single (dev,sg_virt (req->dst), - req->dst_len, -DMA_FROM_DEVICE ); - -if (unlikely (dma_mapping_error (dev, qat_req->out.dh.r))) - goto unmap_src; - + vaddr =sg_virt (req->dst); }else { - qat_req->dst_align =dma_alloc_coherent (dev, ctx->p_size, - &qat_req->out.dh.r, -GFP_KERNEL ); + qat_req->dst_align =kzalloc (ctx->p_size,GFP_KERNEL );if (unlikely (!qat_req->dst_align)) goto unmap_src; + + vaddr = qat_req->dst_align; } + qat_req->out.dh.r =dma_map_single (dev, vaddr, ctx->p_size, +DMA_FROM_DEVICE ); +if (unlikely (dma_mapping_error (dev, qat_req->out.dh.r))) + goto unmap_dst; qat_req->in.dh.in_tab[n_input_params] =0 ; qat_req->out.dh.out_tab[1 ] =0 ;
@@ -371,23 +362,17 @@ static int qat_dh_compute_value(struct kpp_request *req)sizeof (struct qat_dh_input_params ), DMA_TO_DEVICE); unmap_dst: -if (qat_req->dst_align) -dma_free_coherent (dev, ctx->p_size, qat_req->dst_align, - qat_req->out.dh.r); -else -if (!dma_mapping_error (dev, qat_req->out.dh.r)) -dma_unmap_single (dev, qat_req->out.dh.r, ctx->p_size, -DMA_FROM_DEVICE ); +if (!dma_mapping_error (dev, qat_req->out.dh.r)) +dma_unmap_single (dev, qat_req->out.dh.r, ctx->p_size, +DMA_FROM_DEVICE ); +kfree_sensitive (qat_req->dst_align); unmap_src:if (req->src) { -if (qat_req->src_align) -dma_free_coherent (dev, ctx->p_size, qat_req->src_align, - qat_req->in.dh.in.b); -else -if (!dma_mapping_error (dev, qat_req->in.dh.in.b)) -dma_unmap_single (dev, qat_req->in.dh.in.b, - ctx->p_size, -DMA_TO_DEVICE ); +if (!dma_mapping_error (dev, qat_req->in.dh.in.b)) +dma_unmap_single (dev, qat_req->in.dh.in.b, + ctx->p_size, +DMA_TO_DEVICE ); +kfree_sensitive (qat_req->src_align); }return ret; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 165/201 crypto: qat - add param check for RSA
In reply to Greg Kroah-HartmanFrom: Giovanni Cabiddu <[email protected]>
[ Upstream commit 9714061423b8b24b8afb31b8eb4df977c63f19c4 ]
Reject requests with a source buffer that is bigger than the size of the key. This is to prevent a possible integer underflow that might happen when copying the source scatterlist into a linear buffer.
--- drivers/crypto/qat/qat_common/qat_asym_algs.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/crypto/qat/qat_common/qat_asym_algs.c +8 -0
@@ -656,6 +656,10 @@ static int qat_rsa_enc(struct akcipher_request *req) req->dst_len = ctx->key_sz;return -EOVERFLOW ; } + +if (req->src_len > ctx->key_sz) +return -EINVAL ; +memset (msg,'\0' ,sizeof (*msg));ICP_QAT_FW_PKE_HDR_VALID_FLAG_SET (msg->pke_hdr,ICP_QAT_FW_COMN_REQ_FLAG_SET );
@@ -785,6 +789,10 @@ static int qat_rsa_dec(struct akcipher_request *req) req->dst_len = ctx->key_sz;return -EOVERFLOW ; } + +if (req->src_len > ctx->key_sz) +return -EINVAL ; +memset (msg,'\0' ,sizeof (*msg));ICP_QAT_FW_PKE_HDR_VALID_FLAG_SET (msg->pke_hdr,ICP_QAT_FW_COMN_REQ_FLAG_SET );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 166/201 crypto: qat - add param check for DH
In reply to Greg Kroah-HartmanFrom: Giovanni Cabiddu <[email protected]>
[ Upstream commit 2acbb8771f6ac82422886e63832ee7a0f4b1635b ]
Reject requests with a source buffer that is bigger than the size of the key. This is to prevent a possible integer underflow that might happen when copying the source scatterlist into a linear buffer.
--- drivers/crypto/qat/qat_common/qat_asym_algs.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/crypto/qat/qat_common/qat_asym_algs.c +4 -0
@@ -235,6 +235,10 @@ static int qat_dh_compute_value(struct kpp_request *req) req->dst_len = ctx->p_size;return -EOVERFLOW ; } + +if (req->src_len > ctx->p_size) +return -EINVAL ; +memset (msg,'\0' ,sizeof (*msg));ICP_QAT_FW_PKE_HDR_VALID_FLAG_SET (msg->pke_hdr,ICP_QAT_FW_COMN_REQ_FLAG_SET );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 167/201 crypto: qat - re-enable registration of algorithms
In reply to Greg Kroah-HartmanFrom: Giovanni Cabiddu <[email protected]>
[ Upstream commit d09144745959bf7852ccafd73243dd7d1eaeb163 ]
Re-enable the registration of algorithms after fixes to (1) use pre-allocated buffers in the datapath and (2) support the CRYPTO_TFM_REQ_MAY_BACKLOG flag.
This reverts commit 8893d27ffcaf6ec6267038a177cb87bcde4dd3de.
--- drivers/crypto/qat/qat_4xxx/adf_drv.c | 7 ------- drivers/crypto/qat/qat_common/qat_crypto.c | 7 ------- 2 files changed, 14 deletions(-)
drivers/crypto/qat/qat_4xxx/adf_drv.c +0 -7
@@ -52,13 +52,6 @@ static int adf_crypto_dev_config(struct adf_accel_dev *accel_dev)if (ret) goto err; -/* Temporarily set the number of crypto instances to zero to avoid -* registering the crypto algorithms. -* This will be removed when the algorithms will support the -* CRYPTO_TFM_REQ_MAY_BACKLOG flag -*/ - instances =0 ; -for (i =0 ; i < instances; i++) { val = i; bank = i *2 ;
drivers/crypto/qat/qat_common/qat_crypto.c +0 -7
@@ -136,13 +136,6 @@ int qat_crypto_dev_config(struct adf_accel_dev *accel_dev)if (ret) goto err; -/* Temporarily set the number of crypto instances to zero to avoid -* registering the crypto algorithms. -* This will be removed when the algorithms will support the -* CRYPTO_TFM_REQ_MAY_BACKLOG flag -*/ - instances =0 ; -for (i =0 ; i < instances; i++) { val = i;snprintf (key,sizeof (key),ADF_CY "%d" ADF_RING_ASYM_BANK_NUM , i);
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 168/201 exfat: fix referencing wrong parent directory information after renaming
In reply to Greg Kroah-HartmanFrom: Yuezhang Mo <[email protected]>
[ Upstream commit d8dad2588addd1d861ce19e7df3b702330f0c7e3 ]
During renaming, the parent directory information maybe updated. But the file/directory still references to the old parent directory information.
This bug will cause 2 problems.
(1) The renamed file can not be written.
[10768.175172] exFAT-fs (sda1): error, failed to bmap (inode : 7afd50e4 iblock : 0, err : -5)
[10768.184285] exFAT-fs (sda1): Filesystem has been set read-only
ash: write error: Input/output error(2) Some dentries of the renamed file/directory are not set to deleted after removing the file/directory.
exfat_update_parent_info() is a workaround for the wrong parent directory information being used after renaming. Now that bug is fixed, this is no longer needed, so remove it.
--- fs/exfat/namei.c | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-)
fs/exfat/namei.c +1 -26
@@ -1069,6 +1069,7 @@ static int exfat_rename_file(struct inode *inode, struct exfat_chain *p_dir,exfat_remove_entries (inode, p_dir, oldentry,0 , num_old_entries); + ei->dir = *p_dir; ei->entry = newentry; }else {if (exfat_get_entry_type (epold) ==TYPE_FILE ) {
@@ -1159,28 +1160,6 @@ static int exfat_move_file(struct inode *inode, struct exfat_chain *p_olddir,return 0 ; } -static void exfat_update_parent_info (struct exfat_inode_info *ei, -struct inode *parent_inode) -{ -struct exfat_sb_info *sbi =EXFAT_SB (parent_inode->i_sb); -struct exfat_inode_info *parent_ei =EXFAT_I (parent_inode); -loff_t parent_isize =i_size_read (parent_inode); - -/* -* the problem that struct exfat_inode_info caches wrong parent info. -* -* because of flag-mismatch of ei->dir, -* there is abnormal traversing cluster chain. -*/ -if (unlikely (parent_ei->flags != ei->dir.flags || - parent_isize !=EXFAT_CLU_TO_B (ei->dir.size, sbi) || - parent_ei->start_clu != ei->dir.dir)) { -exfat_chain_set (&ei->dir, parent_ei->start_clu, -EXFAT_B_TO_CLU_ROUND_UP (parent_isize, sbi), - parent_ei->flags); - } -} -/* rename or move a old file into a new file */ static int __exfat_rename(struct inode *old_parent_inode, struct exfat_inode_info *ei, struct inode *new_parent_inode,
@@ -1211,8 +1190,6 @@ static int __exfat_rename(struct inode *old_parent_inode,return -ENOENT ; } -exfat_update_parent_info (ei, old_parent_inode); -exfat_chain_dup (&olddir, &ei->dir); dentry = ei->entry;
@@ -1233,8 +1210,6 @@ static int __exfat_rename(struct inode *old_parent_inode, goto out; } -exfat_update_parent_info (new_ei, new_parent_inode); - p_dir = &(new_ei->dir); new_entry = new_ei->entry; ep =exfat_get_dentry (sb, p_dir, new_entry, &new_bh,NULL );
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 169/201 tracing: Have event format check not flag %p* on __get_dynamic_array()
In reply to Greg Kroah-HartmanFrom: Steven Rostedt (Google) <[email protected]>
[ Upstream commit 499f12168aebd6da8fa32c9b7d6203ca9b5eb88d ]
The print fmt check against trace events to make sure that the format does not use pointers that may be freed from the time of the trace to the time the event is read, gives a false positive on %pISpc when reading data that was saved in __get_dynamic_array() when it is perfectly fine to do so, as the data being read is on the ring buffer.
--- kernel/trace/trace_events.c | 7 +++++++ 1 file changed, 7 insertions(+)
kernel/trace/trace_events.c +7 -0
@@ -407,7 +407,14 @@ static void test_event_printk(struct trace_event_call *call) a =strchr (fmt + i,'&' );if ((a && (a < r)) ||test_field (r, call)) dereference_flags &= ~(1ULL << arg); + }else if ((r =strstr (fmt + i,"__get_dynamic_array(" )) && + (!c || r < c)) { + dereference_flags &= ~(1ULL << arg); + }else if ((r =strstr (fmt + i,"__get_sockaddr(" )) && + (!c || r < c)) { + dereference_flags &= ~(1ULL << arg); } + next_arg: i--; arg++;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 170/201 tracing: Place trace_pid_list logic into abstract functions
In reply to Greg Kroah-HartmanFrom: Steven Rostedt (VMware) <[email protected]>
[ Upstream commit 6954e415264eeb5ee6be0d22d789ad12c995ee64 ]
Instead of having the logic that does trace_pid_list open coded, wrap it in abstract functions. This will allow a rewrite of the logic that implements the trace_pid_list without affecting the users.
Note, this causes a change in behavior. Every time a pid is written into the set_*_pid file, it creates a new list and uses RCU to update it. If pid_max is lowered, but there was a pid currently in the list that was higher than pid_max, those pids will now be removed on updating the list. The old behavior kept that from happening.
The rewrite of the pid_list logic will no longer depend on pid_max, and will return the old behavior.
--- kernel/trace/Makefile | 1 + kernel/trace/ftrace.c | 6 +- kernel/trace/pid_list.c | 160 ++++++++++++++++++++++++++++++++++++ kernel/trace/pid_list.h | 13 +++ kernel/trace/trace.c | 78 ++++++------------ kernel/trace/trace.h | 14 +++- kernel/trace/trace_events.c | 6 +- 7 files changed, 217 insertions(+), 61 deletions(-) create mode 100644 kernel/trace/pid_list.c create mode 100644 kernel/trace/pid_list.h
kernel/trace/Makefile +1 -0
@@ -47,6 +47,7 @@ obj-$(CONFIG_TRACING) += trace_output.o obj-$(CONFIG_TRACING) += trace_seq.o obj-$(CONFIG_TRACING) += trace_stat.o obj-$(CONFIG_TRACING) += trace_printk.o +obj-$(CONFIG_TRACING) += pid_list.o obj-$(CONFIG_TRACING_MAP) += tracing_map.o obj-$(CONFIG_PREEMPTIRQ_DELAY_TEST) += preemptirq_delay_test.o obj-$(CONFIG_SYNTH_EVENT_GEN_TEST) += synth_event_gen_test.o
kernel/trace/ftrace.c +3 -3
@@ -7184,10 +7184,10 @@ static void clear_ftrace_pids(struct trace_array *tr, int type)synchronize_rcu ();if ((type &TRACE_PIDS ) && pid_list) -trace_free_pid_list (pid_list); +trace_pid_list_free (pid_list);if ((type &TRACE_NO_PIDS ) && no_pid_list) -trace_free_pid_list (no_pid_list); +trace_pid_list_free (no_pid_list); }void ftrace_clear_pids (struct trace_array *tr)
@@ -7428,7 +7428,7 @@ pid_write(struct file *filp, const char __user *ubuf,if (filtered_pids) {synchronize_rcu (); -trace_free_pid_list (filtered_pids); +trace_pid_list_free (filtered_pids); }else if (pid_list && !other_pids) {/* Register a probe to set whether to ignore the tracing of a task */ register_trace_sched_switch (ftrace_filter_pid_sched_switch_probe, tr);
kernel/trace/pid_list.c new file +160 -0
160 lines not on this page · raw message
kernel/trace/pid_list.h new file +13 -0
@@ -0,0 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* Do not include this file directly. */ + +#ifndef _TRACE_INTERNAL_PID_LIST_H +#define _TRACE_INTERNAL_PID_LIST_H + +struct trace_pid_list { +int pid_max; +unsigned long *pids; +}; + +#endif /* _TRACE_INTERNAL_PID_LIST_H */
kernel/trace/trace.c +27 -51
164 lines not on this page · raw message
kernel/trace/trace.h +10 -4
@@ -22,6 +22,8 @@#include <linux/ctype.h> #include <linux/once_lite.h> +#include "pid_list.h" +#ifdef CONFIG_FTRACE_SYSCALLS #include <asm/unistd.h> /* For NR_SYSCALLS */ #include <asm/syscall.h> /* some archs define it here */
@@ -191,10 +193,14 @@ struct trace_options {struct trace_option_dentry *topts; }; -struct trace_pid_list { -int pid_max; -unsigned long *pids; -}; +struct trace_pid_list *trace_pid_list_alloc (void ); +void trace_pid_list_free (struct trace_pid_list *pid_list); +bool trace_pid_list_is_set (struct trace_pid_list *pid_list,unsigned int pid); +int trace_pid_list_set (struct trace_pid_list *pid_list,unsigned int pid); +int trace_pid_list_clear (struct trace_pid_list *pid_list,unsigned int pid); +int trace_pid_list_first (struct trace_pid_list *pid_list,unsigned int *pid); +int trace_pid_list_next (struct trace_pid_list *pid_list,unsigned int pid, +unsigned int *next);enum {TRACE_PIDS =BIT (0 ),
kernel/trace/trace_events.c +3 -3
@@ -900,10 +900,10 @@ static void __ftrace_clear_event_pids(struct trace_array *tr, int type)tracepoint_synchronize_unregister ();if ((type &TRACE_PIDS ) && pid_list) -trace_free_pid_list (pid_list); +trace_pid_list_free (pid_list);if ((type &TRACE_NO_PIDS ) && no_pid_list) -trace_free_pid_list (no_pid_list); +trace_pid_list_free (no_pid_list); }static void ftrace_clear_event_pids (struct trace_array *tr,int type)
@@ -1982,7 +1982,7 @@ event_pid_write(struct file *filp, const char __user *ubuf,if (filtered_pids) {tracepoint_synchronize_unregister (); -trace_free_pid_list (filtered_pids); +trace_pid_list_free (filtered_pids); }else if (pid_list && !other_pids) {register_pid_events (tr); }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 171/201 tracing: Fix return value of trace_pid_write()
In reply to Greg Kroah-HartmanFrom: Wonhyuk Yang <[email protected]>
[ Upstream commit b27f266f74fbda4ee36c2b2b04d15992860cf23b ]
Setting set_event_pid with trailing whitespace lead to endless write system calls like below.
$ strace echo "123 " > /sys/kernel/debug/tracing/set_event_pid
execve("/usr/bin/echo", ["echo", "123 "], ...) = 0
...
write(1, "123 \n", 5) = 4
write(1, "\n", 1) = 0
write(1, "\n", 1) = 0
write(1, "\n", 1) = 0
write(1, "\n", 1) = 0
write(1, "\n", 1) = 0
....This is because, the result of trace_get_user's are not returned when it read at least one pid. To fix it, update read variable even if parser->idx == 0.
The result of applied patch is below.
$ strace echo "123 " > /sys/kernel/debug/tracing/set_event_pid
execve("/usr/bin/echo", ["echo", "123 "], ...) = 0
...
write(1, "123 \n", 5) = 5
close(1) = 0--- kernel/trace/trace.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
kernel/trace/trace.c +4 -2
@@ -711,13 +711,16 @@ int trace_pid_write(struct trace_pid_list *filtered_pids, pos =0 ; ret =trace_get_user (&parser, ubuf, cnt, &pos); -if (ret <0 || !trace_parser_loaded (&parser)) +if (ret <0 )break ; read += ret; ubuf += ret; cnt -= ret; +if (!trace_parser_loaded (&parser)) +break ; + ret = -EINVAL ;if (kstrtoul (parser.buffer,0 , &val))break ;
@@ -743,7 +746,6 @@ int trace_pid_write(struct trace_pid_list *filtered_pids,if (!nr_pids) {/* Cleared the list of pids */ trace_pid_list_free (pid_list); - read = ret; pid_list =NULL ; }
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 172/201 um: virtio_uml: Allow probing from devicetree
In reply to Greg Kroah-HartmanFrom: Vincent Whitchurch <[email protected]>
[ Upstream commit db0dd9cee82270e032123169ceff659eced5115d ]
Allow the virtio_uml device to be probed from the devicetree so that sub-devices can be specified using the standard virtio bindings, for example:
virtio@1 {
compatible = "virtio,uml";
socket-path = "i2c.sock";
virtio-device-id = <0x22>; i2c-controller {
compatible = "virtio,device22";
#address-cells = <0x01>;
#size-cells = <0x00>;
light-sensor@01 {
compatible = "ti,opt3001";
reg = <0x01>;
};
};};
--- arch/um/drivers/virtio_uml.c | 50 +++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-)
arch/um/drivers/virtio_uml.c +47 -3
@@ -21,6 +21,7 @@* Based on Virtio MMIO driver by Pawel Moll, copyright 2011-2014, ARM Ltd. */ #include <linux/module.h> +#include <linux/of.h> #include <linux/platform_device.h> #include <linux/slab.h> #include <linux/virtio.h>
@@ -49,6 +50,7 @@ struct virtio_uml_platform_data {struct virtio_uml_device {struct virtio_device vdev;struct platform_device *pdev; +struct virtio_uml_platform_data *pdata;spinlock_t sock_lock;int sock, req_fd, irq;
@@ -149,7 +151,7 @@ static int vhost_user_recv(struct virtio_uml_device *vu_dev,if (rc == -ECONNRESET && vu_dev->registered) {struct virtio_uml_platform_data *pdata; - pdata = vu_dev->pdev->dev.platform_data; + pdata = vu_dev->pdata;virtio_break_device (&vu_dev->vdev);schedule_work (&pdata->conn_broken_wk);
@@ -1115,21 +1117,63 @@ void virtio_uml_set_no_vq_suspend(struct virtio_device *vdev, no_vq_suspend ? "dis" : "en"); } +static void vu_of_conn_broken (struct work_struct *wk) +{ +/* +* We can't remove the device from the devicetree so the only thing we +* can do is warn. +*/ +WARN_ON (1 ); +} +/* Platform device */ +static struct virtio_uml_platform_data * +virtio_uml_create_pdata (struct platform_device *pdev) +{ +struct device_node *np = pdev->dev.of_node; +struct virtio_uml_platform_data *pdata; +int ret; + +if (!np) +return ERR_PTR (-EINVAL ); + + pdata =devm_kzalloc (&pdev->dev,sizeof (*pdata),GFP_KERNEL ); +if (!pdata) +return ERR_PTR (-ENOMEM ); + +INIT_WORK (&pdata->conn_broken_wk, vu_of_conn_broken); + pdata->pdev = pdev; + + ret =of_property_read_string (np,"socket-path" , &pdata->socket_path); +if (ret) +return ERR_PTR (ret); + + ret =of_property_read_u32 (np,"virtio-device-id" , + &pdata->virtio_device_id); +if (ret) +return ERR_PTR (ret); + +return pdata; +} +static int virtio_uml_probe (struct platform_device *pdev) {struct virtio_uml_platform_data *pdata = pdev->dev.platform_data;struct virtio_uml_device *vu_dev;int rc; -if (!pdata) -return -EINVAL ; +if (!pdata) { + pdata =virtio_uml_create_pdata (pdev); +if (IS_ERR (pdata)) +return PTR_ERR (pdata); + } vu_dev =kzalloc (sizeof (*vu_dev),GFP_KERNEL );if (!vu_dev)return -ENOMEM ; + vu_dev->pdata = pdata; vu_dev->vdev.dev.parent = &pdev->dev; vu_dev->vdev.dev.release = virtio_uml_release_dev; vu_dev->vdev.config = &virtio_uml_config_ops;
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 173/201 um: virtio_uml: Fix broken device handling in time-travel
In reply to Greg Kroah-HartmanFrom: Johannes Berg <[email protected]>
[ Upstream commit af9fb41ed315ce95f659f0b10b4d59a71975381d ]
If a device implementation crashes, virtio_uml will mark it as dead by calling virtio_break_device() and scheduling the work that will remove it.
This still seems like the right thing to do, but it's done directly while reading the message, and if time-travel is used, this is in the time-travel handler, outside of the normal Linux machinery. Therefore, we cannot acquire locks or do normal "linux-y" things because e.g. lockdep will be confused about the context.
Move handling this situation out of the read function and into the actual IRQ handler and response handling instead, so that in the case of time-travel we don't call it in the wrong context.
Chances are the system will still crash immediately, since the device implementation crashing may also cause the time- travel controller to go down, but at least all of that now happens without strange warnings from lockdep.
--- arch/um/drivers/virtio_uml.c | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-)
arch/um/drivers/virtio_uml.c +23 -10
@@ -63,6 +63,7 @@ struct virtio_uml_device { u8 config_changed_irq:1;uint64_t vq_irq_vq_map; +int recv_rc; };struct virtio_uml_vq_info {
@@ -148,14 +149,6 @@ static int vhost_user_recv(struct virtio_uml_device *vu_dev, rc =vhost_user_recv_header (fd, msg); -if (rc == -ECONNRESET && vu_dev->registered) { -struct virtio_uml_platform_data *pdata; - - pdata = vu_dev->pdata; - -virtio_break_device (&vu_dev->vdev); -schedule_work (&pdata->conn_broken_wk); - }if (rc)return rc; size = msg->header.size;
@@ -164,6 +157,21 @@ static int vhost_user_recv(struct virtio_uml_device *vu_dev,return full_read (fd, &msg->payload, size, false); } +static void vhost_user_check_reset (struct virtio_uml_device *vu_dev, +int rc) +{ +struct virtio_uml_platform_data *pdata = vu_dev->pdata; + +if (rc != -ECONNRESET ) +return ; + +if (!vu_dev->registered) +return ; + +virtio_break_device (&vu_dev->vdev); +schedule_work (&pdata->conn_broken_wk); +} +static int vhost_user_recv_resp (struct virtio_uml_device *vu_dev,struct vhost_user_msg *msg,size_t max_payload_size)
@@ -171,8 +179,10 @@ static int vhost_user_recv_resp(struct virtio_uml_device *vu_dev,int rc =vhost_user_recv (vu_dev, vu_dev->sock, msg, max_payload_size, true); -if (rc) +if (rc) { +vhost_user_check_reset (vu_dev, rc);return rc; + }if (msg->header.flags != (VHOST_USER_FLAG_REPLY |VHOST_USER_VERSION ))return -EPROTO ;
@@ -369,6 +379,7 @@ static irqreturn_t vu_req_read_message(struct virtio_uml_device *vu_dev,sizeof (msg.msg.payload) + sizeof(msg.extra_payload)); + vu_dev->recv_rc = rc;if (rc)return IRQ_NONE ;
@@ -412,7 +423,9 @@ static irqreturn_t vu_req_interrupt(int irq, void *data)if (!um_irq_timetravel_handler_used ()) ret =vu_req_read_message (vu_dev,NULL ); -if (vu_dev->vq_irq_vq_map) { +if (vu_dev->recv_rc) { +vhost_user_check_reset (vu_dev, vu_dev->recv_rc); + }else if (vu_dev->vq_irq_vq_map) {struct virtqueue *vq;virtio_device_for_each_vq ((&vu_dev->vdev), vq) {
Signature · 1 line
2.35.1
Greg Kroah-Hartman
maintainerPATCH 174/201 Bluetooth: Add bt_skb_sendmsg helper
In reply to Greg Kroah-HartmanFrom: Luiz Augusto von Dentz <[email protected]>
commit 38f64f650dc0e44c146ff88d15a7339efa325918 upstream.
bt_skb_sendmsg helps takes care of allocation the skb and copying the the contents of msg over to the skb while checking for possible errors so it should be safe to call it without holding lock_sock.
--- include/net/bluetooth/bluetooth.h | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)
include/net/bluetooth/bluetooth.h +28 -0
@@ -422,6 +422,34 @@ out:return NULL ; } +/* Shall not be called with lock_sock held */ +static inline struct sk_buff *bt_skb_sendmsg (struct sock *sk, +struct msghdr *msg, +size_t len,size_t mtu, +size_t headroom,size_t tailroom) +{ +struct sk_buff *skb; +size_t size =min_t (size_t, len, mtu); +int err; + + skb =bt_skb_send_alloc (sk, size + headroom + tailroom, + msg->msg_flags &MSG_DONTWAIT , &err); +if (!skb) +return ERR_PTR (err); + +skb_reserve (skb, headroom); +skb_tailroom_reserve (skb, mtu, tailroom); + +if (!copy_from_iter_full (skb_put (skb, size), size, &msg->msg_iter)) { +kfree_skb (skb); +return ERR_PTR (-EFAULT ); + } + + skb->priority = sk->sk_priority; + +return skb; +} +int bt_to_errno (u16 code);void hci_sock_set_flag (struct sock *sk,int nr);
Greg Kroah-Hartman
maintainerPATCH 175/201 Bluetooth: Add bt_skb_sendmmsg helper
In reply to Greg Kroah-HartmanFrom: Luiz Augusto von Dentz <[email protected]>
commit 97e4e80299844bb5f6ce5a7540742ffbffae3d97 upstream.
This works similarly to bt_skb_sendmsg but can split the msg into multiple skb fragments which is useful for stream sockets.
--- include/net/bluetooth/bluetooth.h | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+)
include/net/bluetooth/bluetooth.h +38 -0
@@ -450,6 +450,44 @@ static inline struct sk_buff *bt_skb_senreturn skb; } +/* Similar to bt_skb_sendmsg but can split the msg into multiple fragments +* accourding to the MTU. +*/ +static inline struct sk_buff *bt_skb_sendmmsg (struct sock *sk, +struct msghdr *msg, +size_t len,size_t mtu, +size_t headroom,size_t tailroom) +{ +struct sk_buff *skb, **frag; + + skb =bt_skb_sendmsg (sk, msg, len, mtu, headroom, tailroom); +if (IS_ERR_OR_NULL (skb)) +return skb; + + len -= skb->len; +if (!len) +return skb; + +/* Add remaining data over MTU as continuation fragments */ + frag = &skb_shinfo (skb)->frag_list; +while (len) { +struct sk_buff *tmp; + + tmp =bt_skb_sendmsg (sk, msg, len, mtu, headroom, tailroom); +if (IS_ERR_OR_NULL (tmp)) { +kfree_skb (skb); +return tmp; + } + + len -= tmp->len; + + *frag = tmp; + frag = &(*frag)->next; + } + +return skb; +} +int bt_to_errno (u16 code);void hci_sock_set_flag (struct sock *sk,int nr);
Greg Kroah-Hartman
maintainerPATCH 176/201 Bluetooth: SCO: Replace use of memcpy_from_msg with bt_skb_sendmsg
In reply to Greg Kroah-HartmanFrom: Luiz Augusto von Dentz <[email protected]>
commit 0771cbb3b97d3c1d68eecd7f00055f599954c34e upstream.
This makes use of bt_skb_sendmsg instead of allocating a different buffer to be used with memcpy_from_msg which cause one extra copy.
--- net/bluetooth/sco.c | 34 +++++++++++----------------------- 1 file changed, 11 insertions(+), 23 deletions(-)
net/bluetooth/sco.c +11 -23
@@ -280,27 +280,19 @@ static int sco_connect(struct hci_dev *hreturn err; } -static int sco_send_frame (struct sock *sk,void *buf,int len, -unsigned int msg_flags) +static int sco_send_frame (struct sock *sk,struct sk_buff *skb) {struct sco_conn *conn =sco_pi (sk)->conn; -struct sk_buff *skb; -int err;/* Check outgoing MTU */ -if (len > conn->mtu) +if (skb->len > conn->mtu)return -EINVAL ; -BT_DBG ("sk %p len %d" , sk, len); +BT_DBG ("sk %p len %d" , sk, skb->len); - skb =bt_skb_send_alloc (sk, len, msg_flags &MSG_DONTWAIT , &err); -if (!skb) -return err; - -memcpy (skb_put (skb, len), buf, len);hci_send_sco (conn->hcon, skb); -return len; +return skb->len; }static void sco_recv_frame (struct sco_conn *conn,struct sk_buff *skb)
@@ -727,7 +719,7 @@ static int sco_sock_sendmsg(struct socke size_t len) {struct sock *sk = sock->sk; -void *buf; +struct sk_buff *skb;int err;BT_DBG ("sock %p, sk %p" , sock, sk);
@@ -739,24 +731,20 @@ static int sco_sock_sendmsg(struct sockeif (msg->msg_flags &MSG_OOB )return -EOPNOTSUPP ; - buf =kmalloc (len,GFP_KERNEL ); -if (!buf) -return -ENOMEM ; - -if (memcpy_from_msg (buf, msg, len)) { -kfree (buf); -return -EFAULT ; - } + skb =bt_skb_sendmsg (sk, msg, len, len,0 ,0 ); +if (IS_ERR_OR_NULL (skb)) +return PTR_ERR (skb);lock_sock (sk);if (sk->sk_state ==BT_CONNECTED ) - err =sco_send_frame (sk, buf, len, msg->msg_flags); + err =sco_send_frame (sk, skb);else err = -ENOTCONN ;release_sock (sk); -kfree (buf); +if (err) +kfree_skb (skb);return err; }
Greg Kroah-Hartman
maintainerPATCH 177/201 Bluetooth: RFCOMM: Replace use of memcpy_from_msg with bt_skb_sendmmsg
In reply to Greg Kroah-HartmanFrom: Luiz Augusto von Dentz <[email protected]>
commit 81be03e026dc0c16dc1c64e088b2a53b73caa895 upstream.
This makes use of bt_skb_sendmmsg instead using memcpy_from_msg which is not considered safe to be used when lock_sock is held.
Also make rfcomm_dlc_send handle skb with fragments and queue them all atomically.
--- net/bluetooth/rfcomm/core.c | 50 +++++++++++++++++++++++++++++++++++++------- net/bluetooth/rfcomm/sock.c | 50 ++++++++++---------------------------------- 2 files changed, 55 insertions(+), 45 deletions(-)
net/bluetooth/rfcomm/core.c +43 -7
@@ -549,22 +549,58 @@ struct rfcomm_dlc *rfcomm_dlc_exists(bdareturn dlc; } +static int rfcomm_dlc_send_frag (struct rfcomm_dlc *d,struct sk_buff *frag) +{ +int len = frag->len; + +BT_DBG ("dlc %p mtu %d len %d" , d, d->mtu, len); + +if (len > d->mtu) +return -EINVAL ; + +rfcomm_make_uih (frag, d->addr); +__skb_queue_tail (&d->tx_queue, frag); + +return len; +} +int rfcomm_dlc_send (struct rfcomm_dlc *d,struct sk_buff *skb) { -int len = skb->len; +unsigned long flags; +struct sk_buff *frag, *next; +int len;if (d->state !=BT_CONNECTED )return -ENOTCONN ; -BT_DBG ("dlc %p mtu %d len %d" , d, d->mtu, len); + frag =skb_shinfo (skb)->frag_list; +skb_shinfo (skb)->frag_list =NULL ; -if (len > d->mtu) -return -EINVAL ; +/* Queue all fragments atomically. */ +spin_lock_irqsave (&d->tx_queue.lock, flags); + + len =rfcomm_dlc_send_frag (d, skb); +if (len <0 || !frag) + goto unlock; + +for (; frag; frag = next) { +int ret; + + next = frag->next; + + ret =rfcomm_dlc_send_frag (d, frag); +if (ret <0 ) { +kfree_skb (frag); + goto unlock; + } + + len += ret; + } -rfcomm_make_uih (skb, d->addr); -skb_queue_tail (&d->tx_queue, skb); +unlock: +spin_unlock_irqrestore (&d->tx_queue.lock, flags); -if (!test_bit (RFCOMM_TX_THROTTLED , &d->flags)) +if (len >0 && !test_bit (RFCOMM_TX_THROTTLED , &d->flags))rfcomm_schedule ();return len; }
net/bluetooth/rfcomm/sock.c +12 -38
59 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 178/201 Bluetooth: Fix passing NULL to PTR_ERR
In reply to Greg Kroah-HartmanFrom: Luiz Augusto von Dentz <[email protected]>
commit 266191aa8d14b84958aaeb5e96ee4e97839e3d87 upstream.
Passing NULL to PTR_ERR will result in 0 (success), also since the likes of bt_skb_sendmsg does never return NULL it is safe to replace the instances of IS_ERR_OR_NULL with IS_ERR when checking its return.
--- include/net/bluetooth/bluetooth.h | 2 +- net/bluetooth/rfcomm/sock.c | 2 +- net/bluetooth/sco.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-)
include/net/bluetooth/bluetooth.h +1 -1
@@ -474,7 +474,7 @@ static inline struct sk_buff *bt_skb_senstruct sk_buff *tmp; tmp =bt_skb_sendmsg (sk, msg, len, mtu, headroom, tailroom); -if (IS_ERR_OR_NULL (tmp)) { +if (IS_ERR (tmp)) {kfree_skb (skb);return tmp; }
net/bluetooth/rfcomm/sock.c +1 -1
@@ -583,7 +583,7 @@ static int rfcomm_sock_sendmsg(struct so skb =bt_skb_sendmmsg (sk, msg, len, d->mtu,RFCOMM_SKB_HEAD_RESERVE ,RFCOMM_SKB_TAIL_RESERVE ); -if (IS_ERR_OR_NULL (skb)) +if (IS_ERR (skb))return PTR_ERR (skb); sent =rfcomm_dlc_send (d, skb);
net/bluetooth/sco.c +1 -1
@@ -732,7 +732,7 @@ static int sco_sock_sendmsg(struct sockereturn -EOPNOTSUPP ; skb =bt_skb_sendmsg (sk, msg, len, len,0 ,0 ); -if (IS_ERR_OR_NULL (skb)) +if (IS_ERR (skb))return PTR_ERR (skb);lock_sock (sk);
Greg Kroah-Hartman
maintainerPATCH 179/201 Bluetooth: SCO: Fix sco_send_frame returning skb->len
In reply to Greg Kroah-HartmanFrom: Luiz Augusto von Dentz <[email protected]>
commit 037ce005af6b8a3e40ee07c6e9266c8997e6a4d6 upstream.
The skb in modified by hci_send_sco which pushes SCO headers thus changing skb->len causing sco_sock_sendmsg to fail.
--- net/bluetooth/sco.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
net/bluetooth/sco.c +6 -4
@@ -283,16 +283,17 @@ static int sco_connect(struct hci_dev *hstatic int sco_send_frame (struct sock *sk,struct sk_buff *skb) {struct sco_conn *conn =sco_pi (sk)->conn; +int len = skb->len;/* Check outgoing MTU */ -if (skb->len > conn->mtu) +if (len > conn->mtu)return -EINVAL ; -BT_DBG ("sk %p len %d" , sk, skb->len); +BT_DBG ("sk %p len %d" , sk, len);hci_send_sco (conn->hcon, skb); -return skb->len; +return len; }static void sco_recv_frame (struct sco_conn *conn,struct sk_buff *skb)
@@ -743,7 +744,8 @@ static int sco_sock_sendmsg(struct socke err = -ENOTCONN ;release_sock (sk); -if (err) + +if (err <0 )kfree_skb (skb);return err; }
Greg Kroah-Hartman
maintainerPATCH 180/201 Bluetooth: Fix bt_skb_sendmmsg not allocating partial chunks
In reply to Greg Kroah-HartmanFrom: Luiz Augusto von Dentz <[email protected]>
commit 29fb608396d6a62c1b85acc421ad7a4399085b9f upstream.
Since bt_skb_sendmmsg can be used with the likes of SOCK_STREAM it shall return the partial chunks it could allocate instead of freeing everything as otherwise it can cause problems like bellow.
--- include/net/bluetooth/bluetooth.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
include/net/bluetooth/bluetooth.h +1 -2
@@ -475,8 +475,7 @@ static inline struct sk_buff *bt_skb_sen tmp =bt_skb_sendmsg (sk, msg, len, mtu, headroom, tailroom);if (IS_ERR (tmp)) { -kfree_skb (skb); -return tmp; +return skb; } len -= tmp->len;
Greg Kroah-Hartman
maintainerPATCH 181/201 exfat: use updated exfat_chain directly during renaming
In reply to Greg Kroah-HartmanFrom: Sungjong Seo <[email protected]>
commit 204e6ceaa1035cb7b92b156517e88842ebb4c7ff upstream.
In order for a file to access its own directory entry set, exfat_inode_info(ei) has two copied values. One is ei->dir, which is a snapshot of exfat_chain of the parent directory, and the other is ei->entry, which is the offset of the start of the directory entry set in the parent directory.
Since the parent directory can be updated after the snapshot point, it should be used only for accessing one's own directory entry set.
However, as of now, during renaming, it could try to traverse or to allocate clusters via snapshot values, it does not make sense.
This potential problem has been revealed when exfat_update_parent_info() was removed by commit d8dad2588add ("exfat: fix referencing wrong parent directory information after renaming"). However, I don't think it's good idea to bring exfat_update_parent_info() back.
Instead, let's use the updated exfat_chain of parent directory diectly.
--- fs/exfat/namei.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
fs/exfat/namei.c +3 -1
@@ -1190,7 +1190,9 @@ static int __exfat_rename(struct inode *return -ENOENT ; } -exfat_chain_dup (&olddir, &ei->dir); +exfat_chain_set (&olddir,EXFAT_I (old_parent_inode)->start_clu, +EXFAT_B_TO_CLU_ROUND_UP (i_size_read (old_parent_inode), sbi), +EXFAT_I (old_parent_inode)->flags); dentry = ei->entry; ep =exfat_get_dentry (sb, &olddir, dentry, &old_bh,NULL );
Greg Kroah-Hartman
maintainerPATCH 182/201 drm/amd/display: Reset DMCUB before HW init
In reply to Greg Kroah-HartmanFrom: Nicholas Kazlauskas <[email protected]>
commit 791255ca9fbe38042cfd55df5deb116dc11fef18 upstream.
[Why]
If the firmware wasn't reset by PSP or HW and is currently running then the firmware will hang or perform underfined behavior when we modify its firmware state underneath it.
[How]
Reset DMCUB before setting up cache windows and performing HW init.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +5 -0
@@ -1028,6 +1028,11 @@ static int dm_dmub_hw_init(struct amdgpureturn 0 ; } +/* Reset DMCUB if it was previously running - before we overwrite its memory. */ + status =dmub_srv_hw_reset (dmub_srv); +if (status !=DMUB_STATUS_OK ) +DRM_WARN ("Error resetting DMUB HW: %d\n" , status); + hdr = (const struct dmcub_firmware_header_v1_0 *)dmub_fw->data; fw_inst_const = dmub_fw->data +
Greg Kroah-Hartman
maintainerPATCH 183/201 drm/amd/display: Optimize bandwidth on following fast update
In reply to Greg Kroah-HartmanFrom: Nicholas Kazlauskas <[email protected]>
commit 34316c1e561db0b24e341029f04a5a5bead9a7bc upstream.
[Why]
The current call to optimize_bandwidth never occurs because flip is always pending from the FULL and FAST updates.
[How]
Optimize on the following flip when it's a FAST update and we know we aren't going to be modifying the clocks again.
--- drivers/gpu/drm/amd/display/dc/core/dc.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-)
drivers/gpu/drm/amd/display/dc/core/dc.c +8 -9
@@ -1788,6 +1788,11 @@ void dc_post_update_surfaces_to_stream(spost_surface_trace (dc); +if (dc->ctx->dce_version >=DCE_VERSION_MAX ) +TRACE_DCN_CLOCK_STATE (&context->bw_ctx.bw.dcn.clk); +else +TRACE_DCE_CLOCK_STATE (&context->bw_ctx.bw.dce); +if (is_flip_pending_in_pipes (dc, context))return ;
@@ -2974,6 +2979,9 @@ void dc_commit_updates_for_stream(structif (new_pipe->plane_state && new_pipe->plane_state != old_pipe->plane_state) new_pipe->plane_state->force_full_update = true; } + }else if (update_type ==UPDATE_TYPE_FAST ) { +/* Previous frame finished and HW is ready for optimization. */ +dc_post_update_surfaces_to_stream (dc); }
@@ -3030,15 +3038,6 @@ void dc_commit_updates_for_stream(struct pipe_ctx->plane_state->force_full_update = false; } } -/*let's use current_state to update watermark etc*/ -if (update_type >=UPDATE_TYPE_FULL ) { -dc_post_update_surfaces_to_stream (dc); - -if (dc_ctx->dce_version >=DCE_VERSION_MAX ) -TRACE_DCN_CLOCK_STATE (&context->bw_ctx.bw.dcn.clk); -else -TRACE_DCE_CLOCK_STATE (&context->bw_ctx.bw.dce); - }return ;
Greg Kroah-Hartman
maintainerPATCH 184/201 drm/amd/display: Fix surface optimization regression on Carrizo
In reply to Greg Kroah-HartmanFrom: Nicholas Kazlauskas <[email protected]>
commit 62e5a7e2333a9f5395f6a9db766b7b06c949fe7a upstream.
[Why]
DCE legacy optimization path isn't well tested under new DC optimization flow which can result in underflow occuring when initializing X11 on Carrizo.
[How]
Retain the legacy optimization flow for DCE and keep the new one for DCN to satisfy optimizations being correctly applied for ASIC that can support it.
--- drivers/gpu/drm/amd/display/dc/core/dc.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/display/dc/core/dc.c +13 -2
@@ -2979,8 +2979,13 @@ void dc_commit_updates_for_stream(structif (new_pipe->plane_state && new_pipe->plane_state != old_pipe->plane_state) new_pipe->plane_state->force_full_update = true; } - }else if (update_type ==UPDATE_TYPE_FAST ) { -/* Previous frame finished and HW is ready for optimization. */ + }else if (update_type ==UPDATE_TYPE_FAST && dc_ctx->dce_version >=DCE_VERSION_MAX ) { +/* +* Previous frame finished and HW is ready for optimization. +* +* Only relevant for DCN behavior where we can guarantee the optimization +* is safe to apply - retain the legacy behavior for DCE. +*/ dc_post_update_surfaces_to_stream (dc); }
@@ -3039,6 +3044,12 @@ void dc_commit_updates_for_stream(struct } } +/* Legacy optimization path for DCE. */ +if (update_type >=UPDATE_TYPE_FULL && dc_ctx->dce_version <DCE_VERSION_MAX ) { +dc_post_update_surfaces_to_stream (dc); +TRACE_DCE_CLOCK_STATE (&context->bw_ctx.bw.dce); + } +return ; }
Greg Kroah-Hartman
maintainerPATCH 185/201 x86/amd: Use IBPB for firmware calls
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit 28a99e95f55c61855983d36a88c05c178d966bb7 upstream.
On AMD IBRS does not prevent Retbleed; as such use IBPB before a firmware call to flush the branch history state.
And because in order to do an EFI call, the kernel maps a whole lot of the kernel page table into the EFI page table, do an IBPB just in case in order to prevent the scenario of poisoning the BTB and causing an EFI call using the unprotected RET there.
[ bp: Massage. ]
--- arch/x86/include/asm/cpufeatures.h | 1 + arch/x86/include/asm/nospec-branch.h | 2 ++ arch/x86/kernel/cpu/bugs.c | 11 ++++++++++- 3 files changed, 13 insertions(+), 1 deletion(-)
arch/x86/include/asm/cpufeatures.h +1 -0
@@ -300,6 +300,7 @@#define X86_FEATURE_RETPOLINE_LFENCE (11*32+13)/* "" Use LFENCE for Spectre variant 2 */ #define X86_FEATURE_RETHUNK (11*32+14)/* "" Use REturn THUNK */ #define X86_FEATURE_UNRET (11*32+15)/* "" AMD BTB untrain return */ +#define X86_FEATURE_USE_IBPB_FW (11*32+16)/* "" Use IBPB during runtime firmware calls */ /* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */ #define X86_FEATURE_AVX_VNNI (12*32+ 4)/* AVX VNNI instructions */
arch/x86/include/asm/nospec-branch.h +2 -0
@@ -298,6 +298,8 @@ do { \alternative_msr_write (MSR_IA32_SPEC_CTRL , \spec_ctrl_current () |SPEC_CTRL_IBRS , \X86_FEATURE_USE_IBRS_FW ); \ +alternative_msr_write (MSR_IA32_PRED_CMD ,PRED_CMD_IBPB , \ +X86_FEATURE_USE_IBPB_FW ); \ }while (0 ) #define firmware_restrict_branch_speculation_end() \
arch/x86/kernel/cpu/bugs.c +10 -1
@@ -1512,7 +1512,16 @@ static void __init spectre_v2_select_mit* the CPU supports Enhanced IBRS, kernel might un-intentionally not * enable IBRS around firmware calls. */ -if (boot_cpu_has (X86_FEATURE_IBRS ) && !spectre_v2_in_ibrs_mode (mode)) { +if (boot_cpu_has_bug (X86_BUG_RETBLEED ) && + (boot_cpu_data.x86_vendor ==X86_VENDOR_AMD || + boot_cpu_data.x86_vendor ==X86_VENDOR_HYGON )) { + +if (retbleed_cmd !=RETBLEED_CMD_IBPB ) { +setup_force_cpu_cap (X86_FEATURE_USE_IBPB_FW ); +pr_info ("Enabling Speculation Barrier for firmware calls\n" ); + } + + }else if (boot_cpu_has (X86_FEATURE_IBRS ) && !spectre_v2_in_ibrs_mode (mode)) {setup_force_cpu_cap (X86_FEATURE_USE_IBRS_FW );pr_info ("Enabling Restricted Speculation for firmware calls\n" ); }
Greg Kroah-Hartman
maintainerPATCH 186/201 x86/alternative: Report missing return thunk details
In reply to Greg Kroah-HartmanFrom: Kees Cook <[email protected]>
commit 65cdf0d623bedf0e069bb64ed52e8bb20105e2ba upstream.
Debugging missing return thunks is easier if we can see where they're happening.
--- arch/x86/kernel/alternative.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
arch/x86/kernel/alternative.c +3 -1
@@ -554,7 +554,9 @@ void __init_or_module noinline apply_ret dest = addr + insn.length + insn.immediate.value;if (__static_call_fixup (addr, op, dest) || -WARN_ON_ONCE (dest != &__x86_return_thunk)) +WARN_ONCE (dest != &__x86_return_thunk, +"missing return thunk: %pS-%pS: %*ph" , + addr, dest,5 , addr))continue ; DPRINTK("return thunk at: %pS (%px) len: %d to: %pS",
Greg Kroah-Hartman
maintainerPATCH 187/201 watchqueue: make sure to serialize wqueue->defunct properly
In reply to Greg Kroah-HartmanFrom: Linus Torvalds <[email protected]>
commit 353f7988dd8413c47718f7ca79c030b6fb62cfe5 upstream.
When the pipe is closed, we mark the associated watchqueue defunct by calling watch_queue_clear(). However, while that is protected by the watchqueue lock, new watchqueue entries aren't actually added under that lock at all: they use the pipe->rd_wait.lock instead, and looking up that pipe happens without any locking.
The watchqueue code uses the RCU read-side section to make sure that the wqueue entry itself hasn't disappeared, but that does not protect the pipe_info in any way.
So make sure to actually hold the wqueue lock when posting watch events, properly serializing against the pipe being torn down.
--- kernel/watch_queue.c | 53 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 16 deletions(-)
kernel/watch_queue.c +37 -16
@@ -34,6 +34,27 @@ MODULE_LICENSE("GPL");#define WATCH_QUEUE_NOTE_SIZE 128#define WATCH_QUEUE_NOTES_PER_PAGE (PAGE_SIZE / WATCH_QUEUE_NOTE_SIZE) +/* +* This must be called under the RCU read-lock, which makes +* sure that the wqueue still exists. It can then take the lock, +* and check that the wqueue hasn't been destroyed, which in +* turn makes sure that the notification pipe still exists. +*/ +static inline bool lock_wqueue (struct watch_queue *wqueue) +{ +spin_lock_bh (&wqueue->lock); +if (unlikely (wqueue->defunct)) { +spin_unlock_bh (&wqueue->lock); +return false; + } +return true; +} + +static inline void unlock_wqueue (struct watch_queue *wqueue) +{ +spin_unlock_bh (&wqueue->lock); +} +static void watch_queue_pipe_buf_release (struct pipe_inode_info *pipe,struct pipe_buffer *buf) {
@@ -69,6 +90,10 @@ static const struct pipe_buf_operations/* * Post a notification to a watch queue. +* +* Must be called with the RCU lock for reading, and the +* watch_queue lock held, which guarantees that the pipe +* hasn't been released. */ static bool post_one_notification (struct watch_queue *wqueue,struct watch_notification *n)
@@ -85,9 +110,6 @@ static bool post_one_notification(structspin_lock_irq (&pipe->rd_wait.lock); -if (wqueue->defunct) - goto out; - mask = pipe->ring_size -1 ; head = pipe->head; tail = pipe->tail;
@@ -203,7 +225,10 @@ void __post_watch_notification(struct waif (security_post_notification (watch->cred, cred, n) <0 )continue ; -post_one_notification (wqueue, n); +if (lock_wqueue (wqueue)) { +post_one_notification (wqueue, n); +unlock_wqueue (wqueue);; + } }rcu_read_unlock ();
@@ -465,11 +490,12 @@ int add_watch_to_object(struct watch *wareturn -EAGAIN ; } -spin_lock_bh (&wqueue->lock); -kref_get (&wqueue->usage); -kref_get (&watch->usage); -hlist_add_head (&watch->queue_node, &wqueue->watches); -spin_unlock_bh (&wqueue->lock); +if (lock_wqueue (wqueue)) { +kref_get (&wqueue->usage); +kref_get (&watch->usage); +hlist_add_head (&watch->queue_node, &wqueue->watches); +unlock_wqueue (wqueue); + }hlist_add_head (&watch->list_node, &wlist->watchers);return 0 ;
@@ -523,20 +549,15 @@ found: wqueue =rcu_dereference (watch->queue); -/* We don't need the watch list lock for the next bit as RCU is -* protecting *wqueue from deallocation. -*/ -if (wqueue) { +if (lock_wqueue (wqueue)) {post_one_notification (wqueue, &n.watch); -spin_lock_bh (&wqueue->lock); -if (!hlist_unhashed (&watch->queue_node)) {hlist_del_init_rcu (&watch->queue_node);put_watch (watch); } -spin_unlock_bh (&wqueue->lock); +unlock_wqueue (wqueue); }if (wlist->release_watch) {
Greg Kroah-Hartman
maintainerPATCH 188/201 tty: drivers/tty/, stop using tty_schedule_flip()
In reply to Greg Kroah-HartmanFrom: Jiri Slaby <[email protected]>
commit 5f6a85158ccacc3f09744b3aafe8b11ab3b6c6f6 upstream.
Since commit a9c3f68f3cd8d (tty: Fix low_latency BUG) in 2014, tty_flip_buffer_push() is only a wrapper to tty_schedule_flip(). We are going to remove the latter (as it is used less), so call the former in drivers/tty/.
--- drivers/tty/goldfish.c | 2 +- drivers/tty/moxa.c | 4 ++-- drivers/tty/serial/lpc32xx_hs.c | 2 +- drivers/tty/vt/keyboard.c | 6 +++--- drivers/tty/vt/vt.c | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-)
drivers/tty/goldfish.c +1 -1
@@ -151,7 +151,7 @@ static irqreturn_t goldfish_tty_interrup address = (unsigned long )(void *)buf;goldfish_tty_rw (qtty, address, count,0 ); -tty_schedule_flip (&qtty->port); +tty_flip_buffer_push (&qtty->port);return IRQ_HANDLED ; }
drivers/tty/moxa.c +2 -2
@@ -1383,7 +1383,7 @@ static int moxa_poll_port(struct moxa_poif (inited && !tty_throttled (tty) &&MoxaPortRxQueue (p) >0 ) {/* RX */ MoxaPortReadData (p); -tty_schedule_flip (&p->port); +tty_flip_buffer_push (&p->port); } }else {clear_bit (EMPTYWAIT , &p->statusflags);
@@ -1408,7 +1408,7 @@ static int moxa_poll_port(struct moxa_poif (tty && (intr & IntrBreak) && !I_IGNBRK (tty)) {/* BREAK */ tty_insert_flip_char (&p->port,0 ,TTY_BREAK ); -tty_schedule_flip (&p->port); +tty_flip_buffer_push (&p->port); }if (intr & IntrLine)
drivers/tty/serial/lpc32xx_hs.c +1 -1
@@ -341,7 +341,7 @@ static irqreturn_t serial_lpc32xx_interr LPC32XX_HSUART_IIR(port->membase)); port->icount.overrun++;tty_insert_flip_char (tport,0 ,TTY_OVERRUN ); -tty_schedule_flip (tport); +tty_flip_buffer_push (tport); }/* Data received? */
drivers/tty/vt/keyboard.c +3 -3
@@ -324,13 +324,13 @@ int kbd_rate(struct kbd_repeat *rpt)static void put_queue (struct vc_data *vc,int ch) {tty_insert_flip_char (&vc->port, ch,0 ); -tty_schedule_flip (&vc->port); +tty_flip_buffer_push (&vc->port); }static void puts_queue (struct vc_data *vc,const char *cp) {tty_insert_flip_string (&vc->port, cp,strlen (cp)); -tty_schedule_flip (&vc->port); +tty_flip_buffer_push (&vc->port); }static void applkey (struct vc_data *vc,int key,char mode)
@@ -584,7 +584,7 @@ static void fn_inc_console(struct vc_datstatic void fn_send_intr (struct vc_data *vc) {tty_insert_flip_char (&vc->port,0 ,TTY_BREAK ); -tty_schedule_flip (&vc->port); +tty_flip_buffer_push (&vc->port); }static void fn_scroll_forw (struct vc_data *vc)
drivers/tty/vt/vt.c +1 -1
@@ -1833,7 +1833,7 @@ static void csi_m(struct vc_data *vc)static void respond_string (const char *p,size_t len,struct tty_port *port) {tty_insert_flip_string (port, p, len); -tty_schedule_flip (port); +tty_flip_buffer_push (port); }static void cursor_report (struct vc_data *vc,struct tty_struct *tty)
Greg Kroah-Hartman
maintainerPATCH 189/201 tty: the rest, stop using tty_schedule_flip()
In reply to Greg Kroah-HartmanFrom: Jiri Slaby <[email protected]>
commit b68b914494df4f79b4e9b58953110574af1cb7a2 upstream.
Since commit a9c3f68f3cd8d (tty: Fix low_latency BUG) in 2014, tty_flip_buffer_push() is only a wrapper to tty_schedule_flip(). We are going to remove the latter (as it is used less), so call the former in the rest of the users.
--- arch/alpha/kernel/srmcons.c | 2 +- drivers/accessibility/speakup/spk_ttyio.c | 4 ++-- drivers/s390/char/keyboard.h | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-)
arch/alpha/kernel/srmcons.c +1 -1
@@ -59,7 +59,7 @@ srmcons_do_receive_chars(struct tty_port }while ((result.bits.status &1 ) && (++loops <10 ));if (count) -tty_schedule_flip (port); +tty_flip_buffer_push (port);return count; }
drivers/accessibility/speakup/spk_ttyio.c +2 -2
@@ -88,7 +88,7 @@ static int spk_ttyio_receive_buf2(struct }if (!ldisc_data->buf_free) -/* ttyio_in will tty_schedule_flip */ +/* ttyio_in will tty_flip_buffer_push */ return 0 ;/* Make sure the consumer has read buf before we have seen
@@ -312,7 +312,7 @@ static unsigned char ttyio_in(struct spkmb (); ldisc_data->buf_free = true;/* Let TTY push more characters */ -tty_schedule_flip (tty->port); +tty_flip_buffer_push (tty->port);return rv; }
drivers/s390/char/keyboard.h +2 -2
@@ -56,7 +56,7 @@ static inline void kbd_put_queue(struct tty_port *port, int ch) { tty_insert_flip_char(port, ch, 0); -tty_schedule_flip (port); +tty_flip_buffer_push (port); } static inline void
@@ -64,5 +64,5 @@ kbd_puts_queue(struct tty_port *port, ch {while (*cp)tty_insert_flip_char (port, *cp++,0 ); -tty_schedule_flip (port); +tty_flip_buffer_push (port); }
Greg Kroah-Hartman
maintainerPATCH 190/201 tty: drop tty_schedule_flip()
In reply to Greg Kroah-HartmanFrom: Jiri Slaby <[email protected]>
commit 5db96ef23bda6c2a61a51693c85b78b52d03f654 upstream.
Since commit a9c3f68f3cd8d (tty: Fix low_latency BUG) in 2014, tty_flip_buffer_push() is only a wrapper to tty_schedule_flip(). All users were converted in the previous patches, so remove tty_schedule_flip() completely while inlining its body into tty_flip_buffer_push().
One less exported function.
--- drivers/tty/tty_buffer.c | 30 ++++++++---------------------- include/linux/tty_flip.h | 1 - 2 files changed, 8 insertions(+), 23 deletions(-)
drivers/tty/tty_buffer.c +8 -22
@@ -403,27 +403,6 @@ int __tty_insert_flip_char(struct tty_poEXPORT_SYMBOL (__tty_insert_flip_char);/** -* tty_schedule_flip - push characters to ldisc -* @port: tty port to push from -* -* Takes any pending buffers and transfers their ownership to the -* ldisc side of the queue. It then schedules those characters for -* processing by the line discipline. -*/ - -void tty_schedule_flip (struct tty_port *port) -{ -struct tty_bufhead *buf = &port->buf; - -/* paired w/ acquire in flush_to_ldisc(); ensures -* flush_to_ldisc() sees buffer data. -*/ -smp_store_release (&buf->tail->commit, buf->tail->used); -queue_work (system_unbound_wq, &buf->work); -} -EXPORT_SYMBOL (tty_schedule_flip); - -/** * tty_prepare_flip_string - make room for characters * @port: tty port * @chars: return pointer for character write area
@@ -567,7 +546,14 @@ static void flush_to_ldisc(struct work_svoid tty_flip_buffer_push (struct tty_port *port) { -tty_schedule_flip (port); +struct tty_bufhead *buf = &port->buf; + +/* +* Paired w/ acquire in flush_to_ldisc(); ensures flush_to_ldisc() sees +* buffer data. +*/ +smp_store_release (&buf->tail->commit, buf->tail->used); +queue_work (system_unbound_wq, &buf->work); }EXPORT_SYMBOL (tty_flip_buffer_push);
include/linux/tty_flip.h +0 -1
@@ -17,7 +17,6 @@ extern int tty_insert_flip_string_fixed_extern int tty_prepare_flip_string (struct tty_port *port,unsigned char **chars,size_t size);extern void tty_flip_buffer_push (struct tty_port *port); -void tty_schedule_flip (struct tty_port *port);int __tty_insert_flip_char (struct tty_port *port,unsigned char ch,char flag); static inline int tty_insert_flip_char(struct tty_port *port,
Greg Kroah-Hartman
maintainerPATCH 191/201 tty: extract tty_flip_buffer_commit() from tty_flip_buffer_push()
In reply to Greg Kroah-HartmanFrom: Jiri Slaby <[email protected]>
commit 716b10580283fda66f2b88140e3964f8a7f9da89 upstream.
We will need this new helper in the next patch.
--- drivers/tty/tty_buffer.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
drivers/tty/tty_buffer.c +10 -5
@@ -533,6 +533,15 @@ static void flush_to_ldisc(struct work_s } +static inline void tty_flip_buffer_commit (struct tty_buffer *tail) +{ +/* +* Paired w/ acquire in flush_to_ldisc(); ensures flush_to_ldisc() sees +* buffer data. +*/ +smp_store_release (&tail->commit, tail->used); +} +/** * tty_flip_buffer_push - terminal * @port: tty port to push
@@ -548,11 +557,7 @@ void tty_flip_buffer_push(struct tty_por {struct tty_bufhead *buf = &port->buf; -/* -* Paired w/ acquire in flush_to_ldisc(); ensures flush_to_ldisc() sees -* buffer data. -*/ -smp_store_release (&buf->tail->commit, buf->tail->used); +tty_flip_buffer_commit (buf->tail);queue_work (system_unbound_wq, &buf->work); }EXPORT_SYMBOL (tty_flip_buffer_push);
Greg Kroah-Hartman
maintainerPATCH 192/201 tty: use new tty_insert_flip_string_and_push_buffer() in pty_write()
In reply to Greg Kroah-HartmanFrom: Jiri Slaby <[email protected]>
commit a501ab75e7624d133a5a3c7ec010687c8b961d23 upstream.
There is a race in pty_write(). pty_write() can be called in parallel with e.g. ioctl(TIOCSTI) or ioctl(TCXONC) which also inserts chars to the buffer. Provided, tty_flip_buffer_push() in pty_write() is called outside the lock, it can commit inconsistent tail. This can lead to out of bounds writes and other issues. See the Link below.
To fix this, we have to introduce a new helper called tty_insert_flip_string_and_push_buffer(). It does both tty_insert_flip_string() and tty_flip_buffer_commit() under the port lock. It also calls queue_work(), but outside the lock. See 71a174b39f10 (pty: do tty_flip_buffer_push without port->lock in pty_write) for the reasons.
Keep the helper internal-only (in drivers' tty.h). It is not intended to be used widely.
--- drivers/tty/pty.c | 14 ++------------ drivers/tty/tty.h | 3 +++ drivers/tty/tty_buffer.c | 31 +++++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 12 deletions(-)
drivers/tty/pty.c +2 -12
@@ -111,21 +111,11 @@ static void pty_unthrottle(struct tty_ststatic int pty_write (struct tty_struct *tty,const unsigned char *buf,int c) {struct tty_struct *to = tty->link; -unsigned long flags; -if (tty->flow.stopped) +if (tty->flow.stopped || !c)return 0 ; -if (c >0 ) { -spin_lock_irqsave (&to->port->lock, flags); -/* Stuff the data into the input queue of the other end */ - c =tty_insert_flip_string (to->port, buf, c); -spin_unlock_irqrestore (&to->port->lock, flags); -/* And shovel */ -if (c) -tty_flip_buffer_push (to->port); - } -return c; +return tty_insert_flip_string_and_push_buffer (to->port, buf, c); }/**
drivers/tty/tty.h +3 -0
@@ -111,4 +111,7 @@ static inline void tty_audit_tiocsti(strssize_t redirected_tty_write (struct kiocb *,struct iov_iter *); +int tty_insert_flip_string_and_push_buffer (struct tty_port *port, +const unsigned char *chars,size_t cnt); +#endif
drivers/tty/tty_buffer.c +31 -0
@@ -563,6 +563,37 @@ void tty_flip_buffer_push(struct tty_porEXPORT_SYMBOL (tty_flip_buffer_push);/** +* tty_insert_flip_string_and_push_buffer - add characters to the tty buffer and +* push +* @port: tty port +* @chars: characters +* @size: size +* +* The function combines tty_insert_flip_string() and tty_flip_buffer_push() +* with the exception of properly holding the @port->lock. +* +* To be used only internally (by pty currently). +* +* Returns: the number added. +*/ +int tty_insert_flip_string_and_push_buffer (struct tty_port *port, +const unsigned char *chars,size_t size) +{ +struct tty_bufhead *buf = &port->buf; +unsigned long flags; + +spin_lock_irqsave (&port->lock, flags); + size =tty_insert_flip_string (port, chars, size); +if (size) +tty_flip_buffer_commit (buf->tail); +spin_unlock_irqrestore (&port->lock, flags); + +queue_work (system_unbound_wq, &buf->work); + +return size; +} + +/** * tty_buffer_init - prepare a tty buffer structure * @port: tty port to initialise *
Greg Kroah-Hartman
maintainerPATCH 193/201 net: usb: ax88179_178a needs FLAG_SEND_ZLP
In reply to Greg Kroah-HartmanFrom: Jose Alonso <[email protected]>
commit 36a15e1cb134c0395261ba1940762703f778438c upstream.
The extra byte inserted by usbnet.c when
(length % dev->maxpacket == 0) is causing problems to device.
This patch sets FLAG_SEND_ZLP to avoid this.
Tested with: 0b95:1790 ASIX Electronics Corp. AX88179 Gigabit Ethernet
Problems observed:
======================================================================
1) Using ssh/sshfs. The remote sshd daemon can abort with the message:
"message authentication code incorrect"
This happens because the tcp message sent is corrupted during the USB "Bulk out". The device calculate the tcp checksum and send a valid tcp message to the remote sshd. Then the encryption detects the error and aborts.
2) NETDEV WATCHDOG: ... (ax88179_178a): transmit queue 0 timed out
3) Stop normal work without any log message.
The "Bulk in" continue receiving packets normally.
The host sends "Bulk out" and the device responds with -ECONNRESET. (The netusb.c code tx_complete ignore -ECONNRESET)
Under normal conditions these errors take days to happen and in intense usage take hours.
A test with ping gives packet loss, showing that something is wrong:
ping -4 -s 462 {destination} # 462 = 512 - 42 - 8
Not all packets fail.
My guess is that the device tries to find another packet starting at the extra byte and will fail or not depending on the next bytes (old buffer content).
======================================================================
--- drivers/net/usb/ax88179_178a.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
drivers/net/usb/ax88179_178a.c +10 -10
@@ -1796,7 +1796,7 @@ static const struct driver_info ax88179_ .link_reset = ax88179_link_reset, .reset = ax88179_reset, .stop = ax88179_stop, - .flags = FLAG_ETHER | FLAG_FRAMING_AX, + .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, .rx_fixup = ax88179_rx_fixup, .tx_fixup = ax88179_tx_fixup, };
@@ -1809,7 +1809,7 @@ static const struct driver_info ax88178a .link_reset = ax88179_link_reset, .reset = ax88179_reset, .stop = ax88179_stop, - .flags = FLAG_ETHER | FLAG_FRAMING_AX, + .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, .rx_fixup = ax88179_rx_fixup, .tx_fixup = ax88179_tx_fixup, };
@@ -1822,7 +1822,7 @@ static const struct driver_info cypress_ .link_reset = ax88179_link_reset, .reset = ax88179_reset, .stop = ax88179_stop, - .flags = FLAG_ETHER | FLAG_FRAMING_AX, + .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, .rx_fixup = ax88179_rx_fixup, .tx_fixup = ax88179_tx_fixup, };
@@ -1835,7 +1835,7 @@ static const struct driver_info dlink_du .link_reset = ax88179_link_reset, .reset = ax88179_reset, .stop = ax88179_stop, - .flags = FLAG_ETHER | FLAG_FRAMING_AX, + .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, .rx_fixup = ax88179_rx_fixup, .tx_fixup = ax88179_tx_fixup, };
@@ -1848,7 +1848,7 @@ static const struct driver_info sitecom_ .link_reset = ax88179_link_reset, .reset = ax88179_reset, .stop = ax88179_stop, - .flags = FLAG_ETHER | FLAG_FRAMING_AX, + .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, .rx_fixup = ax88179_rx_fixup, .tx_fixup = ax88179_tx_fixup, };
@@ -1861,7 +1861,7 @@ static const struct driver_info samsung_ .link_reset = ax88179_link_reset, .reset = ax88179_reset, .stop = ax88179_stop, - .flags = FLAG_ETHER | FLAG_FRAMING_AX, + .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, .rx_fixup = ax88179_rx_fixup, .tx_fixup = ax88179_tx_fixup, };
@@ -1874,7 +1874,7 @@ static const struct driver_info lenovo_i .link_reset = ax88179_link_reset, .reset = ax88179_reset, .stop = ax88179_stop, - .flags = FLAG_ETHER | FLAG_FRAMING_AX, + .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, .rx_fixup = ax88179_rx_fixup, .tx_fixup = ax88179_tx_fixup, };
@@ -1887,7 +1887,7 @@ static const struct driver_info belkin_i .link_reset = ax88179_link_reset, .reset = ax88179_reset, .stop = ax88179_stop, - .flags = FLAG_ETHER | FLAG_FRAMING_AX, + .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, .rx_fixup = ax88179_rx_fixup, .tx_fixup = ax88179_tx_fixup, };
@@ -1900,7 +1900,7 @@ static const struct driver_info toshiba_ .link_reset = ax88179_link_reset, .reset = ax88179_reset, .stop = ax88179_stop, - .flags = FLAG_ETHER | FLAG_FRAMING_AX, + .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, .rx_fixup = ax88179_rx_fixup, .tx_fixup = ax88179_tx_fixup, };
@@ -1913,7 +1913,7 @@ static const struct driver_info mct_info .link_reset = ax88179_link_reset, .reset = ax88179_reset, .stop = ax88179_stop, - .flags = FLAG_ETHER | FLAG_FRAMING_AX, + .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_SEND_ZLP, .rx_fixup = ax88179_rx_fixup, .tx_fixup = ax88179_tx_fixup, };
Greg Kroah-Hartman
maintainerPATCH 194/201 watch-queue: remove spurious double semicolon
In reply to Greg Kroah-HartmanFrom: Linus Torvalds <[email protected]>
commit 44e29e64cf1ac0cffb152e0532227ea6d002aa28 upstream.
Sedat Dilek noticed that I had an extraneous semicolon at the end of a line in the previous patch.
It's harmless, but unintentional, and while compilers just treat it as an extra empty statement, for all I know some other tooling might warn about it. So clean it up before other people notice too ;)
--- kernel/watch_queue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/watch_queue.c +1 -1
@@ -227,7 +227,7 @@ void __post_watch_notification(struct waif (lock_wqueue (wqueue)) {post_one_notification (wqueue, n); -unlock_wqueue (wqueue);; +unlock_wqueue (wqueue); } }
Greg Kroah-Hartman
maintainerPATCH 195/201 drm/amd/display: Dont lock connection_mutex for DMUB HPD
In reply to Greg Kroah-HartmanFrom: Nicholas Kazlauskas <[email protected]>
commit d82b3266ef88dc10fe0e7031b2bd8ba7eedb7e59 upstream.
[Why]
Per DRM spec we only need to hold that lock when touching connector->state - which we do not do in that handler.
Taking this locking introduces unnecessary dependencies with other threads which is bad for performance and opens up the potential for a deadlock since there are multiple locks being held at once.
[How]
Remove the connection_mutex lock/unlock routine and just iterate over the drm connectors normally. The iter helpers implicitly lock the connection list so this is safe to do.
DC link access also does not need to be guarded since the link table is static at creation - we don't dynamically add or remove links, just streams.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 ---- 1 file changed, 4 deletions(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +0 -4
@@ -668,10 +668,7 @@ void dmub_hpd_callback(struct amdgpu_devreturn ; } -drm_modeset_lock (&dev->mode_config.connection_mutex,NULL ); - link_index = notify->link_index; - link = adev->dm.dc->links[link_index];drm_connector_list_iter_begin (dev, &iter);
@@ -684,7 +681,6 @@ void dmub_hpd_callback(struct amdgpu_dev } }drm_connector_list_iter_end (&iter); -drm_modeset_unlock (&dev->mode_config.connection_mutex); }
Greg Kroah-Hartman
maintainerPATCH 196/201 drm/amd/display: invalid parameter check in dmub_hpd_callback
In reply to Greg Kroah-HartmanFrom: José Expósito <[email protected]>
commit 978ffac878fd64039f95798b15b430032d2d89d5 upstream.
The function performs a check on the "adev" input parameter, however, it is used before the check.
Initialize the "dev" variable after the sanity check to avoid a possible NULL pointer dereference.
Addresses-Coverity-ID: 1493909 ("Null pointer dereference")
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +2 -1
@@ -653,7 +653,7 @@ void dmub_hpd_callback(struct amdgpu_devstruct drm_connector_list_iter iter;struct dc_link *link;uint8_t link_index =0 ; -struct drm_device *dev = adev->dm.ddev; +struct drm_device *dev;if (adev ==NULL )return ;
@@ -670,6 +670,7 @@ void dmub_hpd_callback(struct amdgpu_dev link_index = notify->link_index; link = adev->dm.dc->links[link_index]; + dev = adev->dm.ddev;drm_connector_list_iter_begin (dev, &iter);drm_for_each_connector_iter (connector, &iter) {
Greg Kroah-Hartman
maintainerPATCH 197/201 x86/extable: Prefer local labels in .set directives
In reply to Greg Kroah-HartmanFrom: Nick Desaulniers <[email protected]>
commit 334865b2915c33080624e0d06f1c3e917036472c upstream.
Bernardo reported an error that Nathan bisected down to (x86_64) defconfig+LTO_CLANG_FULL+X86_PMEM_LEGACY.
LTO vmlinux.o
ld.lld: error: <instantiation>:1:13: redefinition of 'found' .set found, 0
^
<inline asm>:29:1: while in macro instantiation extable_type_reg reg=%eax, type=(17 | ((0) << 16)) ^
This appears to be another LTO specific issue similar to what was folded into commit 4b5305decc84 ("x86/extable: Extend extable functionality"), where the .set found, 0 in DEFINE_EXTABLE_TYPE_REG in arch/x86/include/asm/asm.h conflicts with the symbol for the static function found in arch/x86/kernel/pmem.c.
Assembler .set directive declare symbols with global visibility, so the assembler may not rename such symbols in the event of a conflict. LTO could rename static functions if there was a conflict in C sources, but it cannot see into symbols defined in inline asm.
The symbols are also retained in the symbol table, regardless of LTO.
Give the symbols .L prefixes making them locally visible, so that they may be renamed for LTO to avoid conflicts, and to drop them from the symbol table regardless of LTO.
--- arch/x86/include/asm/asm.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
arch/x86/include/asm/asm.h +10 -10
@@ -149,24 +149,24 @@# define DEFINE_EXTABLE_TYPE_REG \ ".macro extable_type_reg type:req reg:req\n" \ - ".set found, 0\n" \ - ".set regnr, 0\n" \ + ".set .Lfound, 0\n" \ + ".set .Lregnr, 0\n" \ ".irp rs,rax,rcx,rdx,rbx,rsp,rbp,rsi,rdi,r8,r9,r10,r11,r12,r13,r14,r15\n" \ ".ifc \\reg, %%\\rs\n" \ - ".set found, found+1\n" \ - ".long \\type + (regnr << 8)\n" \ + ".set .Lfound, .Lfound+1\n" \ + ".long \\type + (.Lregnr << 8)\n" \ ".endif\n" \ - ".set regnr, regnr+1\n" \ + ".set .Lregnr, .Lregnr+1\n" \ ".endr\n" \ - ".set regnr, 0\n" \ + ".set .Lregnr, 0\n" \ ".irp rs,eax,ecx,edx,ebx,esp,ebp,esi,edi,r8d,r9d,r10d,r11d,r12d,r13d,r14d,r15d\n" \ ".ifc \\reg, %%\\rs\n" \ - ".set found, found+1\n" \ - ".long \\type + (regnr << 8)\n" \ + ".set .Lfound, .Lfound+1\n" \ + ".long \\type + (.Lregnr << 8)\n" \ ".endif\n" \ - ".set regnr, regnr+1\n" \ + ".set .Lregnr, .Lregnr+1\n" \ ".endr\n" \ - ".if (found != 1)\n" \ + ".if (.Lfound != 1)\n" \ ".error \"extable_type_reg: bad register argument\"\n" \ ".endif\n" \ ".endm\n"
Greg Kroah-Hartman
maintainerPATCH 198/201 KVM: x86: fix typo in __try_cmpxchg_user causing non-atomicness
In reply to Greg Kroah-HartmanFrom: Maxim Levitsky <[email protected]>
commit 33fbe6befa622c082f7d417896832856814bdde0 upstream.
This shows up as a TDP MMU leak when running nested. Non-working cmpxchg on L0 relies makes L1 install two different shadow pages under same spte, and one of them is leaked.
Message-Id: <[email protected]>
--- arch/x86/kvm/x86.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kvm/x86.c +1 -1
@@ -6933,7 +6933,7 @@ static int emulator_cmpxchg_emulated(str goto emul_write; hva =kvm_vcpu_gfn_to_hva (vcpu,gpa_to_gfn (gpa)); -if (kvm_is_error_hva (addr)) +if (kvm_is_error_hva (hva)) goto emul_write; hva +=offset_in_page (gpa);
Greg Kroah-Hartman
maintainerPATCH 199/201 x86: drop bogus "cc" clobber from __try_cmpxchg_user_asm()
In reply to Greg Kroah-HartmanFrom: Jan Beulich <[email protected]>
commit 1df931d95f4dc1c11db1123e85d4e08156e46ef9 upstream.
As noted (and fixed) a couple of times in the past, "=@cc<cond>" outputs and clobbering of "cc" don't work well together. The compiler appears to mean to reject such, but doesn't - in its upstream form - quite manage to yet for "cc". Furthermore two similar macros don't clobber "cc", and clobbering "cc" is pointless in asm()-s for x86 anyway - the compiler always assumes status flags to be clobbered there.
Message-Id: <[email protected]>
--- arch/x86/include/asm/uaccess.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/include/asm/uaccess.h +1 -1
@@ -471,7 +471,7 @@ do { \ [ptr] "+m" (*_ptr), \[old] " +a" (__old) \ : [new] ltype (__new) \ - : "memory", "cc"); \ + : "memory"); \ if (unlikely(__err)) \ goto label; \ if (unlikely(!success)) \
Greg Kroah-Hartman
maintainerPATCH 200/201 drm/amdgpu: Off by one in dm_dmub_outbox1_low_irq()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
commit a35faec3db0e13aac8ea720bc1a3503081dd5a3d upstream.
The > ARRAY_SIZE() should be >= ARRAY_SIZE() to prevent an out of bounds access.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +1 -1
@@ -757,7 +757,7 @@ static void dm_dmub_outbox1_low_irq(voidif (irq_params->irq_src ==DC_IRQ_SOURCE_DMCUB_OUTBOX ) { do { dc_stat_get_dmub_notification(adev->dm.dc, ¬ify); - if (notify.type > ARRAY_SIZE(dm->dmub_thread_offload)) { + if (notify.type >= ARRAY_SIZE(dm->dmub_thread_offload)) { DRM_ERROR("DM: notify type %d larger than the array size %ld !", notify.type, ARRAY_SIZE(dm->dmub_thread_offload)); continue;
Greg Kroah-Hartman
maintainerPATCH 201/201 x86/entry_32: Fix segment exceptions
In reply to Greg Kroah-HartmanFrom: Peter Zijlstra <[email protected]>
commit 9cdbeec4096804083944d05da96bbaf59a1eb4f9 upstream.
The LKP robot reported that commit in Fixes: caused a failure. Turns out the ldt_gdt_32 selftest turns into an infinite loop trying to clear the segment.
As discovered by Sean, what happens is that PARANOID_EXIT_TO_KERNEL_MODE in the handle_exception_return path overwrites the entry stack data with the task stack data, restoring the "bad" segment value.
Instead of having the exception retry the instruction, have it emulate the full instruction. Replace EX_TYPE_POP_ZERO with EX_TYPE_POP_REG which will do the equivalent of: POP %reg; MOV $imm, %reg.
In order to encode the segment registers, add them as registers 8-11 for 32-bit.
By setting regs->[defg]s the (nested) RESTORE_REGS will pop this value at the end of the exception handler and by increasing regs->sp, it will have skipped the stack slot.
This was debugged by Sean Christopherson <[email protected]>.
[ bp: Add EX_REG_GS too. ]
--- arch/x86/entry/entry_32.S | 13 +++++++++---- arch/x86/include/asm/extable_fixup_types.h | 11 ++++++++++- arch/x86/lib/insn-eval.c | 5 +++++ arch/x86/mm/extable.c | 17 +++-------------- 4 files changed, 27 insertions(+), 19 deletions(-)
arch/x86/entry/entry_32.S +9 -4
@@ -268,11 +268,16 @@ 1: popl %ds 2: popl %es 3: popl %fs - addl $(4 + \pop), %esp /* pop the unused "gs" slot */ +4: addl $(4 + \pop), %esp /* pop the unused "gs" slot */ IRET_FRAME - _ASM_EXTABLE_TYPE(1b, 1b, EX_TYPE_POP_ZERO) - _ASM_EXTABLE_TYPE(2b, 2b, EX_TYPE_POP_ZERO) - _ASM_EXTABLE_TYPE(3b, 3b, EX_TYPE_POP_ZERO) + + /* + * There is no _ASM_EXTABLE_TYPE_REG() for ASM, however since this is + * ASM the registers are known and we can trivially hard-code them. + */ + _ASM_EXTABLE_TYPE(1b, 2b, EX_TYPE_POP_ZERO|EX_REG_DS) + _ASM_EXTABLE_TYPE(2b, 3b, EX_TYPE_POP_ZERO|EX_REG_ES) + _ASM_EXTABLE_TYPE(3b, 4b, EX_TYPE_POP_ZERO|EX_REG_FS) .endm .macro RESTORE_ALL_NMI cr3_reg:req pop=0
arch/x86/include/asm/extable_fixup_types.h +10 -1
@@ -16,9 +16,16 @@#define EX_DATA_FLAG_SHIFT 12#define EX_DATA_IMM_SHIFT 16 +#define EX_DATA_REG (reg) ((reg) << EX_DATA_REG_SHIFT)#define EX_DATA_FLAG (flag) ((flag) << EX_DATA_FLAG_SHIFT)#define EX_DATA_IMM (imm) ((imm) << EX_DATA_IMM_SHIFT) +/* segment regs */ +#define EX_REG_DS EX_DATA_REG(8) +#define EX_REG_ES EX_DATA_REG(9) +#define EX_REG_FS EX_DATA_REG(10) +#define EX_REG_GS EX_DATA_REG(11) +/* flags */ #define EX_FLAG_CLEAR_AX EX_DATA_FLAG(1)#define EX_FLAG_CLEAR_DX EX_DATA_FLAG(2)
@@ -41,7 +48,9 @@#define EX_TYPE_RDMSR_IN_MCE 13#define EX_TYPE_DEFAULT_MCE_SAFE 14#define EX_TYPE_FAULT_MCE_SAFE 15 -#define EX_TYPE_POP_ZERO 16 + +#define EX_TYPE_POP_REG 16/* sp += sizeof(long) */ +#define EX_TYPE_POP_ZERO (EX_TYPE_POP_REG | EX_DATA_IMM(0))#define EX_TYPE_IMM_REG 17/* reg := (long)imm */ #define EX_TYPE_EFAULT_REG (EX_TYPE_IMM_REG | EX_DATA_IMM(-EFAULT))
arch/x86/lib/insn-eval.c +5 -0
@@ -430,6 +430,11 @@ static const int pt_regoff[] = { offsetof(struct pt_regs , r13), offsetof(struct pt_regs , r14), offsetof(struct pt_regs , r15), +#else + offsetof(struct pt_regs , ds), + offsetof(struct pt_regs , es), + offsetof(struct pt_regs , fs), + offsetof(struct pt_regs, gs), #endif };
arch/x86/mm/extable.c +3 -14
@@ -118,18 +118,6 @@ static bool ex_handler_clear_fs(const streturn ex_handler_default (fixup, regs); } -static bool ex_handler_pop_zero (const struct exception_table_entry *fixup, -struct pt_regs *regs) -{ -/* -* Typically used for when "pop %seg" traps, in which case we'll clear -* the stack slot and re-try the instruction, which will then succeed -* to pop zero. -*/ - *((unsigned long *)regs->sp) =0 ; -return ex_handler_default (fixup, regs); -} -static bool ex_handler_imm_reg (const struct exception_table_entry *fixup,struct pt_regs *regs,int reg,int imm) {
@@ -203,8 +191,9 @@ int fixup_exception(struct pt_regs *regscase EX_TYPE_RDMSR_IN_MCE :ex_handler_msr_mce (regs, false);break ; -case EX_TYPE_POP_ZERO : -return ex_handler_pop_zero (e, regs); +case EX_TYPE_POP_REG : + regs->sp +=sizeof (long ); + fallthrough;case EX_TYPE_IMM_REG :return ex_handler_imm_reg (e, regs, reg, imm); }
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.15.58 release. There are 201 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri, 29 Jul 2022 16:09:50 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.58-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.15.y
and the diffstat can be found below.thanks,
greg k-h
On ARCH_BRCMSTB using 32-bit and 64-bit ARM kernels and build tested on BMIPS_GENERIC:
Signature · 1 line
Florian
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.15.58 release. There are 201 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri, 29 Jul 2022 16:09:50 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.58-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.15.y
and the diffstat can be found below.thanks,
greg k-h
Results from Linaro’s test farm.
No regressions on arm64, arm, x86_64, and i386.
## Build
* kernel: 5.15.58-rc1
* git: https://gitlab.com/Linaro/lkft/mirrors/stable/linux-stable-rc
* git branch: linux-5.15.y
* git commit: 6a9b4e0a656c73ff2dc9a24b5714c6afccff043c
* git describe: v5.15.57-202-g6a9b4e0a656c
* test details:
https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-5.15.y/build/v5.15.57-202-g6a9b4e0a656c
## Test Regressions (compared to v5.15.57)
No test regressions found.
## Metric Regressions (compared to v5.15.57)
No metric regressions found.
## Test Fixes (compared to v5.15.57)
No test fixes found.
## Metric Fixes (compared to v5.15.57)
No metric fixes found.
## Test result summary
total: 141611, pass: 127731, fail: 395, skip: 12661, xfail: 824
## Build Summary
* arc: 10 total, 10 passed, 0 failed
* arm: 313 total, 310 passed, 3 failed
* arm64: 68 total, 66 passed, 2 failed
* i386: 57 total, 50 passed, 7 failed
* mips: 50 total, 47 passed, 3 failed
* parisc: 14 total, 14 passed, 0 failed
* powerpc: 59 total, 56 passed, 3 failed
* riscv: 27 total, 27 passed, 0 failed
* s390: 26 total, 23 passed, 3 failed
* sh: 26 total, 24 passed, 2 failed
* sparc: 14 total, 14 passed, 0 failed
* x86_64: 62 total, 60 passed, 2 failed
## Test suites summary
* fwts
* igt-gpu-tools
* kunit
* kvm-unit-tests
* libgpiod
* libhugetlbfs
* log-parser-boot
* log-parser-test
* ltp-cap_bounds
* ltp-commands
* ltp-containers
* ltp-controllers
* ltp-cpuhotplug
* ltp-crypto
* ltp-cve
* ltp-dio
* ltp-fcntl-locktests
* ltp-filecaps
* ltp-fs
* ltp-fs_bind
* ltp-fs_perms_simple
* ltp-fsx
* ltp-hugetlb
* ltp-io
* ltp-ipc
* ltp-math
* ltp-mm
* ltp-nptl
* ltp-open-posix-tests
* ltp-pty
* ltp-sched
* ltp-securebits
* ltp-smoke
* ltp-syscalls
* ltp-tracing
* network-basic-tests
* packetdrill
* rcutorture
* ssuite
* v4l2-compliance
* vdso
--
Linaro LKFT
https://lkft.linaro.org
Quoted 4 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.15.58 release. There are 201 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Successfully cross-compiled for arm64 (bcm2711_defconfig, GCC 10.2.0) and powerpc (ps3_defconfig, GCC 12.1.0).
Signature · 1 line
An old man doll... just what I always wanted! - Clara
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.15.58 release. There are 201 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri, 29 Jul 2022 16:09:50 +0000. Anything received after that time might be too late.
Building i386:allyesconfig ... failed
--------------
Error log:
In file included from drivers/gpu/drm/amd/amdgpu/../display/dc/os_types.h:37,
from drivers/gpu/drm/amd/amdgpu/../display/dc/dm_services_types.h:29,
from drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:29:drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c: In function 'dm_dmub_outbox1_low_irq':drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:761:51: error: format '%ld' expects argument of type 'long int', but argument 3 has type 'unsigned int'
Needs commit 655c167edc8c26 ("drm/amd/display: Fix wrong format specifier in amdgpu_dm.c").
Guenter
Greg Kroah-Hartman
maintainerQuoted 19 lines · Guenter Roeck
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.15.58 release. There are 201 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri, 29 Jul 2022 16:09:50 +0000. Anything received after that time might be too late.
Building i386:allyesconfig ... failed
--------------
Error log:
In file included fromdrivers/gpu/drm/amd/amdgpu/../display/dc/os_types.h:37,
fromdrivers/gpu/drm/amd/amdgpu/../display/dc/dm_services_types.h:29,
fromdrivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:29:drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c: In function 'dm_dmub_outbox1_low_irq':drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:761:51: error: format '%ld' expects argument of type 'long int', but argument 3 has type 'unsigned int'
Quoted 2 lines
Needs commit
655c167edc8c26("drm/amd/display: Fix wrong format specifier inamdgpu_dm.c").
Thanks, now added. I'll push out a -rc2 now with that fix as well.
greg k-h
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.15.58 release. There are 201 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri, 29 Jul 2022 16:09:50 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.58-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.15.y
and the diffstat can be found below.thanks,
greg k-h
All tests passing for Tegra ...
Test results for stable-v5.15:
10 builds: 10 pass, 0 fail
28 boots: 28 pass, 0 fail
106 tests: 106 pass, 0 failLinux version: 5.15.58-rc1-g6a9b4e0a656c
Boards tested: tegra124-jetson-tk1, tegra186-p2771-0000,
tegra194-p2972-0000, tegra194-p3509-0000+p3668-0000,
tegra20-ventana, tegra210-p2371-2180,
tegra210-p3450-0000, tegra30-cardhu-a04Jon
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.15.58 release. There are 201 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri, 29 Jul 2022 16:09:50 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 9 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.58-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.15.y
and the diffstat can be found below.thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
thanks,
-- Shuah