6.6.64-rc1 review
Subsystems (5)
Greg Kroah-Hartman
maintainerPATCH 270/676 cpufreq: loongson2: Unregister platform_driver on failure
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuan Can <[email protected]>
[ Upstream commit 5f856d71ccdf89b4bac0ff70ebb0bb582e7f7f18 ]
When cpufreq_register_driver() returns error, the cpufreq_init() returns without unregister platform_driver, fix by add missing platform_driver_unregister() when cpufreq_register_driver() failed.
--- drivers/cpufreq/loongson2_cpufreq.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/cpufreq/loongson2_cpufreq.c +3 -1
@@ -154,7 +154,9 @@ static int __init cpufreq_init(void) ret =cpufreq_register_driver (&loongson2_cpufreq_driver); -if (!ret && !nowait) { +if (ret) { +platform_driver_unregister (&platform_driver); + }else if (!nowait) { saved_cpu_wait = cpu_wait; cpu_wait = loongson2_cpu_wait; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 271/676 powerpc/fadump: Refactor and prepare fadump_cma_init for late init
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ritesh Harjani (IBM) <[email protected]>
[ Upstream commit adfaec30ffaceecd565e06adae367aa944acc3c9 ]
We anyway don't use any return values from fadump_cma_init(). Since fadump_reserve_mem() from where fadump_cma_init() gets called today, already has the required checks.
This patch makes this function return type as void. Let's also handle extra cases like return if fadump_supported is false or dump_active, so that in later patches we can call fadump_cma_init() separately from setup_arch().
Stable-dep-of: 05b94cae1c47 ("powerpc/fadump: Move fadump_cma_init to setup_arch() after initmem_init()")
--- arch/powerpc/kernel/fadump.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-)
arch/powerpc/kernel/fadump.c +9 -14
@@ -80,27 +80,23 @@ static struct cma *fadump_cma;* But for some reason even if it fails we still have the memory reservation * with us and we can still continue doing fadump. */ -static int __init fadump_cma_init (void ) +static void __init fadump_cma_init (void ) {unsigned long long base, size;int rc; -if (!fw_dump.fadump_enabled) -return 0 ; - +if (!fw_dump.fadump_supported || !fw_dump.fadump_enabled || + fw_dump.dump_active) +return ;/* * Do not use CMA if user has provided fadump=nocma kernel parameter. -* Return 1 to continue with fadump old behaviour. */ -if (fw_dump.nocma) -return 1 ; +if (fw_dump.nocma || !fw_dump.boot_memory_size) +return ; base = fw_dump.reserve_dump_area_start; size = fw_dump.boot_memory_size; -if (!size) -return 0 ; - rc =cma_init_reserved_mem (base, size,0 ,"fadump_cma" , &fadump_cma);if (rc) {pr_err ("Failed to init cma area for firmware-assisted dump,%d\n" , rc);
@@ -110,7 +106,7 @@ static int __init fadump_cma_init(void)* blocked from production system usage. Hence return 1, * so that we can continue with fadump. */ -return 1 ; +return ; }/*
@@ -127,10 +123,9 @@ static int __init fadump_cma_init(void)cma_get_size (fadump_cma), (unsigned long )cma_get_base (fadump_cma) >>20 , fw_dump.reserve_dump_area_size); - return 1; }#else -static int __init fadump_cma_init (void ) {return 1 ; } +static void __init fadump_cma_init (void ) { }#endif /* CONFIG_CMA */ /* Scan the Firmware Assisted dump configuration details. */
@@ -648,7 +643,7 @@ int __init fadump_reserve_mem(void)pr_info ("Reserved %lldMB of memory at %#016llx (System RAM: %lldMB)\n" , (size >>20 ), base, (memblock_phys_mem_size () >>20 )); - ret =fadump_cma_init (); +fadump_cma_init (); }return ret;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 272/676 powerpc/fadump: Move fadump_cma_init to setup_arch() after initmem_init()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ritesh Harjani (IBM) <[email protected]>
[ Upstream commit 05b94cae1c47f94588c3e7096963c1007c4d9c1d ]
During early init CMA_MIN_ALIGNMENT_BYTES can be PAGE_SIZE, since pageblock_order is still zero and it gets initialized later during initmem_init() e.g.setup_arch() -> initmem_init() -> sparse_init() -> set_pageblock_order()
One such use case where this causes issue is -early_setup() -> early_init_devtree() -> fadump_reserve_mem() -> fadump_cma_init()
This causes CMA memory alignment check to be bypassed in cma_init_reserved_mem(). Then later cma_activate_area() can hit a VM_BUG_ON_PAGE(pfn & ((1 << order) - 1)) if the reserved memory area was not pageblock_order aligned.
Fix it by moving the fadump_cma_init() after initmem_init(), where other such cma reservations also gets called.
<stack trace>
==============
page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x10010 flags: 0x13ffff800000000(node=1|zone=0|lastcpupid=0x7ffff) CMA raw: 013ffff800000000 5deadbeef0000100 5deadbeef0000122 0000000000000000 raw: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000 page dumped because: VM_BUG_ON_PAGE(pfn & ((1 << order) - 1)) ------------[ cut here ]------------ kernel BUG at mm/page_alloc.c:778! Call Trace: __free_one_page+0x57c/0x7b0 (unreliable) free_pcppages_bulk+0x1a8/0x2c8 free_unref_page_commit+0x3d4/0x4e4 free_unref_page+0x458/0x6d0 init_cma_reserved_pageblock+0x114/0x198 cma_init_reserved_areas+0x270/0x3e0 do_one_initcall+0x80/0x2f8 kernel_init_freeable+0x33c/0x530 kernel_init+0x34/0x26c ret_from_kernel_user_thread+0x14/0x1c
--- arch/powerpc/include/asm/fadump.h | 7 +++++++ arch/powerpc/kernel/fadump.c | 6 +----- arch/powerpc/kernel/setup-common.c | 6 ++++-- 3 files changed, 12 insertions(+), 7 deletions(-)
arch/powerpc/include/asm/fadump.h +7 -0
@@ -32,4 +32,11 @@ extern int early_init_dt_scan_fw_dump(unsigned long node, const char *uname, int depth, void *data);extern int fadump_reserve_mem (void );#endif + +#if defined(CONFIG_FA_DUMP ) && defined(CONFIG_CMA ) +void fadump_cma_init (void ); +#else +static inline void fadump_cma_init (void ) { } +#endif +#endif /* _ASM_POWERPC_FADUMP_H */
arch/powerpc/kernel/fadump.c +1 -5
@@ -80,7 +80,7 @@ static struct cma *fadump_cma;* But for some reason even if it fails we still have the memory reservation * with us and we can still continue doing fadump. */ -static void __init fadump_cma_init (void ) +void __init fadump_cma_init (void ) {unsigned long long base, size;int rc;
@@ -124,8 +124,6 @@ static void __init fadump_cma_init(void) (unsigned long )cma_get_base (fadump_cma) >>20 , fw_dump.reserve_dump_area_size); } -#else -static void __init fadump_cma_init (void ) { }#endif /* CONFIG_CMA */ /* Scan the Firmware Assisted dump configuration details. */
@@ -642,8 +640,6 @@ int __init fadump_reserve_mem(void)pr_info ("Reserved %lldMB of memory at %#016llx (System RAM: %lldMB)\n" , (size >>20 ), base, (memblock_phys_mem_size () >>20 )); - -fadump_cma_init (); }return ret;
arch/powerpc/kernel/setup-common.c +4 -2
@@ -988,9 +988,11 @@ void __init setup_arch(char **cmdline_p)initmem_init ();/* -* Reserve large chunks of memory for use by CMA for KVM and hugetlb. These must -* be called after initmem_init(), so that pageblock_order is initialised. +* Reserve large chunks of memory for use by CMA for fadump, KVM and +* hugetlb. These must be called after initmem_init(), so that +* pageblock_order is initialised. */ +fadump_cma_init ();kvm_cma_reserve ();gigantic_hugetlb_cma_reserve ();
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 273/676 mtd: hyperbus: rpc-if: Convert to platform remove callback returning void
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Uwe Kleine-König <[email protected]>
[ Upstream commit baaa90c1c923ff2412fae0162eb66d036fd3be6b ]
The .remove() callback for a platform driver returns an int which makes many driver authors wrongly assume it's possible to do error handling by returning an error code. However the value returned is ignored (apart from emitting a warning) and this typically results in resource leaks.
To improve here there is a quest to make the remove callback return void. In the first step of this quest all drivers are converted to .remove_new(), which already returns void. Eventually after all drivers are converted, .remove_new() will be renamed to .remove().
Trivially convert this driver from always returning zero in the remove callback to the void returning variant.
Stable-dep-of: 7d189579a287 ("mtd: hyperbus: rpc-if: Add missing MODULE_DEVICE_TABLE")
--- drivers/mtd/hyperbus/rpc-if.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/mtd/hyperbus/rpc-if.c +2 -4
@@ -154,20 +154,18 @@ static int rpcif_hb_probe(struct platform_device *pdev)return error; } -static int rpcif_hb_remove (struct platform_device *pdev) +static void rpcif_hb_remove (struct platform_device *pdev) {struct rpcif_hyperbus *hyperbus =platform_get_drvdata (pdev);hyperbus_unregister_device (&hyperbus->hbdev);pm_runtime_disable (hyperbus->rpc.dev); - -return 0 ; }static struct platform_driver rpcif_platform_driver = { .probe = rpcif_hb_probe, - .remove = rpcif_hb_remove, + .remove_new = rpcif_hb_remove, .driver = { .name ="rpc-if-hyperflash" , },
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 274/676 mtd: hyperbus: rpc-if: Add missing MODULE_DEVICE_TABLE
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Biju Das <[email protected]>
[ Upstream commit 7d189579a287d5c568db623c5fc2344cce98a887 ]
The rpc-if-hyperflash driver can be compiled as a module, but lacks MODULE_DEVICE_TABLE() and will therefore not be loaded automatically. Fix this.
--- drivers/mtd/hyperbus/rpc-if.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/mtd/hyperbus/rpc-if.c +7 -0
@@ -163,9 +163,16 @@ static void rpcif_hb_remove(struct platform_device *pdev)pm_runtime_disable (hyperbus->rpc.dev); } +static const struct platform_device_id rpc_if_hyperflash_id_table[] = { + { .name ="rpc-if-hyperflash" }, + {/* sentinel */ } +}; +MODULE_DEVICE_TABLE (platform, rpc_if_hyperflash_id_table); +static struct platform_driver rpcif_platform_driver = { .probe = rpcif_hb_probe, .remove_new = rpcif_hb_remove, + .id_table = rpc_if_hyperflash_id_table, .driver = { .name ="rpc-if-hyperflash" , },
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 275/676 mtd: rawnand: atmel: Fix possible memory leak
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miquel Raynal <[email protected]>
[ Upstream commit 6d734f1bfc336aaea91313a5632f2f197608fadd ]
The pmecc "user" structure is allocated in atmel_pmecc_create_user() and was supposed to be freed with atmel_pmecc_destroy_user(), but this other helper is never called. One solution would be to find the proper location to call the destructor, but the trend today is to switch to device managed allocations, which in this case fits pretty well.
Replace kzalloc() by devm_kzalloc() and drop the destructor entirely.
--- drivers/mtd/nand/raw/atmel/pmecc.c | 8 +------- drivers/mtd/nand/raw/atmel/pmecc.h | 2 -- 2 files changed, 1 insertion(+), 9 deletions(-)
drivers/mtd/nand/raw/atmel/pmecc.c +1 -7
@@ -362,7 +362,7 @@ atmel_pmecc_create_user(struct atmel_pmecc *pmecc, size =ALIGN (size,sizeof (s32)); size += (req->ecc.strength +1 ) *sizeof (s32) *3 ; - user =kzalloc (size,GFP_KERNEL ); + user =devm_kzalloc (pmecc->dev, size,GFP_KERNEL );if (!user)return ERR_PTR (-ENOMEM );
@@ -408,12 +408,6 @@ atmel_pmecc_create_user(struct atmel_pmecc *pmecc, }EXPORT_SYMBOL_GPL (atmel_pmecc_create_user); -void atmel_pmecc_destroy_user (struct atmel_pmecc_user *user) -{ -kfree (user); -} -EXPORT_SYMBOL_GPL (atmel_pmecc_destroy_user); -static int get_strength (struct atmel_pmecc_user *user) {const int *strengths = user->pmecc->caps->strengths;
drivers/mtd/nand/raw/atmel/pmecc.h +0 -2
@@ -55,8 +55,6 @@ struct atmel_pmecc *devm_atmel_pmecc_get(struct device *dev);struct atmel_pmecc_user *atmel_pmecc_create_user (struct atmel_pmecc *pmecc,struct atmel_pmecc_user_req *req); -void atmel_pmecc_destroy_user (struct atmel_pmecc_user *user); -void atmel_pmecc_reset (struct atmel_pmecc *pmecc);int atmel_pmecc_enable (struct atmel_pmecc_user *user,int op);void atmel_pmecc_disable (struct atmel_pmecc_user *user);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 276/676 powerpc/mm/fault: Fix kfence page fault reporting
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ritesh Harjani (IBM) <[email protected]>
[ Upstream commit 06dbbb4d5f7126b6307ab807cbf04ecfc459b933 ]
copy_from_kernel_nofault() can be called when doing read of /proc/kcore. /proc/kcore can have some unmapped kfence objects which when read via copy_from_kernel_nofault() can cause page faults. Since *_nofault() functions define their own fixup table for handling fault, use that instead of asking kfence to handle such faults.
Hence we search the exception tables for the nip which generated the fault. If there is an entry then we let the fixup table handler handle the page fault by returning an error from within ___do_page_fault().
This can be easily triggered if someone tries to do dd from /proc/kcore. eg. dd if=/proc/kcore of=/dev/null bs=1M
Some example false negatives:
===============================
BUG: KFENCE: invalid read in copy_from_kernel_nofault+0x9c/0x1a0 Invalid read at 0xc0000000fdff0000: copy_from_kernel_nofault+0x9c/0x1a0 0xc00000000665f950 read_kcore_iter+0x57c/0xa04 proc_reg_read_iter+0xe4/0x16c vfs_read+0x320/0x3ec ksys_read+0x90/0x154 system_call_exception+0x120/0x310 system_call_vectored_common+0x15c/0x2ec BUG: KFENCE: use-after-free read in copy_from_kernel_nofault+0x9c/0x1a0 Use-after-free read at 0xc0000000fe050000 (in kfence-#2): copy_from_kernel_nofault+0x9c/0x1a0 0xc00000000665f950 read_kcore_iter+0x57c/0xa04 proc_reg_read_iter+0xe4/0x16c vfs_read+0x320/0x3ec ksys_read+0x90/0x154 system_call_exception+0x120/0x310 system_call_vectored_common+0x15c/0x2ec
--- arch/powerpc/mm/fault.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
arch/powerpc/mm/fault.c +8 -2
@@ -431,10 +431,16 @@ static int ___do_page_fault(struct pt_regs *regs, unsigned long address,/* * The kernel should never take an execute fault nor should it * take a page fault to a kernel address or a page fault to a user -* address outside of dedicated places +* address outside of dedicated places. +* +* Rather than kfence directly reporting false negatives, search whether +* the NIP belongs to the fixup table for cases where fault could come +* from functions like copy_from_kernel_nofault(). */ if (unlikely (!is_user &&bad_kernel_fault (regs, error_code, address, is_write))) { -if (kfence_handle_page_fault (address, is_write, regs)) +if (is_kfence_address ((void *)address) && + !search_exception_tables (instruction_pointer (regs)) && +kfence_handle_page_fault (address, is_write, regs))return 0 ;return SIGSEGV ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 277/676 mtd: spi-nor: spansion: Use nor->addr_nbytes in octal DTR mode in RD_ANY_REG_OP
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takahiro Kuwano <[email protected]>
[ Upstream commit b61c35e3404557779ec427c077f7a9f057bb053d ]
In octal DTR mode, RD_ANY_REG_OP needs to use 4-byte address regardless of flash's internal address mode. Use nor->addr_nbytes which is set to 4 during setup.
--- drivers/mtd/spi-nor/spansion.c | 1 + 1 file changed, 1 insertion(+)
drivers/mtd/spi-nor/spansion.c +1 -0
@@ -105,6 +105,7 @@ static int cypress_nor_sr_ready_and_clear_reg(struct spi_nor *nor, u64 addr)int ret;if (nor->reg_proto ==SNOR_PROTO_8_8_8_DTR ) { + op.addr.nbytes = nor->addr_nbytes; op.dummy.nbytes = params->rdsr_dummy; op.data.nbytes =2 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 278/676 powerpc/pseries: Fix dtl_access_lock to be a rw_semaphore
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Ellerman <[email protected]>
[ Upstream commit cadae3a45d23aa4f6485938a67cbc47aaaa25e38 ]
The dtl_access_lock needs to be a rw_sempahore, a sleeping lock, because the code calls kmalloc() while holding it, which can sleep:
# echo 1 > /proc/powerpc/vcpudispatch_stats
BUG: sleeping function called from invalid context at include/linux/sched/mm.h:337
in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 199, name: sh
preempt_count: 1, expected: 0
3 locks held by sh/199:
#0: c00000000a0743f8 (sb_writers#3){.+.+}-{0:0}, at: vfs_write+0x324/0x438
#1: c0000000028c7058 (dtl_enable_mutex){+.+.}-{3:3}, at: vcpudispatch_stats_write+0xd4/0x5f4
#2: c0000000028c70b8 (dtl_access_lock){+.+.}-{2:2}, at: vcpudispatch_stats_write+0x220/0x5f4
CPU: 0 PID: 199 Comm: sh Not tainted 6.10.0-rc4 #152
Hardware name: IBM pSeries (emulated by qemu) POWER9 (raw) 0x4e1202 0xf000005 of:SLOF,HEAD hv:linux,kvm pSeries
Call Trace:
dump_stack_lvl+0x130/0x148 (unreliable)
__might_resched+0x174/0x410
kmem_cache_alloc_noprof+0x340/0x3d0
alloc_dtl_buffers+0x124/0x1ac
vcpudispatch_stats_write+0x2a8/0x5f4
proc_reg_write+0xf4/0x150
vfs_write+0xfc/0x438
ksys_write+0x88/0x148
system_call_exception+0x1c4/0x5a0
system_call_common+0xf4/0x258--- arch/powerpc/include/asm/dtl.h | 4 ++-- arch/powerpc/platforms/pseries/dtl.c | 8 ++++---- arch/powerpc/platforms/pseries/lpar.c | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-)
arch/powerpc/include/asm/dtl.h +2 -2
@@ -1,8 +1,8 @@#ifndef _ASM_POWERPC_DTL_H#define _ASM_POWERPC_DTL_H +#include <linux/rwsem.h> #include <asm/lppaca.h> -#include <linux/spinlock_types.h> /* * Layout of entries in the hypervisor's dispatch trace log buffer.
@@ -35,7 +35,7 @@ struct dtl_entry {#define DTL_LOG_ALL (DTL_LOG_CEDE | DTL_LOG_PREEMPT | DTL_LOG_FAULT)extern struct kmem_cache *dtl_cache; -extern rwlock_t dtl_access_lock; +extern struct rw_semaphore dtl_access_lock;extern void register_dtl_buffer (int cpu);extern void alloc_dtl_buffers (unsigned long *time_limit);
arch/powerpc/platforms/pseries/dtl.c +4 -4
@@ -191,7 +191,7 @@ static int dtl_enable(struct dtl *dtl)return -EBUSY ;/* ensure there are no other conflicting dtl users */ -if (!read_trylock (&dtl_access_lock)) +if (!down_read_trylock (&dtl_access_lock))return -EBUSY ; n_entries = dtl_buf_entries;
@@ -199,7 +199,7 @@ static int dtl_enable(struct dtl *dtl)if (!buf) {printk (KERN_WARNING "%s: buffer alloc failed for cpu %d\n" , __func__, dtl->cpu); -read_unlock (&dtl_access_lock); +up_read (&dtl_access_lock);return -ENOMEM ; }
@@ -217,7 +217,7 @@ static int dtl_enable(struct dtl *dtl)spin_unlock (&dtl->lock);if (rc) { -read_unlock (&dtl_access_lock); +up_read (&dtl_access_lock);kmem_cache_free (dtl_cache, buf); }
@@ -232,7 +232,7 @@ static void dtl_disable(struct dtl *dtl) dtl->buf =NULL ; dtl->buf_entries =0 ;spin_unlock (&dtl->lock); -read_unlock (&dtl_access_lock); +up_read (&dtl_access_lock); }/* file interface */
arch/powerpc/platforms/pseries/lpar.c +4 -4
@@ -169,7 +169,7 @@ struct vcpu_dispatch_data {*/ #define NR_CPUS_H NR_CPUS -DEFINE_RWLOCK (dtl_access_lock); +DECLARE_RWSEM (dtl_access_lock); static DEFINE_PER_CPU(struct vcpu_dispatch_data, vcpu_disp_data); static DEFINE_PER_CPU(u64, dtl_entry_ridx); static DEFINE_PER_CPU(struct dtl_worker, dtl_workers);
@@ -463,7 +463,7 @@ static int dtl_worker_enable(unsigned long *time_limit) {int rc =0 , state; -if (!write_trylock (&dtl_access_lock)) { +if (!down_write_trylock (&dtl_access_lock)) { rc = -EBUSY ; goto out; }
@@ -479,7 +479,7 @@ static int dtl_worker_enable(unsigned long *time_limit)pr_err ("vcpudispatch_stats: unable to setup workqueue for DTL processing\n" );free_dtl_buffers (time_limit);reset_global_dtl_mask (); -write_unlock (&dtl_access_lock); +up_write (&dtl_access_lock); rc = -EINVAL ; goto out; }
@@ -494,7 +494,7 @@ static void dtl_worker_disable(unsigned long *time_limit)cpuhp_remove_state (dtl_worker_state);free_dtl_buffers (time_limit);reset_global_dtl_mask (); -write_unlock (&dtl_access_lock); +up_write (&dtl_access_lock); } static ssize_t vcpudispatch_stats_write(struct file *file, const char __user *p,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 279/676 cpufreq: CPPC: Fix possible null-ptr-deref for cpufreq_cpu_get_raw()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinjie Ruan <[email protected]>
[ Upstream commit a78e7207564258db6e373e86294a85f9d646d35a ]
cpufreq_cpu_get_raw() may return NULL if the cpu is not in policy->cpus cpu mask and it will cause null pointer dereference.
--- drivers/cpufreq/cppc_cpufreq.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/cpufreq/cppc_cpufreq.c +3 -0
@@ -428,6 +428,9 @@ static int cppc_get_cpu_power(struct device *cpu_dev,struct cppc_cpudata *cpu_data; policy =cpufreq_cpu_get_raw (cpu_dev->id); +if (!policy) +return 0 ; + cpu_data = policy->driver_data; perf_caps = &cpu_data->perf_caps; max_cap =arch_scale_cpu_capacity (cpu_dev->id);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 280/676 cpufreq: CPPC: Fix possible null-ptr-deref for cppc_get_cpu_cost()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinjie Ruan <[email protected]>
[ Upstream commit 1a1374bb8c5926674973d849feed500bc61ad535 ]
cpufreq_cpu_get_raw() may return NULL if the cpu is not in policy->cpus cpu mask and it will cause null pointer dereference, so check NULL for cppc_get_cpu_cost().
--- drivers/cpufreq/cppc_cpufreq.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/cpufreq/cppc_cpufreq.c +3 -0
@@ -498,6 +498,9 @@ static int cppc_get_cpu_cost(struct device *cpu_dev, unsigned long KHz,int step; policy =cpufreq_cpu_get_raw (cpu_dev->id); +if (!policy) +return 0 ; + cpu_data = policy->driver_data; perf_caps = &cpu_data->perf_caps; max_cap =arch_scale_cpu_capacity (cpu_dev->id);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 281/676 RDMA/hns: Fix an AEQE overflow error caused by untimely update of eq_db_ci
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: wenglianfa <[email protected]>
[ Upstream commit 571e4ab8a45e530623ab129803f090a844dd3fe9 ]
eq_db_ci is updated only after all AEQEs are processed in the AEQ interrupt handler, which is not timely enough and may result in AEQ overflow. Two optimization methods are proposed:
1. Set an upper limit for AEQE processing.
2. Move time-consuming operations such as printings to the bottom half of the interrupt.
cmd events and flush_cqe events are still fully processed in the top half to ensure timely handling.
--- drivers/infiniband/hw/hns/hns_roce_device.h | 1 + drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 75 ++++++++++++++------- drivers/infiniband/hw/hns/hns_roce_hw_v2.h | 5 ++ drivers/infiniband/hw/hns/hns_roce_qp.c | 54 +++++++++------ 4 files changed, 91 insertions(+), 44 deletions(-)
drivers/infiniband/hw/hns/hns_roce_device.h +1 -0
@@ -1236,6 +1236,7 @@ void hns_roce_cq_completion(struct hns_roce_dev *hr_dev, u32 cqn);void hns_roce_cq_event (struct hns_roce_dev *hr_dev,u32 cqn,int event_type);void flush_cqe (struct hns_roce_dev *dev,struct hns_roce_qp *qp);void hns_roce_qp_event (struct hns_roce_dev *hr_dev,u32 qpn,int event_type); +void hns_roce_flush_cqe (struct hns_roce_dev *hr_dev,u32 qpn);void hns_roce_srq_event (struct hns_roce_dev *hr_dev,u32 srqn,int event_type);void hns_roce_handle_device_err (struct hns_roce_dev *hr_dev);int hns_roce_init (struct hns_roce_dev *hr_dev);
drivers/infiniband/hw/hns/hns_roce_hw_v2.c +50 -25
138 lines not on this page · raw message
drivers/infiniband/hw/hns/hns_roce_hw_v2.h +5 -0
@@ -85,6 +85,11 @@#define HNS_ROCE_V2_TABLE_CHUNK_SIZE (1 << 18) +/* budget must be smaller than aeqe_depth to guarantee that we update +* the ci before we polled all the entries in the EQ. +*/ +#define HNS_AEQ_POLLING_BUDGET 64 +enum {HNS_ROCE_CMD_FLAG_IN =BIT (0 ),HNS_ROCE_CMD_FLAG_OUT =BIT (1 ),
drivers/infiniband/hw/hns/hns_roce_qp.c +35 -19
72 lines not on this page · raw message
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 282/676 RDMA/hns: Use dev_* printings in hem code instead of ibdev_*
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Junxian Huang <[email protected]>
[ Upstream commit d81fb6511abf18591befaa5f4a972ffc838690ec ]
The hem code is executed before ib_dev is registered, so use dev_* printing instead of ibdev_* to avoid log like this:
(null): set HEM address to HW failed!
--- drivers/infiniband/hw/hns/hns_roce_hem.c | 44 ++++++++++++------------ 1 file changed, 22 insertions(+), 22 deletions(-)
drivers/infiniband/hw/hns/hns_roce_hem.c +22 -22
@@ -337,7 +337,7 @@ static int calc_hem_config(struct hns_roce_dev *hr_dev,struct hns_roce_hem_mhop *mhop, struct hns_roce_hem_index *index) { - struct ib_device *ibdev = &hr_dev->ib_dev; + struct device *dev = hr_dev->dev;unsigned long mhop_obj = obj;u32 l0_idx, l1_idx, l2_idx;u32 chunk_ba_num;
@@ -368,14 +368,14 @@ static int calc_hem_config(struct hns_roce_dev *hr_dev, index->buf = l0_idx;break ;default : -ibdev_err (ibdev,"table %u not support mhop.hop_num = %u!\n" , - table->type, mhop->hop_num); +dev_err (dev,"table %u not support mhop.hop_num = %u!\n" , + table->type, mhop->hop_num);return -EINVAL ; }if (unlikely (index->buf >= table->num_hem)) { -ibdev_err (ibdev,"table %u exceed hem limt idx %llu, max %lu!\n" , - table->type, index->buf, table->num_hem); +dev_err (dev,"table %u exceed hem limt idx %llu, max %lu!\n" , + table->type, index->buf, table->num_hem);return -EINVAL ; }
@@ -487,14 +487,14 @@ static int set_mhop_hem(struct hns_roce_dev *hr_dev,struct hns_roce_hem_mhop *mhop, struct hns_roce_hem_index *index) { - struct ib_device *ibdev = &hr_dev->ib_dev; + struct device *dev = hr_dev->dev;u32 step_idx;int ret =0 ;if (index->inited &HEM_INDEX_L0 ) { ret = hr_dev->hw->set_hem (hr_dev, table, obj,0 );if (ret) { -ibdev_err (ibdev,"set HEM step 0 failed!\n" ); +dev_err (dev,"set HEM step 0 failed!\n" ); goto out; } }
@@ -502,7 +502,7 @@ static int set_mhop_hem(struct hns_roce_dev *hr_dev,if (index->inited &HEM_INDEX_L1 ) { ret = hr_dev->hw->set_hem (hr_dev, table, obj,1 );if (ret) { -ibdev_err (ibdev,"set HEM step 1 failed!\n" ); +dev_err (dev,"set HEM step 1 failed!\n" ); goto out; } }
@@ -514,7 +514,7 @@ static int set_mhop_hem(struct hns_roce_dev *hr_dev, step_idx = mhop->hop_num; ret = hr_dev->hw->set_hem (hr_dev, table, obj, step_idx);if (ret) -ibdev_err (ibdev,"set HEM step last failed!\n" ); +dev_err (dev,"set HEM step last failed!\n" ); } out:return ret;
@@ -524,14 +524,14 @@ static int hns_roce_table_mhop_get(struct hns_roce_dev *hr_dev, struct hns_roce_hem_table *table, unsigned long obj) { -struct ib_device *ibdev = &hr_dev->ib_dev;struct hns_roce_hem_index index = {};struct hns_roce_hem_mhop mhop = {}; +struct device *dev = hr_dev->dev;int ret; ret =calc_hem_config (hr_dev, table, obj, &mhop, &index);if (ret) { -ibdev_err (ibdev,"calc hem config failed!\n" ); +dev_err (dev,"calc hem config failed!\n" );return ret; }
@@ -543,7 +543,7 @@ static int hns_roce_table_mhop_get(struct hns_roce_dev *hr_dev, ret =alloc_mhop_hem (hr_dev, table, &mhop, &index);if (ret) { -ibdev_err (ibdev,"alloc mhop hem failed!\n" ); +dev_err (dev,"alloc mhop hem failed!\n" ); goto out; }
@@ -551,7 +551,7 @@ static int hns_roce_table_mhop_get(struct hns_roce_dev *hr_dev,if (table->type <HEM_TYPE_MTT ) { ret =set_mhop_hem (hr_dev, table, obj, &mhop, &index);if (ret) { -ibdev_err (ibdev,"set HEM address to HW failed!\n" ); +dev_err (dev,"set HEM address to HW failed!\n" ); goto err_alloc; } }
@@ -615,7 +615,7 @@ static void clear_mhop_hem(struct hns_roce_dev *hr_dev,struct hns_roce_hem_mhop *mhop, struct hns_roce_hem_index *index) { - struct ib_device *ibdev = &hr_dev->ib_dev; + struct device *dev = hr_dev->dev;u32 hop_num = mhop->hop_num;u32 chunk_ba_num;u32 step_idx;
@@ -645,21 +645,21 @@ static void clear_mhop_hem(struct hns_roce_dev *hr_dev, ret = hr_dev->hw->clear_hem (hr_dev, table, obj, step_idx);if (ret) -ibdev_warn (ibdev,"failed to clear hop%u HEM, ret = %d.\n" , - hop_num, ret); +dev_warn (dev,"failed to clear hop%u HEM, ret = %d.\n" , + hop_num, ret);if (index->inited &HEM_INDEX_L1 ) { ret = hr_dev->hw->clear_hem (hr_dev, table, obj,1 );if (ret) -ibdev_warn (ibdev,"failed to clear HEM step 1, ret = %d.\n" , - ret); +dev_warn (dev,"failed to clear HEM step 1, ret = %d.\n" , + ret); }if (index->inited &HEM_INDEX_L0 ) { ret = hr_dev->hw->clear_hem (hr_dev, table, obj,0 );if (ret) -ibdev_warn (ibdev,"failed to clear HEM step 0, ret = %d.\n" , - ret); +dev_warn (dev,"failed to clear HEM step 0, ret = %d.\n" , + ret); } } }
@@ -669,14 +669,14 @@ static void hns_roce_table_mhop_put(struct hns_roce_dev *hr_dev, unsigned long obj, int check_refcount) { -struct ib_device *ibdev = &hr_dev->ib_dev;struct hns_roce_hem_index index = {};struct hns_roce_hem_mhop mhop = {}; +struct device *dev = hr_dev->dev;int ret; ret =calc_hem_config (hr_dev, table, obj, &mhop, &index);if (ret) { -ibdev_err (ibdev,"calc hem config failed!\n" ); +dev_err (dev,"calc hem config failed!\n" );return ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 283/676 RDMA/hns: Fix cpu stuck caused by printings during reset
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: wenglianfa <[email protected]>
[ Upstream commit 323275ac2ff15b2b7b3eac391ae5d8c5a3c3a999 ]
During reset, cmd to destroy resources such as qp, cq, and mr may fail, and error logs will be printed. When a large number of resources are destroyed, there will be lots of printings, and it may lead to a cpu stuck.
Delete some unnecessary printings and replace other printing functions in these paths with the ratelimited version.
--- drivers/infiniband/hw/hns/hns_roce_cq.c | 4 +- drivers/infiniband/hw/hns/hns_roce_hem.c | 4 +- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 73 ++++++++++------------ drivers/infiniband/hw/hns/hns_roce_mr.c | 4 +- drivers/infiniband/hw/hns/hns_roce_srq.c | 4 +- 5 files changed, 41 insertions(+), 48 deletions(-)
drivers/infiniband/hw/hns/hns_roce_cq.c +2 -2
@@ -180,8 +180,8 @@ static void free_cqc(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq) ret =hns_roce_destroy_hw_ctx (hr_dev,HNS_ROCE_CMD_DESTROY_CQC , hr_cq->cqn);if (ret) -dev_err (dev,"DESTROY_CQ failed (%d) for CQN %06lx\n" , ret, - hr_cq->cqn); +dev_err_ratelimited (dev,"DESTROY_CQ failed (%d) for CQN %06lx\n" , + ret, hr_cq->cqn);xa_erase_irq (&cq_table->array, hr_cq->cqn);
drivers/infiniband/hw/hns/hns_roce_hem.c +2 -2
@@ -712,8 +712,8 @@ void hns_roce_table_put(struct hns_roce_dev *hr_dev, ret = hr_dev->hw->clear_hem (hr_dev, table, obj,HEM_HOP_STEP_DIRECT );if (ret) -dev_warn (dev,"failed to clear HEM base address, ret = %d.\n" , - ret); +dev_warn_ratelimited (dev,"failed to clear HEM base address, ret = %d.\n" , + ret);hns_roce_free_hem (hr_dev, table->hem[i]); table->hem[i] =NULL ;
drivers/infiniband/hw/hns/hns_roce_hw_v2.c +33 -40
160 lines not on this page · raw message
drivers/infiniband/hw/hns/hns_roce_mr.c +2 -2
@@ -130,8 +130,8 @@ static void hns_roce_mr_free(struct hns_roce_dev *hr_dev, struct hns_roce_mr *mrkey_to_hw_index (mr->key) & (hr_dev->caps.num_mtpts - 1));if (ret) -ibdev_warn (ibdev,"failed to destroy mpt, ret = %d.\n" , - ret); +ibdev_warn_ratelimited (ibdev,"failed to destroy mpt, ret = %d.\n" , + ret); }free_mr_pbl (hr_dev, mr);
drivers/infiniband/hw/hns/hns_roce_srq.c +2 -2
@@ -150,8 +150,8 @@ static void free_srqc(struct hns_roce_dev *hr_dev, struct hns_roce_srq *srq) ret =hns_roce_destroy_hw_ctx (hr_dev,HNS_ROCE_CMD_DESTROY_SRQ , srq->srqn);if (ret) -dev_err (hr_dev->dev,"DESTROY_SRQ failed (%d) for SRQN %06lx\n" , - ret, srq->srqn); +dev_err_ratelimited (hr_dev->dev,"DESTROY_SRQ failed (%d) for SRQN %06lx\n" , + ret, srq->srqn);xa_erase_irq (&srq_table->xa, srq->srqn);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 284/676 RDMA/rxe: Fix the qp flush warnings in req
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhu Yanjun <[email protected]>
[ Upstream commit ea4c990fa9e19ffef0648e40c566b94ba5ab31be ]
When the qp is in error state, the status of WQEs in the queue should be set to error. Or else the following will appear.
[ 920.617269] WARNING: CPU: 1 PID: 21 at drivers/infiniband/sw/rxe/rxe_comp.c:756 rxe_completer+0x989/0xcc0 [rdma_rxe] [ 920.617744] Modules linked in: rnbd_client(O) rtrs_client(O) rtrs_core(O) rdma_ucm rdma_cm iw_cm ib_cm crc32_generic rdma_rxe ip6_udp_tunnel udp_tunnel ib_uverbs ib_core loop brd null_blk ipv6 [ 920.618516] CPU: 1 PID: 21 Comm: ksoftirqd/1 Tainted: G O 6.1.113-storage+ #65 [ 920.618986] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014 [ 920.619396] RIP: 0010:rxe_completer+0x989/0xcc0 [rdma_rxe] [ 920.619658] Code: 0f b6 84 24 3a 02 00 00 41 89 84 24 44 04 00 00 e9 2a f7 ff ff 39 ca bb 03 00 00 00 b8 0e 00 00 00 48 0f 45 d8 e9 15 f7 ff ff <0f> 0b e9 cb f8 ff ff 41 bf f5 ff ff ff e9 08 f8 ff ff 49 8d bc 24 [ 920.620482] RSP: 0018:ffff97b7c00bbc38 EFLAGS: 00010246 [ 920.620817] RAX: 0000000000000000 RBX: 000000000000000c RCX: 0000000000000008 [ 920.621183] RDX: ffff960dc396ebc0 RSI: 0000000000005400 RDI: ffff960dc4e2fbac [ 920.621548] RBP: 0000000000000000 R08: 0000000000000001 R09: ffffffffac406450 [ 920.621884] R10: ffffffffac4060c0 R11: 0000000000000001 R12: ffff960dc4e2f800 [ 920.622254] R13: ffff960dc4e2f928 R14: ffff97b7c029c580 R15: 0000000000000000 [ 920.622609] FS: 0000000000000000(0000) GS:ffff960ef7d00000(0000) knlGS:0000000000000000 [ 920.622979] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 920.623245] CR2: 00007fa056965e90 CR3: 00000001107f1000 CR4: 00000000000006e0 [ 920.623680] Call Trace: [ 920.623815] <TASK> [ 920.623933] ? __warn+0x79/0xc0 [ 920.624116] ? rxe_completer+0x989/0xcc0 [rdma_rxe] [ 920.624356] ? report_bug+0xfb/0x150 [ 920.624594] ? handle_bug+0x3c/0x60 [ 920.624796] ? exc_invalid_op+0x14/0x70 [ 920.624976] ? asm_exc_invalid_op+0x16/0x20 [ 920.625203] ? rxe_completer+0x989/0xcc0 [rdma_rxe] [ 920.625474] ? rxe_completer+0x329/0xcc0 [rdma_rxe] [ 920.625749] rxe_do_task+0x80/0x110 [rdma_rxe] [ 920.626037] rxe_requester+0x625/0xde0 [rdma_rxe] [ 920.626310] ? rxe_cq_post+0xe2/0x180 [rdma_rxe] [ 920.626583] ? do_complete+0x18d/0x220 [rdma_rxe] [ 920.626812] ? rxe_completer+0x1a3/0xcc0 [rdma_rxe] [ 920.627050] rxe_do_task+0x80/0x110 [rdma_rxe] [ 920.627285] tasklet_action_common.constprop.0+0xa4/0x120 [ 920.627522] handle_softirqs+0xc2/0x250 [ 920.627728] ? sort_range+0x20/0x20 [ 920.627942] run_ksoftirqd+0x1f/0x30 [ 920.628158] smpboot_thread_fn+0xc7/0x1b0 [ 920.628334] kthread+0xd6/0x100 [ 920.628504] ? kthread_complete_and_exit+0x20/0x20 [ 920.628709] ret_from_fork+0x1f/0x30 [ 920.628892] </TASK>
--- drivers/infiniband/sw/rxe/rxe_req.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/infiniband/sw/rxe/rxe_req.c +4 -2
@@ -693,10 +693,12 @@ int rxe_requester(struct rxe_qp *qp)if (unlikely (qp_state (qp) ==IB_QPS_ERR )) { wqe =__req_next_wqe (qp);spin_unlock_irqrestore (&qp->state_lock, flags); -if (wqe) +if (wqe) { + wqe->status =IB_WC_WR_FLUSH_ERR ; goto err; -else + }else { goto exit; + } }if (unlikely (qp_state (qp) ==IB_QPS_RESET )) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 285/676 RDMA/bnxt_re: Check cqe flags to know imm_data vs inv_irkey
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kashyap Desai <[email protected]>
[ Upstream commit 808ca6de989c598bc5af1ae0ad971a66077efac0 ]
Invalidate rkey is cpu endian and immediate data is in big endian format. Both immediate data and invalidate the remote key returned by HW is in little endian format.
While handling the commit in fixes tag, the difference between immediate data and invalidate rkey endianness was not considered.
Without changes of this patch, Kernel ULP was failing while processing inv_rkey.
dmesg log snippet -
nvme nvme0: Bogus remote invalidation for rkey 0x2000019Fix in this patch
Do endianness conversion based on completion queue entry flag. Also, the HW completions are already converted to host endianness in bnxt_qplib_cq_process_res_rc and bnxt_qplib_cq_process_res_ud and there is no need to convert it again in bnxt_re_poll_cq. Modified the union to hold the correct data type.
--- drivers/infiniband/hw/bnxt_re/ib_verbs.c | 7 +++++-- drivers/infiniband/hw/bnxt_re/qplib_fp.h | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-)
drivers/infiniband/hw/bnxt_re/ib_verbs.c +5 -2
@@ -3559,7 +3559,7 @@ static void bnxt_re_process_res_shadow_qp_wc(struct bnxt_re_qp *gsi_sqp, wc->byte_len = orig_cqe->length; wc->qp = &gsi_qp->ib_qp; - wc->ex.imm_data =cpu_to_be32 (le32_to_cpu (orig_cqe->immdata)); + wc->ex.imm_data =cpu_to_be32 (orig_cqe->immdata); wc->src_qp = orig_cqe->src_qp;memcpy (wc->smac, orig_cqe->smac,ETH_ALEN );if (bnxt_re_is_vlan_pkt (orig_cqe, &vlan_id, &sl)) {
@@ -3704,7 +3704,10 @@ int bnxt_re_poll_cq(struct ib_cq *ib_cq, int num_entries, struct ib_wc *wc) (unsigned long )(cqe->qp_handle), struct bnxt_re_qp, qplib_qp); wc->qp = &qp->ib_qp; - wc->ex.imm_data =cpu_to_be32 (le32_to_cpu (cqe->immdata)); +if (cqe->flags &CQ_RES_RC_FLAGS_IMM ) + wc->ex.imm_data =cpu_to_be32 (cqe->immdata); +else + wc->ex.invalidate_rkey = cqe->invrkey; wc->src_qp = cqe->src_qp;memcpy (wc->smac, cqe->smac,ETH_ALEN ); wc->port_num =1 ;
drivers/infiniband/hw/bnxt_re/qplib_fp.h +1 -1
@@ -389,7 +389,7 @@ struct bnxt_qplib_cqe {u16 cfa_meta;u64 wr_id;union { -__le32 immdata; +u32 immdata;u32 invrkey; };u64 qp_handle;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 286/676 clk: sunxi-ng: d1: Fix PLL_AUDIO0 preset
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andre Przywara <[email protected]>
[ Upstream commit e0f253a52ccee3cf3eb987e99756e20c68a1aac9 ]
To work around a limitation in our clock modelling, we try to force two bits in the AUDIO0 PLL to 0, in the CCU probe routine. However the ~ operator only applies to the first expression, and does not cover the second bit, so we end up clearing only bit 1.
Group the bit-ORing with parentheses, to make it both clearer to read and actually correct.
--- drivers/clk/sunxi-ng/ccu-sun20i-d1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/sunxi-ng/ccu-sun20i-d1.c +1 -1
@@ -1371,7 +1371,7 @@ static int sun20i_d1_ccu_probe(struct platform_device *pdev)/* Enforce m1 = 0, m0 = 0 for PLL_AUDIO0 */ val =readl (reg +SUN20I_D1_PLL_AUDIO0_REG ); - val &= ~BIT (1 ) |BIT (0 ); + val &= ~(BIT (1 ) |BIT (0 ));writel (val, reg +SUN20I_D1_PLL_AUDIO0_REG );/* Force fanout-27M factor N to 0. */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 287/676 clk: renesas: rzg2l: Fix FOUTPOSTDIV clk
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Biju Das <[email protected]>
[ Upstream commit dabf72b85f298970e86891b5218459c17b57b26a ]
While computing foutpostdiv_rate, the value of params->pl5_fracin is discarded, which results in the wrong refresh rate. Fix the formula for computing foutpostdiv_rate.
--- drivers/clk/renesas/rzg2l-cpg.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
drivers/clk/renesas/rzg2l-cpg.c +6 -5
@@ -285,7 +285,7 @@ static unsigned long rzg2l_cpg_get_foutpostdiv_rate(struct rzg2l_pll5_param *params, unsigned long rate) { -unsigned long foutpostdiv_rate; +unsigned long foutpostdiv_rate, foutvco_rate; params->pl5_intin = rate /MEGA ; params->pl5_fracin =div_u64 (((u64 )rate %MEGA ) <<24 ,MEGA );
@@ -294,10 +294,11 @@ rzg2l_cpg_get_foutpostdiv_rate(struct rzg2l_pll5_param *params, params->pl5_postdiv2 =1 ; params->pl5_spread =0x16 ; - foutpostdiv_rate = -EXTAL_FREQ_IN_MEGA_HZ *MEGA / params->pl5_refdiv * - ((((params->pl5_intin <<24 ) + params->pl5_fracin)) >>24 ) / - (params->pl5_postdiv1 * params->pl5_postdiv2); + foutvco_rate =div_u64 (mul_u32_u32 (EXTAL_FREQ_IN_MEGA_HZ *MEGA , + (params->pl5_intin <<24 ) + params->pl5_fracin), + params->pl5_refdiv) >>24 ; + foutpostdiv_rate =DIV_ROUND_CLOSEST_ULL (foutvco_rate, + params->pl5_postdiv1 * params->pl5_postdiv2);return foutpostdiv_rate; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 288/676 RDMA/rxe: Set queue pair cur_qp_state when being queried
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Liu Jian <[email protected]>
[ Upstream commit 775e6d3c8fda41083b16c26d05163fd69f029a62 ]
Same with commit e375b9c92985 ("RDMA/cxgb4: Set queue pair state when
being queried"). The API for ib_query_qp requires the driver to setcur_qp_state on return, add the missing set.
--- drivers/infiniband/sw/rxe/rxe_qp.c | 1 + 1 file changed, 1 insertion(+)
drivers/infiniband/sw/rxe/rxe_qp.c +1 -0
@@ -781,6 +781,7 @@ int rxe_qp_to_attr(struct rxe_qp *qp, struct ib_qp_attr *attr, int mask)* Yield the processor */ spin_lock_irqsave (&qp->state_lock, flags); + attr->cur_qp_state =qp_state (qp);if (qp->attr.sq_draining) {spin_unlock_irqrestore (&qp->state_lock, flags);cond_resched ();
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 289/676 RISC-V: KVM: Fix APLIC in_clrip and clripnum write emulation
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yong-Xuan Wang <[email protected]>
[ Upstream commit 60821fb4dd7345e5662094accf0a52845306de8c ]
In the section "4.7 Precise effects on interrupt-pending bits" of the RISC-V AIA specification defines that:
"If the source mode is Level1 or Level0 and the interrupt domain is configured in MSI delivery mode (domaincfg.DM = 1):
The pending bit is cleared whenever the rectified input value is low, when the interrupt is forwarded by MSI, or by a relevant write to an in_clrip register or to clripnum."
Update the aplic_write_pending() to match the spec.
--- arch/riscv/kvm/aia_aplic.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/riscv/kvm/aia_aplic.c +2 -1
@@ -143,7 +143,7 @@ static void aplic_write_pending(struct aplic *aplic, u32 irq, bool pending)if (sm ==APLIC_SOURCECFG_SM_LEVEL_HIGH || sm ==APLIC_SOURCECFG_SM_LEVEL_LOW ) {if (!pending) - goto skip_write_pending; + goto noskip_write_pending;if ((irqd->state &APLIC_IRQ_STATE_INPUT ) && sm ==APLIC_SOURCECFG_SM_LEVEL_LOW ) goto skip_write_pending;
@@ -152,6 +152,7 @@ static void aplic_write_pending(struct aplic *aplic, u32 irq, bool pending) goto skip_write_pending; } +noskip_write_pending:if (pending) irqd->state |=APLIC_IRQ_STATE_PENDING ;else
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 290/676 clk: imx: lpcg-scu: SW workaround for errata (e10858)
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peng Fan <[email protected]>
[ Upstream commit 5ee063fac85656bea9cfe3570af147ba1701ba18 ]
Back-to-back LPCG writes can be ignored by the LPCG register due to a HW bug. The writes need to be separated by at least 4 cycles of the gated clock. See https://www.nxp.com.cn/docs/en/errata/IMX8_1N94W.pdf
The workaround is implemented as follows:
1. For clocks running greater than or equal to 24MHz, a read followed by the write will provide sufficient delay.
2. For clocks running below 24MHz, add a delay of 4 clock cylces after the write to the LPCG register.
--- drivers/clk/imx/clk-lpcg-scu.c | 37 ++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-)
drivers/clk/imx/clk-lpcg-scu.c +29 -8
@@ -6,10 +6,12 @@#include <linux/bits.h> #include <linux/clk-provider.h> +#include <linux/delay.h> #include <linux/err.h> #include <linux/io.h> #include <linux/slab.h> #include <linux/spinlock.h> +#include <linux/units.h> #include "clk-scu.h"
@@ -41,6 +43,29 @@ struct clk_lpcg_scu {#define to_clk_lpcg_scu (_hw) container_of(_hw, struct clk_lpcg_scu, hw) +/* e10858 -LPCG clock gating register synchronization errata */ +static void lpcg_e10858_writel (unsigned long rate,void __iomem *reg,u32 val) +{ +writel (val, reg); + +if (rate >=24 *HZ_PER_MHZ || rate ==0 ) { +/* +* The time taken to access the LPCG registers from the AP core +* through the interconnect is longer than the minimum delay +* of 4 clock cycles required by the errata. +* Adding a readl will provide sufficient delay to prevent +* back-to-back writes. +*/ +readl (reg); + }else { +/* +* For clocks running below 24MHz, wait a minimum of +* 4 clock cycles. +*/ +ndelay (4 * (DIV_ROUND_UP (1000 *HZ_PER_MHZ , rate))); + } +} +static int clk_lpcg_scu_enable (struct clk_hw *hw) {struct clk_lpcg_scu *clk =to_clk_lpcg_scu (hw);
@@ -57,7 +82,8 @@ static int clk_lpcg_scu_enable(struct clk_hw *hw) val |=CLK_GATE_SCU_LPCG_HW_SEL ; reg |= val << clk->bit_idx; -writel (reg, clk->reg); + +lpcg_e10858_writel (clk_hw_get_rate (hw), clk->reg, reg);spin_unlock_irqrestore (&imx_lpcg_scu_lock, flags);
@@ -74,7 +100,7 @@ static void clk_lpcg_scu_disable(struct clk_hw *hw) reg =readl_relaxed (clk->reg); reg &= ~(CLK_GATE_SCU_LPCG_MASK << clk->bit_idx); -writel (reg, clk->reg); +lpcg_e10858_writel (clk_hw_get_rate (hw), clk->reg, reg);spin_unlock_irqrestore (&imx_lpcg_scu_lock, flags); }
@@ -145,13 +171,8 @@ static int __maybe_unused imx_clk_lpcg_scu_resume(struct device *dev) {struct clk_lpcg_scu *clk =dev_get_drvdata (dev); -/* -* FIXME: Sometimes writes don't work unless the CPU issues -* them twice -*/ - -writel (clk->state, clk->reg);writel (clk->state, clk->reg); +lpcg_e10858_writel (0 , clk->reg, clk->state);dev_dbg (dev,"restore lpcg state 0x%x\n" , clk->state);return 0 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 291/676 clk: imx: fracn-gppll: correct PLL initialization flow
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peng Fan <[email protected]>
[ Upstream commit 557be501c38e1864b948fc6ccdf4b035d610a2ea ]
Per i.MX93 Reference Mannual 22.4 Initialization information
1. Program appropriate value of DIV[ODIV], DIV[RDIV] and DIV[MFI] as per Integer mode.
2. Wait for 5 μs.
3. Program the following field in CTRL register.
Set CTRL[POWERUP] to 1'b1 to enable PLL block.
4. Poll PLL_STATUS[PLL_LOCK] register, and wait till PLL_STATUS[PLL_LOCK] is 1'b1 and pll_lock output signal is 1'b1.
5. Set CTRL[CLKMUX_EN] to 1'b1 to enable PLL output clock.
So move the CLKMUX_EN operation after PLL locked.
--- drivers/clk/imx/clk-fracn-gppll.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/clk/imx/clk-fracn-gppll.c +3 -3
@@ -301,13 +301,13 @@ static int clk_fracn_gppll_prepare(struct clk_hw *hw) val |=POWERUP_MASK ;writel_relaxed (val, pll->base +PLL_CTRL ); - val |=CLKMUX_EN ; -writel_relaxed (val, pll->base +PLL_CTRL ); - ret =clk_fracn_gppll_wait_lock (pll);if (ret)return ret; + val |=CLKMUX_EN ; +writel_relaxed (val, pll->base +PLL_CTRL ); + val &= ~CLKMUX_BYPASS ;writel_relaxed (val, pll->base +PLL_CTRL );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 292/676 clk: imx: fracn-gppll: fix pll power up
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peng Fan <[email protected]>
[ Upstream commit ff4279618f0aec350b0fb41b2b35841324fbd96e ]
To i.MX93 which features dual Cortex-A55 cores and DSU, when using writel_relaxed to write value to PLL registers, the value might be buffered. To make sure the value has been written into the hardware, using readl to read back the register could achieve the goal.
current PLL power up flow can be simplified as below:
1. writel_relaxed to set the PLL POWERUP bit;
2. readl_poll_timeout to check the PLL lock bit:
a). timeout = ktime_add_us(ktime_get(), timeout_us); b). readl the pll the lock reg;
c). check if the pll lock bit ready
d). check if timeout
But in some corner cases, both the write in step 1 and read in step 2 will be blocked by other bus transaction in the SoC for a long time, saying the value into real hardware is just before step b). That means the timeout counting has begins for quite sometime since step a), but value still not written into real hardware until bus released just at a point before step b).
Then there maybe chances that the pll lock bit is not ready when readl done but the timeout happens. readl_poll_timeout will err return due to timeout. To avoid such unexpected failure, read back the reg to make sure the write has been done in HW reg.
So use readl after writel_relaxed to fix the issue.
Since we are here, to avoid udelay to run before writel_relaxed, use readl before udelay.
--- drivers/clk/imx/clk-fracn-gppll.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/clk/imx/clk-fracn-gppll.c +4 -0
@@ -252,9 +252,11 @@ static int clk_fracn_gppll_set_rate(struct clk_hw *hw, unsigned long drate, pll_div =FIELD_PREP (PLL_RDIV_MASK , rate->rdiv) | rate->odiv |FIELD_PREP (PLL_MFI_MASK , rate->mfi);writel_relaxed (pll_div, pll->base +PLL_DIV ); +readl (pll->base +PLL_DIV );if (pll->flags &CLK_FRACN_GPPLL_FRACN ) {writel_relaxed (rate->mfd, pll->base +PLL_DENOMINATOR );writel_relaxed (FIELD_PREP (PLL_MFN_MASK , rate->mfn), pll->base +PLL_NUMERATOR ); +readl (pll->base +PLL_NUMERATOR ); }/* Wait for 5us according to fracn mode pll doc */
@@ -263,6 +265,7 @@ static int clk_fracn_gppll_set_rate(struct clk_hw *hw, unsigned long drate,/* Enable Powerup */ tmp |=POWERUP_MASK ;writel_relaxed (tmp, pll->base +PLL_CTRL ); +readl (pll->base +PLL_CTRL );/* Wait Lock */ ret =clk_fracn_gppll_wait_lock (pll);
@@ -300,6 +303,7 @@ static int clk_fracn_gppll_prepare(struct clk_hw *hw) val |=POWERUP_MASK ;writel_relaxed (val, pll->base +PLL_CTRL ); +readl (pll->base +PLL_CTRL ); ret =clk_fracn_gppll_wait_lock (pll);if (ret)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 293/676 clk: imx: clk-scu: fix clk enable state save and restore
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dong Aisheng <[email protected]>
[ Upstream commit e81361f6cf9bf4a1848b0813bc4becb2250870b8 ]
The scu clk_ops only inplements prepare() and unprepare() callback. Saving the clock state during suspend by checking clk_hw_is_enabled() is not safe as it's possible that some device drivers may only disable the clocks without unprepare. Then the state retention will not work for such clocks.
Fixing it by checking clk_hw_is_prepared() which is more reasonable and safe.
--- drivers/clk/imx/clk-scu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/imx/clk-scu.c +1 -1
@@ -594,7 +594,7 @@ static int __maybe_unused imx_clk_scu_suspend(struct device *dev) clk->rate =clk_scu_recalc_rate (&clk->hw,0 ); else clk->rate = clk_hw_get_rate(&clk->hw); - clk->is_enabled =clk_hw_is_enabled (&clk->hw); + clk->is_enabled =clk_hw_is_prepared (&clk->hw);if (clk->parent) dev_dbg(dev, "save parent %s idx %u\n", clk_hw_get_name(clk->parent),
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 294/676 clk: imx: imx8-acm: Fix return value check in clk_imx_acm_attach_pm_domains()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yang Yingliang <[email protected]>
[ Upstream commit 81a206d736c19139d3863b79e7174f9e98b45499 ]
If device_link_add() fails, it returns NULL pointer not ERR_PTR(), replace IS_ERR() with NULL pointer check, and return -EINVAL.
--- drivers/clk/imx/clk-imx8-acm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/clk/imx/clk-imx8-acm.c +2 -2
@@ -289,9 +289,9 @@ static int clk_imx_acm_attach_pm_domains(struct device *dev,DL_FLAG_STATELESS |DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE); -if (IS_ERR (dev_pm->pd_dev_link[i])) { +if (!dev_pm->pd_dev_link[i]) {dev_pm_domain_detach (dev_pm->pd_dev[i], false); - ret =PTR_ERR (dev_pm->pd_dev_link[i]); + ret = -EINVAL ; goto detach_pm; } }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 295/676 iommu/vt-d: Fix checks and print in dmar_fault_dump_ptes()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhenzhong Duan <[email protected]>
[ Upstream commit 6ceb93f952f6ca34823ce3650c902c31b8385b40 ]
There are some issues in dmar_fault_dump_ptes():
1. return value of phys_to_virt() is used for checking if an entry is present.
2. dump is confusing, e.g., "pasid table entry is not present", confusing by unpresent pasid table vs. unpresent pasid table entry. Current code means the former.
3. pgtable_walk() is called without checking if page table is present.
Fix 1 by checking present bit of an entry before dump a lower level entry. Fix 2 by removing "entry" string, e.g., "pasid table is not present". Fix 3 by checking page table present before walk.
Take issue 3 for example, before fix:
[ 442.240357] DMAR: pasid dir entry: 0x000000012c83e001 [ 442.246661] DMAR: pasid table entry[0]: 0x0000000000000000 [ 442.253429] DMAR: pasid table entry[1]: 0x0000000000000000 [ 442.260203] DMAR: pasid table entry[2]: 0x0000000000000000 [ 442.266969] DMAR: pasid table entry[3]: 0x0000000000000000 [ 442.273733] DMAR: pasid table entry[4]: 0x0000000000000000 [ 442.280479] DMAR: pasid table entry[5]: 0x0000000000000000 [ 442.287234] DMAR: pasid table entry[6]: 0x0000000000000000 [ 442.293989] DMAR: pasid table entry[7]: 0x0000000000000000 [ 442.300742] DMAR: PTE not present at level 2
After fix:
...
[ 357.241214] DMAR: pasid table entry[6]: 0x0000000000000000 [ 357.248022] DMAR: pasid table entry[7]: 0x0000000000000000 [ 357.254824] DMAR: scalable mode page table is not present
--- drivers/iommu/intel/iommu.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-)
drivers/iommu/intel/iommu.c +20 -9
@@ -845,11 +845,11 @@ void dmar_fault_dump_ptes(struct intel_iommu *iommu, u16 source_id,pr_info ("Dump %s table entries for IOVA 0x%llx\n" , iommu->name, addr);/* root entry dump */ - rt_entry = &iommu->root_entry[bus]; -if (!rt_entry) { -pr_info ("root table entry is not present\n" ); +if (!iommu->root_entry) { +pr_info ("root table is not present\n" );return ; } + rt_entry = &iommu->root_entry[bus];if (sm_supported (iommu)) pr_info("scalable mode root entry: hi 0x%016llx, low 0x%016llx\n",
@@ -860,7 +860,7 @@ void dmar_fault_dump_ptes(struct intel_iommu *iommu, u16 source_id,/* context entry dump */ ctx_entry =iommu_context_addr (iommu, bus, devfn,0 );if (!ctx_entry) { -pr_info ("context table entry is not present\n" ); +pr_info ("context table is not present\n" );return ; }
@@ -869,17 +869,23 @@ void dmar_fault_dump_ptes(struct intel_iommu *iommu, u16 source_id,/* legacy mode does not require PASID entries */ if (!sm_supported (iommu)) { +if (!context_present (ctx_entry)) { +pr_info ("legacy mode page table is not present\n" ); +return ; + } level =agaw_to_level (ctx_entry->hi &7 ); pgtable =phys_to_virt (ctx_entry->lo &VTD_PAGE_MASK ); goto pgtable_walk; } -/* get the pointer to pasid directory entry */ - dir =phys_to_virt (ctx_entry->lo &VTD_PAGE_MASK ); -if (!dir) { -pr_info ("pasid directory entry is not present\n" ); +if (!context_present (ctx_entry)) { +pr_info ("pasid directory table is not present\n" );return ; } + +/* get the pointer to pasid directory entry */ + dir =phys_to_virt (ctx_entry->lo &VTD_PAGE_MASK ); +/* For request-without-pasid, get the pasid from context entry */ if (intel_iommu_sm && pasid ==IOMMU_PASID_INVALID ) pasid =IOMMU_NO_PASID ;
@@ -891,7 +897,7 @@ void dmar_fault_dump_ptes(struct intel_iommu *iommu, u16 source_id,/* get the pointer to the pasid table entry */ entries =get_pasid_table_from_pde (pde);if (!entries) { -pr_info ("pasid table entry is not present\n" ); +pr_info ("pasid table is not present\n" );return ; } index = pasid &PASID_PTE_MASK ;
@@ -899,6 +905,11 @@ void dmar_fault_dump_ptes(struct intel_iommu *iommu, u16 source_id,for (i =0 ; i <ARRAY_SIZE (pte->val); i++)pr_info ("pasid table entry[%d]: 0x%016llx\n" , i, pte->val[i]); +if (!pasid_pte_is_present (pte)) { +pr_info ("scalable mode page table is not present\n" ); +return ; + } +if (pasid_pte_get_pgtt (pte) ==PASID_ENTRY_PGTT_FL_ONLY ) { level = pte->val[2 ] &BIT_ULL (2 ) ?5 :4 ; pgtable =phys_to_virt (pte->val[2 ] &VTD_PAGE_MASK );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 296/676 iommu/vt-d: Fix checks and print in pgtable_walk()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhenzhong Duan <[email protected]>
[ Upstream commit f1645676f25d2c846798f0233c3a953efd62aafb ]
There are some issues in pgtable_walk():
1. Super page is dumped as non-present page
2. dma_pte_superpage() should not check against leaf page table entries
3. Pointer pte is never NULL so checking it is meaningless
4. When an entry is not present, it still makes sense to dump the entry content.
Fix 1,2 by checking dma_pte_superpage()'s returned value after level check. Fix 3 by removing pte check.
Fix 4 by checking present bit after printing.
By this chance, change to print "page table not present" instead of "PTE not present" to be clearer.
--- drivers/iommu/intel/iommu.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
drivers/iommu/intel/iommu.c +6 -5
@@ -815,14 +815,15 @@ static void pgtable_walk(struct intel_iommu *iommu, unsigned long pfn,while (1 ) { offset =pfn_level_offset (pfn, level); pte = &parent[offset]; -if (!pte || (dma_pte_superpage (pte) || !dma_pte_present (pte))) { -pr_info ("PTE not present at level %d\n" , level); -break ; - }pr_info ("pte level: %d, pte value: 0x%016llx\n" , level, pte->val); -if (level ==1 ) +if (!dma_pte_present (pte)) { +pr_info ("page table not present at level %d\n" , level -1 ); +break ; + } + +if (level ==1 ||dma_pte_superpage (pte))break ; parent =phys_to_virt (dma_pte_addr (pte));
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 297/676 checkpatch: check for missing Fixes tags
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
[ Upstream commit d5d6281ae8e0c929c3ff188652f5b12c680fe8bf ]
This check looks for common words that probably indicate a patch is a fix. For now the regex is:
(?:(?:BUG: K.|UB)SAN: |Call Trace:|stable\@|syzkaller)/)
Why are stable patches encouraged to have a fixes tag? Some people mark their stable patches as "# 5.10" etc. This is useful but a Fixes tag is still a good idea. For example, the Fixes tag helps in review. It helps people to not cherry-pick buggy patches without also cherry-picking the fix.
Also if a bug affects the 5.7 kernel some people will round it up to 5.10+ because 5.7 is not supported on kernel.org. It's possible the Bad Binder bug was caused by this sort of gap where companies outside of kernel.org are supporting different kernels from kernel.org.
Should it be counted as a Fix when a patch just silences harmless WARN_ON() stack trace. Yes. Definitely.
Is silencing compiler warnings a fix? It seems unfair to the original authors, but we use -Werror now, and warnings break the build so let's just add Fixes tags. I tell people that silencing static checker warnings is not a fix but the rules on this vary by subsystem.
Is fixing a minor LTP issue (Linux Test Project) a fix? Probably? It's hard to know what to do if the LTP test has technically always been broken.
One clear false positive from this check is when someone updated their debug output and included before and after Call Traces. Or when crashes are introduced deliberately for testing. In those cases, you should just ignore checkpatch.
Stable-dep-of: 2f07b6523849 ("checkpatch: always parse orig_commit in fixes tag")
--- scripts/checkpatch.pl | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)
scripts/checkpatch.pl +24 -0
@@ -28,6 +28,7 @@ my %verbose_messages = (); my %verbose_emitted = (); my $tree = 1; my $chk_signoff = 1; +my $chk_fixes_tag = 1; my $chk_patch = 1; my $tst_only; my $emacs = 0;
@@ -88,6 +89,7 @@ Options: -v, --verbose verbose mode --no-tree run without a kernel tree --no-signoff do not check for 'Signed-off-by' line + --no-fixes-tag do not check for 'Fixes:' tag --patch treat FILE as patchfile (default) --emacs emacs compile window format --terse one line per report
@@ -295,6 +297,7 @@ GetOptions( 'v|verbose!' => \$verbose, 'tree!' => \$tree, 'signoff!' => \$chk_signoff, + 'fixes-tag!' => \$chk_fixes_tag, 'patch!' => \$chk_patch, 'emacs!' => \$emacs, 'terse!' => \$terse,
@@ -1256,6 +1259,7 @@ sub git_commit_info { } $chk_signoff = 0 if ($file); +$chk_fixes_tag = 0 if ($file); my @rawlines = (); my @lines = ();
@@ -2635,6 +2639,9 @@ sub process { our $clean = 1; my $signoff = 0; + my $fixes_tag = 0; + my $is_revert = 0; + my $needs_fixes_tag = ""; my $author = ''; my $authorsignoff = 0; my $author_sob = '';
@@ -3188,6 +3195,16 @@ sub process { } } +# These indicate a bug fix + if (!$in_header_lines && !$is_patch && + $line =~ /^This reverts commit/) { + $is_revert = 1; + } + + if (!$in_header_lines && !$is_patch && + $line =~ /((?:(?:BUG: K.|UB)SAN: |Call Trace:|stable\@|syzkaller))/) { + $needs_fixes_tag = $1; + } # Check Fixes: styles is correct if (!$in_header_lines &&
@@ -3200,6 +3217,7 @@ sub process { my $id_length = 1; my $id_case = 1; my $title_has_quotes = 0; + $fixes_tag = 1; if ($line =~ /(\s*fixes:?)\s+([0-9a-f]{5,})\s+($balanced_parens)/i) { my $tag = $1;
@@ -7680,6 +7698,12 @@ sub process { ERROR("NOT_UNIFIED_DIFF", "Does not appear to be a unified-diff format patch\n"); } + if ($is_patch && $has_commit_log && $chk_fixes_tag) { + if ($needs_fixes_tag ne "" && !$is_revert && !$fixes_tag) { + WARN("MISSING_FIXES_TAG", + "The commit message has '$needs_fixes_tag', perhaps it also needs a 'Fixes:' tag?\n"); + } + } if ($is_patch && $has_commit_log && $chk_signoff) { if ($signoff == 0) { ERROR("MISSING_SIGN_OFF",
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 298/676 checkpatch: always parse orig_commit in fixes tag
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tamir Duberstein <[email protected]>
[ Upstream commit 2f07b652384969f5d0b317e1daa5f2eb967bc73d ]
Do not require the presence of $balanced_parens to get the commit SHA; this allows a Fixes: deadbeef tag to get a correct suggestion rather than a suggestion containing a reference to HEAD.
Given this patch:
: From: Tamir Duberstein <[email protected]> : Subject: Test patch
: Date: Fri, 25 Oct 2024 19:30:51 -0400
:
: This is a test patch.
:
: Fixes: bd17e036b495
: Signed-off-by: Tamir Duberstein <[email protected]> : --- /dev/null
: +++ b/new-file
: @@ -0,0 +1 @@
: +Test.
Before:
WARNING: Please use correct Fixes: style 'Fixes: <12 chars of sha1> ("<title line>")' - ie: 'Fixes: c10a7d25e68f ("Test patch")'
After:
WARNING: Please use correct Fixes: style 'Fixes: <12 chars of sha1> ("<title line>")' - ie: 'Fixes: bd17e036b495 ("checkpatch: warn for non-standard fixes tag style")'
The prior behavior incorrectly suggested the patch's own SHA and title line rather than the referenced commit's. This fixes that.
Ironically this:
--- scripts/checkpatch.pl | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-)
scripts/checkpatch.pl +16 -21
@@ -3208,36 +3208,31 @@ sub process { # Check Fixes: styles is correct if (!$in_header_lines && - $line =~ /^\s*fixes:?\s*(?:commit\s*)?[0-9a-f]{5,}\b/i) { - my $orig_commit = ""; - my $id = "0123456789ab"; - my $title = "commit title"; - my $tag_case = 1; - my $tag_space = 1; - my $id_length = 1; - my $id_case = 1; + $line =~ /^\s*(fixes:?)\s*(?:commit\s*)?([0-9a-f]{5,40})(?:\s*($balanced_parens))?/i) { + my $tag = $1; + my $orig_commit = $2; + my $title; my $title_has_quotes = 0; $fixes_tag = 1; - - if ($line =~ /(\s*fixes:?)\s+([0-9a-f]{5,})\s+($balanced_parens)/i) { - my $tag = $1; - $orig_commit = $2; - $title = $3; - - $tag_case = 0 if $tag eq "Fixes:"; - $tag_space = 0 if ($line =~ /^fixes:? [0-9a-f]{5,} ($balanced_parens)/i); - - $id_length = 0 if ($orig_commit =~ /^[0-9a-f]{12}$/i); - $id_case = 0 if ($orig_commit !~ /[A-F]/); - + if (defined $3) { # Always strip leading/trailing parens then double quotes if existing - $title = substr($title, 1, -1); + $title = substr($3, 1, -1); if ($title =~ /^".*"$/) { $title = substr($title, 1, -1); $title_has_quotes = 1; } + } else { + $title = "commit title" } + + my $tag_case = not ($tag eq "Fixes:"); + my $tag_space = not ($line =~ /^fixes:? [0-9a-f]{5,40} ($balanced_parens)/i); + + my $id_length = not ($orig_commit =~ /^[0-9a-f]{12}$/i); + my $id_case = not ($orig_commit !~ /[A-F]/); + + my $id = "0123456789ab"; my ($cid, $ctitle) = git_commit_info($orig_commit, $id, $title);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 299/676 mfd: rt5033: Fix missing regmap_del_irq_chip()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhang Changzhong <[email protected]>
[ Upstream commit d256d612f47529ed0b332298e2d5ea981a4dd5b8 ]
Fix missing call to regmap_del_irq_chip() in error handling path by using devm_regmap_add_irq_chip().
--- drivers/mfd/rt5033.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/mfd/rt5033.c +2 -2
@@ -81,8 +81,8 @@ static int rt5033_i2c_probe(struct i2c_client *i2c) chip_rev = dev_id &RT5033_CHIP_REV_MASK ;dev_info (&i2c->dev,"Device found (rev. %d)\n" , chip_rev); - ret =regmap_add_irq_chip (rt5033->regmap, rt5033->irq, -IRQF_TRIGGER_FALLING |IRQF_ONESHOT , + ret =devm_regmap_add_irq_chip (rt5033->dev, rt5033->regmap, + rt5033->irq,IRQF_TRIGGER_FALLING |IRQF_ONESHOT ,0 , &rt5033_irq_chip, &rt5033->irq_data);if (ret) { dev_err(&i2c->dev, "Failed to request IRQ %d: %d\n",
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 300/676 fs/proc/kcore.c: fix coccinelle reported ERROR instances
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mirsad Todorovac <[email protected]>
[ Upstream commit 82e33f249f1126cf3c5f39a31b850d485ac33bc3 ]
Coccinelle complains about the nested reuse of the pointer `iter' with different pointer type:
./fs/proc/kcore.c:515:26-30: ERROR: invalid reference to the index variable of the iterator on line 499 ./fs/proc/kcore.c:534:23-27: ERROR: invalid reference to the index variable of the iterator on line 499 ./fs/proc/kcore.c:550:40-44: ERROR: invalid reference to the index variable of the iterator on line 499 ./fs/proc/kcore.c:568:27-31: ERROR: invalid reference to the index variable of the iterator on line 499 ./fs/proc/kcore.c:581:28-32: ERROR: invalid reference to the index variable of the iterator on line 499 ./fs/proc/kcore.c:599:27-31: ERROR: invalid reference to the index variable of the iterator on line 499 ./fs/proc/kcore.c:607:38-42: ERROR: invalid reference to the index variable of the iterator on line 499 ./fs/proc/kcore.c:614:26-30: ERROR: invalid reference to the index variable of the iterator on line 499
Replacing struct kcore_list *iter' with struct kcore_list *tmp' doesn't change the scope and the functionality is the same and coccinelle seems happy.
NOTE: There was an issue with using `struct kcore_list *pos' as the nested iterator.
The build did not work!
--- fs/proc/kcore.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
fs/proc/kcore.c +5 -5
@@ -493,13 +493,13 @@ static ssize_t read_kcore_iter(struct kiocb *iocb, struct iov_iter *iter)* the previous entry, search for a matching entry. */ if (!m || start < m->addr || start >= m->addr + m->size) { -struct kcore_list *iter; +struct kcore_list *pos; m =NULL ; -list_for_each_entry (iter, &kclist_head, list) { -if (start >= iter->addr && - start < iter->addr + iter->size) { - m = iter; +list_for_each_entry (pos, &kclist_head, list) { +if (start >= pos->addr && + start < pos->addr + pos->size) { + m = pos;break ; } }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 301/676 scsi: bfa: Fix use-after-free in bfad_im_module_exit()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ye Bin <[email protected]>
[ Upstream commit 178b8f38932d635e90f5f0e9af1986c6f4a89271 ]
BUG: KASAN: slab-use-after-free in __lock_acquire+0x2aca/0x3a20 Read of size 8 at addr ffff8881082d80c8 by task modprobe/25303 Call Trace: <TASK> dump_stack_lvl+0x95/0xe0 print_report+0xcb/0x620 kasan_report+0xbd/0xf0 __lock_acquire+0x2aca/0x3a20 lock_acquire+0x19b/0x520 _raw_spin_lock+0x2b/0x40 attribute_container_unregister+0x30/0x160 fc_release_transport+0x19/0x90 [scsi_transport_fc] bfad_im_module_exit+0x23/0x60 [bfa] bfad_init+0xdb/0xff0 [bfa] do_one_initcall+0xdc/0x550 do_init_module+0x22d/0x6b0 load_module+0x4e96/0x5ff0 init_module_from_file+0xcd/0x130 idempotent_init_module+0x330/0x620 __x64_sys_finit_module+0xb3/0x110 do_syscall_64+0xc1/0x1d0 entry_SYSCALL_64_after_hwframe+0x77/0x7f </TASK> Allocated by task 25303: kasan_save_stack+0x24/0x50 kasan_save_track+0x14/0x30 __kasan_kmalloc+0x7f/0x90 fc_attach_transport+0x4f/0x4740 [scsi_transport_fc] bfad_im_module_init+0x17/0x80 [bfa] bfad_init+0x23/0xff0 [bfa] do_one_initcall+0xdc/0x550 do_init_module+0x22d/0x6b0 load_module+0x4e96/0x5ff0 init_module_from_file+0xcd/0x130 idempotent_init_module+0x330/0x620 __x64_sys_finit_module+0xb3/0x110 do_syscall_64+0xc1/0x1d0 entry_SYSCALL_64_after_hwframe+0x77/0x7f Freed by task 25303: kasan_save_stack+0x24/0x50 kasan_save_track+0x14/0x30 kasan_save_free_info+0x3b/0x60 __kasan_slab_free+0x38/0x50 kfree+0x212/0x480 bfad_im_module_init+0x7e/0x80 [bfa] bfad_init+0x23/0xff0 [bfa] do_one_initcall+0xdc/0x550 do_init_module+0x22d/0x6b0 load_module+0x4e96/0x5ff0 init_module_from_file+0xcd/0x130 idempotent_init_module+0x330/0x620 __x64_sys_finit_module+0xb3/0x110 do_syscall_64+0xc1/0x1d0 entry_SYSCALL_64_after_hwframe+0x77/0x7f
Above issue happens as follows:
bfad_init
error = bfad_im_module_init()
fc_release_transport(bfad_im_scsi_transport_template);
if (error)
goto ext;ext:
bfad_im_module_exit();
fc_release_transport(bfad_im_scsi_transport_template);
--> Trigger double releaseDon't call bfad_im_module_exit() if bfad_im_module_init() failed.
--- drivers/scsi/bfa/bfad.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/scsi/bfa/bfad.c +1 -2
@@ -1693,9 +1693,8 @@ bfad_init(void) error =bfad_im_module_init ();if (error) { - error = -ENOMEM ;printk (KERN_WARNING "bfad_im_module_init failure\n" ); - goto ext; +return -ENOMEM ; }if (strcmp (FCPI_NAME ," fcpim" ) ==0 )
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 302/676 scsi: fusion: Remove unused variable rc
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zeng Heng <[email protected]>
[ Upstream commit bd65694223f7ad11c790ab63ad1af87a771192ee ]
The return value of scsi_device_reprobe() is currently ignored in _scsih_reprobe_lun(). Fixing the calling code to deal with the potential error is non-trivial, so for now just WARN_ON().
The handling of scsi_device_reprobe()'s return value refers to _scsih_reprobe_lun() and the following link:
--- drivers/message/fusion/mptsas.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/message/fusion/mptsas.c +1 -3
@@ -4234,10 +4234,8 @@ mptsas_find_phyinfo_by_phys_disk_num(MPT_ADAPTER *ioc, u8 phys_disk_num,static void mptsas_reprobe_lun (struct scsi_device *sdev,void *data) { -int rc; - sdev->no_uld_attach = data ?1 :0 ; - rc =scsi_device_reprobe (sdev); +WARN_ON (scsi_device_reprobe (sdev)); } static void
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 303/676 scsi: qedf: Fix a possible memory leak in qedf_alloc_and_init_sb()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhen Lei <[email protected]>
[ Upstream commit c62c30429db3eb4ced35c7fcf6f04a61ce3a01bb ]
Hook "qed_ops->common->sb_init = qed_sb_init" does not release the DMA memory sb_virt when it fails. Add dma_free_coherent() to free it. This is the same way as qedr_alloc_mem_sb() and qede_alloc_mem_sb().
--- drivers/scsi/qedf/qedf_main.c | 1 + 1 file changed, 1 insertion(+)
drivers/scsi/qedf/qedf_main.c +1 -0
@@ -2737,6 +2737,7 @@ static int qedf_alloc_and_init_sb(struct qedf_ctx *qedf, sb_id, QED_SB_TYPE_STORAGE);if (ret) { +dma_free_coherent (&qedf->pdev->dev,sizeof (*sb_virt), sb_virt, sb_phys);QEDF_ERR (&qedf->dbg_ctx,"Status block initialization failed (0x%x) for id = %d.\n" , ret, sb_id);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 304/676 scsi: qedi: Fix a possible memory leak in qedi_alloc_and_init_sb()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhen Lei <[email protected]>
[ Upstream commit 95bbdca4999bc59a72ebab01663d421d6ce5775d ]
Hook "qedi_ops->common->sb_init = qed_sb_init" does not release the DMA memory sb_virt when it fails. Add dma_free_coherent() to free it. This is the same way as qedr_alloc_mem_sb() and qede_alloc_mem_sb().
--- drivers/scsi/qedi/qedi_main.c | 1 + 1 file changed, 1 insertion(+)
drivers/scsi/qedi/qedi_main.c +1 -0
@@ -369,6 +369,7 @@ static int qedi_alloc_and_init_sb(struct qedi_ctx *qedi, ret = qedi_ops->common->sb_init (qedi->cdev, sb_info, sb_virt, sb_phys, sb_id,QED_SB_TYPE_STORAGE );if (ret) { +dma_free_coherent (&qedi->pdev->dev,sizeof (*sb_virt), sb_virt, sb_phys);QEDI_ERR (&qedi->dbg_ctx,"Status block initialization failed for id = %d.\n" , sb_id);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 305/676 scsi: sg: Enable runtime power management
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bart Van Assche <[email protected]>
[ Upstream commit 4045de893f691f75193c606aec440c365cf7a7be ]
In 2010, runtime power management support was implemented in the SCSI core. The description of patch "[SCSI] implement runtime Power Management" mentions that the sg driver is skipped but not why. This patch enables runtime power management even if an instance of the sg driver is held open. Enabling runtime PM for the sg driver is safe because all interactions of the sg driver with the SCSI device pass through the block layer (blk_execute_rq_nowait()) and the block layer already supports runtime PM.
--- drivers/scsi/sg.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-)
drivers/scsi/sg.c +1 -8
@@ -307,10 +307,6 @@ sg_open(struct inode *inode, struct file *filp)if (retval) goto sg_put; - retval =scsi_autopm_get_device (device); -if (retval) - goto sdp_put; -/* scsi_block_when_processing_errors() may block so bypass * check if O_NONBLOCK. Permits SCSI commands to be issued * during error recovery. Tread carefully. */
@@ -318,7 +314,7 @@ sg_open(struct inode *inode, struct file *filp) scsi_block_when_processing_errors(device))) { retval = -ENXIO ;/* we are in error recovery for this device */ - goto error_out; + goto sdp_put; }mutex_lock (&sdp->open_rel_lock);
@@ -371,8 +367,6 @@ sg_open(struct inode *inode, struct file *filp) } error_mutex_locked:mutex_unlock (&sdp->open_rel_lock); -error_out: -scsi_autopm_put_device (device); sdp_put:kref_put (&sdp->d_ref, sg_device_destroy);scsi_device_put (device);
@@ -392,7 +386,6 @@ sg_release(struct inode *inode, struct file *filp)SCSI_LOG_TIMEOUT (3 ,sg_printk (KERN_INFO , sdp,"sg_release\n" ));mutex_lock (&sdp->open_rel_lock); -scsi_autopm_put_device (sdp->device);kref_put (&sfp->f_ref, sg_remove_sfp); sdp->open_cnt--;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 306/676 x86/tdx: Skip saving output regs when SEAMCALL fails with VMFailInvalid
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kai Huang <[email protected]>
[ Upstream commit 03a423d40cb30e0e1cb77a801acb56ddb0bf6f5e ]
If SEAMCALL fails with VMFailInvalid, the SEAM software (e.g., the TDX module) won't have chance to set any output register. Skip saving the output registers to the structure in this case.
Also, as '.Lno_output_struct' is the very last symbol before RET, rename it to '.Lout' to make it short.
Opportunistically make the asm directives unindented.
Stable-dep-of: f65aa0ad79fc ("x86/tdx: Dynamically disable SEPT violations from causing #VEs")
--- arch/x86/coco/tdx/tdcall.S | 3 --- arch/x86/virt/vmx/tdx/tdxcall.S | 29 ++++++++++++++++++++--------- 2 files changed, 20 insertions(+), 12 deletions(-)
arch/x86/coco/tdx/tdcall.S +0 -3
@@ -78,10 +78,7 @@ * Return status of TDCALL via RAX. */ SYM_FUNC_START(__tdx_module_call) - FRAME_BEGIN TDX_MODULE_CALL host=0 - FRAME_END - RET SYM_FUNC_END(__tdx_module_call) /*
arch/x86/virt/vmx/tdx/tdxcall.S +20 -9
@@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 */ #include <asm/asm-offsets.h> +#include <asm/frame.h> #include <asm/tdx.h> /*
@@ -18,6 +19,7 @@ * TDX module. */ .macro TDX_MODULE_CALL host:req + FRAME_BEGIN /* * R12 will be used as temporary storage for struct tdx_module_output * pointer. Since R12-R15 registers are not used by TDCALL/SEAMCALL
@@ -44,7 +46,7 @@ mov %rsi, %rcx /* Leave input param 2 in RDX */ - .if \host +.if \host seamcall /* * SEAMCALL instruction is essentially a VMExit from VMX root
@@ -57,13 +59,10 @@ * This value will never be used as actual SEAMCALL error code as * it is from the Reserved status code class. */ - jnc .Lno_vmfailinvalid - mov $TDX_SEAMCALL_VMFAILINVALID, %rax -.Lno_vmfailinvalid: - - .else + jc .Lseamcall_vmfailinvalid +.else tdcall - .endif +.endif /* * Fetch output pointer from stack to R12 (It is used
@@ -80,7 +79,7 @@ * Other registers may contain details of the failure. */ test %r12, %r12 - jz .Lno_output_struct + jz .Lout /* Copy result registers to output struct: */ movq %rcx, TDX_MODULE_rcx(%r12)
@@ -90,7 +89,19 @@ movq %r10, TDX_MODULE_r10(%r12) movq %r11, TDX_MODULE_r11(%r12) -.Lno_output_struct: +.Lout: /* Restore the state of R12 register */ pop %r12 + + FRAME_END + RET + +.if \host +.Lseamcall_vmfailinvalid: + mov $TDX_SEAMCALL_VMFAILINVALID, %rax + /* pop the unused output pointer back to %r9 */ + pop %r9 + jmp .Lout +.endif /* \host */ + .endm
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 307/676 x86/tdx: Make macros of TDCALLs consistent with the spec
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kai Huang <[email protected]>
[ Upstream commit f0024dbfc48d8814d915eb5bd5253496b9b8a6df ]
The TDX spec names all TDCALLs with prefix "TDG". Currently, the kernel doesn't follow such convention for the macros of those TDCALLs but uses prefix "TDX_" for all of them. Although it's arguable whether the TDX spec names those TDCALLs properly, it's better for the kernel to follow the spec when naming those macros.
Change all macros of TDCALLs to make them consistent with the spec. As a bonus, they get distinguished easily from the host-side SEAMCALLs, which all have prefix "TDH".
No functional change intended.
Stable-dep-of: f65aa0ad79fc ("x86/tdx: Dynamically disable SEPT violations from causing #VEs")
--- arch/x86/coco/tdx/tdx-shared.c | 4 ++-- arch/x86/coco/tdx/tdx.c | 8 ++++---- arch/x86/include/asm/shared/tdx.h | 10 +++++----- 3 files changed, 11 insertions(+), 11 deletions(-)
arch/x86/coco/tdx/tdx-shared.c +2 -2
@@ -35,7 +35,7 @@ static unsigned long try_accept_one(phys_addr_t start, unsigned long len, } tdcall_rcx = start | page_size; -if (__tdx_module_call (TDX_ACCEPT_PAGE , tdcall_rcx,0 ,0 ,0 ,NULL )) +if (__tdx_module_call (TDG_MEM_PAGE_ACCEPT , tdcall_rcx,0 ,0 ,0 ,NULL ))return 0 ;return accept_size;
@@ -45,7 +45,7 @@ bool tdx_accept_memory(phys_addr_t start, phys_addr_t end) {/* * For shared->private conversion, accept the page using -* TDX_ACCEPT_PAGE TDX module call. +* TDG_MEM_PAGE_ACCEPT TDX module call. */ while (start < end) {unsigned long len = end - start;
arch/x86/coco/tdx/tdx.c +4 -4
@@ -93,7 +93,7 @@ int tdx_mcall_get_report0(u8 *reportdata, u8 *tdreport) {u64 ret; - ret =__tdx_module_call (TDX_GET_REPORT ,virt_to_phys (tdreport), + ret =__tdx_module_call (TDG_MR_REPORT ,virt_to_phys (tdreport),virt_to_phys (reportdata),TDREPORT_SUBTYPE_0 ,0 ,NULL );if (ret) {
@@ -154,7 +154,7 @@ static void tdx_parse_tdinfo(u64 *cc_mask)* Guest-Host-Communication Interface (GHCI), section 2.4.2 TDCALL * [TDG.VP.INFO]. */ -tdx_module_call (TDX_GET_INFO ,0 ,0 ,0 ,0 , &out); +tdx_module_call (TDG_VP_INFO ,0 ,0 ,0 ,0 , &out);/* * The highest bit of a guest physical address is the "sharing" bit.
@@ -600,7 +600,7 @@ void tdx_get_ve_info(struct ve_info *ve)* Note, the TDX module treats virtual NMIs as inhibited if the #VE * valid flag is set. It means that NMI=>#VE will not result in a #DF. */ -tdx_module_call (TDX_GET_VEINFO ,0 ,0 ,0 ,0 , &out); +tdx_module_call (TDG_VP_VEINFO_GET ,0 ,0 ,0 ,0 , &out);/* Transfer the output parameters */ ve->exit_reason = out.rcx;
@@ -780,7 +780,7 @@ void __init tdx_early_init(void)cc_set_mask (cc_mask);/* Kernel does not use NOTIFY_ENABLES and does not need random #VEs */ -tdx_module_call (TDX_WR ,0 ,TDCS_NOTIFY_ENABLES ,0 ,-1ULL ,NULL ); +tdx_module_call (TDG_VM_WR ,0 ,TDCS_NOTIFY_ENABLES ,0 ,-1ULL ,NULL );/* * All bits above GPA width are reserved and kernel treats shared bit
arch/x86/include/asm/shared/tdx.h +5 -5
@@ -11,11 +11,11 @@#define TDX_IDENT "IntelTDX "/* TDX module Call Leaf IDs */ -#define TDX_GET_INFO 1 -#define TDX_GET_VEINFO 3 -#define TDX_GET_REPORT 4 -#define TDX_ACCEPT_PAGE 6 -#define TDX_WR 8 +#define TDG_VP_INFO 1 +#define TDG_VP_VEINFO_GET 3 +#define TDG_MR_REPORT 4 +#define TDG_MEM_PAGE_ACCEPT 6 +#define TDG_VM_WR 8/* TDCS fields. To be used by TDG.VM.WR and TDG.VM.RD module calls */ #define TDCS_NOTIFY_ENABLES 0x9100000000000010
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 308/676 x86/tdx: Rename __tdx_module_call() to __tdcall()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kai Huang <[email protected]>
[ Upstream commit 5efb96289e581c187af1bc288ce5d26ed6181749 ]
__tdx_module_call() is only used by the TDX guest to issue TDCALL to the TDX module. Rename it to __tdcall() to match its behaviour, e.g., it cannot be used to make host-side SEAMCALL.
Also rename tdx_module_call() which is a wrapper of __tdx_module_call() to tdcall().
No functional change intended.
Stable-dep-of: f65aa0ad79fc ("x86/tdx: Dynamically disable SEPT violations from causing #VEs")
--- arch/x86/coco/tdx/tdcall.S | 10 +++++----- arch/x86/coco/tdx/tdx-shared.c | 2 +- arch/x86/coco/tdx/tdx.c | 18 +++++++++--------- arch/x86/include/asm/shared/tdx.h | 4 ++-- 4 files changed, 17 insertions(+), 17 deletions(-)
arch/x86/coco/tdx/tdcall.S +5 -5
@@ -40,8 +40,8 @@ .section .noinstr.text, "ax" /* - * __tdx_module_call() - Used by TDX guests to request services from - * the TDX module (does not include VMM services) using TDCALL instruction. + * __tdcall() - Used by TDX guests to request services from the TDX + * module (does not include VMM services) using TDCALL instruction. * * Transforms function call register arguments into the TDCALL register ABI. * After TDCALL operation, TDX module output is saved in @out (if it is
@@ -62,7 +62,7 @@ * *------------------------------------------------------------------------- * - * __tdx_module_call() function ABI: + * __tdcall() function ABI: * * @fn (RDI) - TDCALL Leaf ID, moved to RAX * @rcx (RSI) - Input parameter 1, moved to RCX
@@ -77,9 +77,9 @@ * * Return status of TDCALL via RAX. */ -SYM_FUNC_START(__tdx_module_call) +SYM_FUNC_START(__tdcall) TDX_MODULE_CALL host=0 -SYM_FUNC_END(__tdx_module_call) +SYM_FUNC_END(__tdcall) /* * TDX_HYPERCALL - Make hypercalls to a TDX VMM using TDVMCALL leaf of TDCALL
arch/x86/coco/tdx/tdx-shared.c +1 -1
@@ -35,7 +35,7 @@ static unsigned long try_accept_one(phys_addr_t start, unsigned long len, } tdcall_rcx = start | page_size; -if (__tdx_module_call (TDG_MEM_PAGE_ACCEPT , tdcall_rcx,0 ,0 ,0 ,NULL )) +if (__tdcall (TDG_MEM_PAGE_ACCEPT , tdcall_rcx,0 ,0 ,0 ,NULL ))return 0 ;return accept_size;
arch/x86/coco/tdx/tdx.c +9 -9
@@ -68,10 +68,10 @@ EXPORT_SYMBOL_GPL(tdx_kvm_hypercall);* should only be used for calls that have no legitimate reason to fail * or where the kernel can not survive the call failing. */ -static inline void tdx_module_call (u64 fn,u64 rcx,u64 rdx,u64 r8,u64 r9, -struct tdx_module_output *out) +static inline void tdcall (u64 fn,u64 rcx,u64 rdx,u64 r8,u64 r9, +struct tdx_module_output *out) { -if (__tdx_module_call (fn, rcx, rdx, r8, r9, out)) +if (__tdcall (fn, rcx, rdx, r8, r9, out))panic ("TDCALL %lld failed (Buggy TDX module!)\n" , fn); }
@@ -93,9 +93,9 @@ int tdx_mcall_get_report0(u8 *reportdata, u8 *tdreport) {u64 ret; - ret =__tdx_module_call (TDG_MR_REPORT ,virt_to_phys (tdreport), -virt_to_phys (reportdata),TDREPORT_SUBTYPE_0 , -0 ,NULL ); + ret =__tdcall (TDG_MR_REPORT ,virt_to_phys (tdreport), +virt_to_phys (reportdata),TDREPORT_SUBTYPE_0 , +0 ,NULL );if (ret) {if (TDCALL_RETURN_CODE (ret) ==TDCALL_INVALID_OPERAND )return -EINVAL ;
@@ -154,7 +154,7 @@ static void tdx_parse_tdinfo(u64 *cc_mask)* Guest-Host-Communication Interface (GHCI), section 2.4.2 TDCALL * [TDG.VP.INFO]. */ -tdx_module_call (TDG_VP_INFO ,0 ,0 ,0 ,0 , &out); +tdcall (TDG_VP_INFO ,0 ,0 ,0 ,0 , &out);/* * The highest bit of a guest physical address is the "sharing" bit.
@@ -600,7 +600,7 @@ void tdx_get_ve_info(struct ve_info *ve)* Note, the TDX module treats virtual NMIs as inhibited if the #VE * valid flag is set. It means that NMI=>#VE will not result in a #DF. */ -tdx_module_call (TDG_VP_VEINFO_GET ,0 ,0 ,0 ,0 , &out); +tdcall (TDG_VP_VEINFO_GET ,0 ,0 ,0 ,0 , &out);/* Transfer the output parameters */ ve->exit_reason = out.rcx;
@@ -780,7 +780,7 @@ void __init tdx_early_init(void)cc_set_mask (cc_mask);/* Kernel does not use NOTIFY_ENABLES and does not need random #VEs */ -tdx_module_call (TDG_VM_WR ,0 ,TDCS_NOTIFY_ENABLES ,0 ,-1ULL ,NULL ); +tdcall (TDG_VM_WR ,0 ,TDCS_NOTIFY_ENABLES ,0 ,-1ULL ,NULL );/* * All bits above GPA width are reserved and kernel treats shared bit
arch/x86/include/asm/shared/tdx.h +2 -2
@@ -88,8 +88,8 @@ struct tdx_module_output { };/* Used to communicate with the TDX module */ -u64 __tdx_module_call (u64 fn,u64 rcx,u64 rdx,u64 r8,u64 r9, -struct tdx_module_output *out); +u64 __tdcall (u64 fn,u64 rcx,u64 rdx,u64 r8,u64 r9, +struct tdx_module_output *out);bool tdx_accept_memory (phys_addr_t start,phys_addr_t end);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 309/676 x86/tdx: Pass TDCALL/SEAMCALL input/output registers via a structure
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kai Huang <[email protected]>
[ Upstream commit 57a420bb8186d1d0178b857e5dd5026093641654 ]
Currently, the TDX_MODULE_CALL asm macro, which handles both TDCALL and SEAMCALL, takes one parameter for each input register and an optional 'struct tdx_module_output' (a collection of output registers) as output. This is different from the TDX_HYPERCALL macro which uses a single 'struct tdx_hypercall_args' to carry all input/output registers.
The newer TDX versions introduce more TDCALLs/SEAMCALLs which use more input/output registers. Also, the TDH.VP.ENTER (which isn't covered by the current TDX_MODULE_CALL macro) basically can use all registers that the TDX_HYPERCALL does. The current TDX_MODULE_CALL macro isn't extendible to cover those cases.
Similar to the TDX_HYPERCALL macro, simplify the TDX_MODULE_CALL macro to use a single structure 'struct tdx_module_args' to carry all the input/output registers. Currently, R10/R11 are only used as output register but not as input by any TDCALL/SEAMCALL. Change to also use R10/R11 as input register to make input/output registers symmetric.
Currently, the TDX_MODULE_CALL macro depends on the caller to pass a non-NULL 'struct tdx_module_output' to get additional output registers. Similar to the TDX_HYPERCALL macro, change the TDX_MODULE_CALL macro to take a new 'ret' macro argument to indicate whether to save the output registers to the 'struct tdx_module_args'. Also introduce a new __tdcall_ret() for that purpose, similar to the __tdx_hypercall_ret().
Note the tdcall(), which is a wrapper of __tdcall(), is called by three
callers: tdx_parse_tdinfo(), tdx_get_ve_info() and tdx_early_init(). The former two need the additional output but the last one doesn't. For simplicity, make tdcall() always call __tdcall_ret() to avoid another "_ret()" wrapper. The last caller tdx_early_init() isn't performance critical anyway.
Stable-dep-of: f65aa0ad79fc ("x86/tdx: Dynamically disable SEPT violations from causing #VEs")
--- arch/x86/coco/tdx/tdcall.S | 47 ++++++--------- arch/x86/coco/tdx/tdx-shared.c | 6 +- arch/x86/coco/tdx/tdx.c | 44 +++++++------- arch/x86/include/asm/shared/tdx.h | 8 +-- arch/x86/kernel/asm-offsets.c | 12 ++-- arch/x86/virt/vmx/tdx/tdxcall.S | 95 +++++++++++++------------------ 6 files changed, 95 insertions(+), 117 deletions(-)
arch/x86/coco/tdx/tdcall.S +18 -29
@@ -43,37 +43,10 @@ * __tdcall() - Used by TDX guests to request services from the TDX * module (does not include VMM services) using TDCALL instruction. * - * Transforms function call register arguments into the TDCALL register ABI. - * After TDCALL operation, TDX module output is saved in @out (if it is - * provided by the user). - * - *------------------------------------------------------------------------- - * TDCALL ABI: - *------------------------------------------------------------------------- - * Input Registers: - * - * RAX - TDCALL Leaf number. - * RCX,RDX,R8-R9 - TDCALL Leaf specific input registers. - * - * Output Registers: - * - * RAX - TDCALL instruction error code. - * RCX,RDX,R8-R11 - TDCALL Leaf specific output registers. - * - *------------------------------------------------------------------------- - * * __tdcall() function ABI: * - * @fn (RDI) - TDCALL Leaf ID, moved to RAX - * @rcx (RSI) - Input parameter 1, moved to RCX - * @rdx (RDX) - Input parameter 2, moved to RDX - * @r8 (RCX) - Input parameter 3, moved to R8 - * @r9 (R8) - Input parameter 4, moved to R9 - * - * @out (R9) - struct tdx_module_output pointer - * stored temporarily in R12 (not - * shared with the TDX module). It - * can be NULL. + * @fn (RDI) - TDCALL Leaf ID, moved to RAX + * @args (RSI) - struct tdx_module_args for input * * Return status of TDCALL via RAX. */
@@ -81,6 +54,22 @@ SYM_FUNC_START(__tdcall) TDX_MODULE_CALL host=0 SYM_FUNC_END(__tdcall) +/* + * __tdcall_ret() - Used by TDX guests to request services from the TDX + * module (does not include VMM services) using TDCALL instruction, with + * saving output registers to the 'struct tdx_module_args' used as input. + * + * __tdcall_ret() function ABI: + * + * @fn (RDI) - TDCALL Leaf ID, moved to RAX + * @args (RSI) - struct tdx_module_args for input and output + * + * Return status of TDCALL via RAX. + */ +SYM_FUNC_START(__tdcall_ret) + TDX_MODULE_CALL host=0 ret=1 +SYM_FUNC_END(__tdcall_ret) + /* * TDX_HYPERCALL - Make hypercalls to a TDX VMM using TDVMCALL leaf of TDCALL * instruction
arch/x86/coco/tdx/tdx-shared.c +3 -3
@@ -5,7 +5,7 @@ static unsigned long try_accept_one(phys_addr_t start, unsigned long len, enum pg_level pg_level) {unsigned long accept_size =page_level_size (pg_level); -u64 tdcall_rcx; +struct tdx_module_args args = {};u8 page_size;if (!IS_ALIGNED (start, accept_size))
@@ -34,8 +34,8 @@ static unsigned long try_accept_one(phys_addr_t start, unsigned long len,return 0 ; } - tdcall_rcx = start | page_size; -if (__tdcall (TDG_MEM_PAGE_ACCEPT , tdcall_rcx,0 ,0 ,0 ,NULL )) + args.rcx = start | page_size; +if (__tdcall (TDG_MEM_PAGE_ACCEPT , &args))return 0 ;return accept_size;
arch/x86/coco/tdx/tdx.c +25 -19
109 lines not on this page · raw message
arch/x86/include/asm/shared/tdx.h +4 -4
@@ -74,11 +74,11 @@ static inline u64 _tdx_hypercall(u64 fn, u64 r12, u64 r13, u64 r14, u64 r15)void __tdx_hypercall_failed (void );/* -* Used in __tdx_module_call() to gather the output registers' values of the +* Used in __tdcall*() to gather the input/output registers' values of the * TDCALL instruction when requesting services from the TDX module. This is a * software only structure and not part of the TDX module/VMM ABI */ -struct tdx_module_output { +struct tdx_module_args {u64 rcx;u64 rdx;u64 r8;
@@ -88,8 +88,8 @@ struct tdx_module_output { };/* Used to communicate with the TDX module */ -u64 __tdcall (u64 fn,u64 rcx,u64 rdx,u64 r8,u64 r9, -struct tdx_module_output *out); +u64 __tdcall (u64 fn,struct tdx_module_args *args); +u64 __tdcall_ret (u64 fn,struct tdx_module_args *args);bool tdx_accept_memory (phys_addr_t start,phys_addr_t end);
arch/x86/kernel/asm-offsets.c +6 -6
@@ -68,12 +68,12 @@ static void __used common(void)#endif BLANK (); -OFFSET (TDX_MODULE_rcx, tdx_module_output, rcx); -OFFSET (TDX_MODULE_rdx, tdx_module_output, rdx); -OFFSET (TDX_MODULE_r8, tdx_module_output, r8); -OFFSET (TDX_MODULE_r9, tdx_module_output, r9); -OFFSET (TDX_MODULE_r10, tdx_module_output, r10); -OFFSET (TDX_MODULE_r11, tdx_module_output, r11); +OFFSET (TDX_MODULE_rcx, tdx_module_args, rcx); +OFFSET (TDX_MODULE_rdx, tdx_module_args, rdx); +OFFSET (TDX_MODULE_r8, tdx_module_args, r8); +OFFSET (TDX_MODULE_r9, tdx_module_args, r9); +OFFSET (TDX_MODULE_r10, tdx_module_args, r10); +OFFSET (TDX_MODULE_r11, tdx_module_args, r11);BLANK ();OFFSET (TDX_HYPERCALL_r8, tdx_hypercall_args, r8);
arch/x86/virt/vmx/tdx/tdxcall.S +39 -56
122 lines not on this page · raw message
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 310/676 x86/tdx: Introduce wrappers to read and write TD metadata
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kirill A. Shutemov <[email protected]>
[ Upstream commit 5081e8fadb809253c911b349b01d87c5b4e3fec5 ]
The TDG_VM_WR TDCALL is used to ask the TDX module to change some TD-specific VM configuration. There is currently only one user in the kernel of this TDCALL leaf. More will be added shortly.
Refactor to make way for more users of TDG_VM_WR who will need to modify other TD configuration values.
Add a wrapper for the TDG_VM_RD TDCALL that requests TD-specific metadata from the TDX module. There are currently no users for TDG_VM_RD. Mark it as __maybe_unused until the first user appears.
This is preparation for enumeration and enabling optional TD features.
Stable-dep-of: f65aa0ad79fc ("x86/tdx: Dynamically disable SEPT violations from causing #VEs")
--- arch/x86/coco/tdx/tdx.c | 32 ++++++++++++++++++++++++++----- arch/x86/include/asm/shared/tdx.h | 1 + 2 files changed, 28 insertions(+), 5 deletions(-)
arch/x86/coco/tdx/tdx.c +27 -5
@@ -74,6 +74,32 @@ static inline void tdcall(u64 fn, struct tdx_module_args *args)panic ("TDCALL %lld failed (Buggy TDX module!)\n" , fn); } +/* Read TD-scoped metadata */ +static inline u64 __maybe_unused tdg_vm_rd (u64 field,u64 *value) +{ +struct tdx_module_args args = { + .rdx = field, + }; +u64 ret; + + ret =__tdcall_ret (TDG_VM_RD , &args); + *value = args.r8; + +return ret; +} + +/* Write TD-scoped metadata */ +static inline u64 tdg_vm_wr (u64 field,u64 value,u64 mask) +{ +struct tdx_module_args args = { + .rdx = field, + .r8 = value, + .r9 = mask, + }; + +return __tdcall (TDG_VM_WR , &args); +} +/** * tdx_mcall_get_report0() - Wrapper to get TDREPORT0 (a.k.a. TDREPORT * subtype 0) using TDG.MR.REPORT TDCALL.
@@ -767,10 +793,6 @@ static bool tdx_enc_status_change_finish(unsigned long vaddr, int numpages,void __init tdx_early_init (void ) { -struct tdx_module_args args = { - .rdx =TDCS_NOTIFY_ENABLES , - .r9 =-1ULL , - };u64 cc_mask;u32 eax, sig[3 ];
@@ -786,7 +808,7 @@ void __init tdx_early_init(void)cc_set_mask (cc_mask);/* Kernel does not use NOTIFY_ENABLES and does not need random #VEs */ -tdcall (TDG_VM_WR , &args); +tdg_vm_wr (TDCS_NOTIFY_ENABLES ,0 ,-1ULL );/* * All bits above GPA width are reserved and kernel treats shared bit
arch/x86/include/asm/shared/tdx.h +1 -0
@@ -15,6 +15,7 @@#define TDG_VP_VEINFO_GET 3#define TDG_MR_REPORT 4#define TDG_MEM_PAGE_ACCEPT 6 +#define TDG_VM_RD 7#define TDG_VM_WR 8/* TDCS fields. To be used by TDG.VM.WR and TDG.VM.RD module calls */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 311/676 x86/tdx: Rename tdx_parse_tdinfo() to tdx_setup()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kirill A. Shutemov <[email protected]>
[ Upstream commit b064043d9565786b385f85e6436ca5716bbd5552 ]
Rename tdx_parse_tdinfo() to tdx_setup() and move setting NOTIFY_ENABLES there.
The function will be extended to adjust TD configuration.
Stable-dep-of: f65aa0ad79fc ("x86/tdx: Dynamically disable SEPT violations from causing #VEs")
--- arch/x86/coco/tdx/tdx.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
arch/x86/coco/tdx/tdx.c +8 -5
@@ -169,7 +169,7 @@ static void __noreturn tdx_panic(const char *msg)__tdx_hypercall (&args); } -static void tdx_parse_tdinfo (u64 *cc_mask) +static void tdx_setup (u64 *cc_mask) {struct tdx_module_args args = {};unsigned int gpa_width;
@@ -194,6 +194,9 @@ static void tdx_parse_tdinfo(u64 *cc_mask) gpa_width = args.rcx &GENMASK (5 ,0 ); *cc_mask =BIT_ULL (gpa_width -1 ); +/* Kernel does not use NOTIFY_ENABLES and does not need random #VEs */ +tdg_vm_wr (TDCS_NOTIFY_ENABLES ,0 ,-1ULL ); +/* * The kernel can not handle #VE's when accessing normal kernel * memory. Ensure that no #VE will be delivered for accesses to
@@ -804,11 +807,11 @@ void __init tdx_early_init(void)setup_force_cpu_cap (X86_FEATURE_TDX_GUEST ); cc_vendor =CC_VENDOR_INTEL ; -tdx_parse_tdinfo (&cc_mask); -cc_set_mask (cc_mask); -/* Kernel does not use NOTIFY_ENABLES and does not need random #VEs */ -tdg_vm_wr (TDCS_NOTIFY_ENABLES ,0 ,-1ULL ); +/* Configure the TD */ +tdx_setup (&cc_mask); + +cc_set_mask (cc_mask);/* * All bits above GPA width are reserved and kernel treats shared bit
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 312/676 x86/tdx: Dynamically disable SEPT violations from causing #VEs
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kirill A. Shutemov <[email protected]>
[ Upstream commit f65aa0ad79fca4ace921da0701644f020129043d ]
Memory access #VEs are hard for Linux to handle in contexts like the entry code or NMIs. But other OSes need them for functionality. There's a static (pre-guest-boot) way for a VMM to choose one or the other. But VMMs don't always know which OS they are booting, so they choose to deliver those #VEs so the "other" OSes will work. That, unfortunately has left us in the lurch and exposed to these hard-to-handle #VEs.
The TDX module has introduced a new feature. Even if the static configuration is set to "send nasty #VEs", the kernel can dynamically request that they be disabled. Once they are disabled, access to private memory that is not in the Mapped state in the Secure-EPT (SEPT) will result in an exit to the VMM rather than injecting a #VE.
Check if the feature is available and disable SEPT #VE if possible.
If the TD is allowed to disable/enable SEPT #VEs, the ATTR_SEPT_VE_DISABLE attribute is no longer reliable. It reflects the initial state of the control for the TD, but it will not be updated if someone (e.g. bootloader) changes it before the kernel starts. Kernel must check TDCS_TD_CTLS bit to determine if SEPT #VEs are enabled or disabled.
[ dhansen: remove 'return' at end of function ]
--- arch/x86/coco/tdx/tdx.c | 74 ++++++++++++++++++++++++------- arch/x86/include/asm/shared/tdx.h | 10 ++++- 2 files changed, 67 insertions(+), 17 deletions(-)
arch/x86/coco/tdx/tdx.c +58 -16
@@ -75,7 +75,7 @@ static inline void tdcall(u64 fn, struct tdx_module_args *args) }/* Read TD-scoped metadata */ -static inline u64 __maybe_unused tdg_vm_rd (u64 field,u64 *value) +static inline u64 tdg_vm_rd (u64 field,u64 *value) {struct tdx_module_args args = { .rdx = field,
@@ -169,6 +169,60 @@ static void __noreturn tdx_panic(const char *msg)__tdx_hypercall (&args); } +/* +* The kernel cannot handle #VEs when accessing normal kernel memory. Ensure +* that no #VE will be delivered for accesses to TD-private memory. +* +* TDX 1.0 does not allow the guest to disable SEPT #VE on its own. The VMM +* controls if the guest will receive such #VE with TD attribute +* ATTR_SEPT_VE_DISABLE. +* +* Newer TDX modules allow the guest to control if it wants to receive SEPT +* violation #VEs. +* +* Check if the feature is available and disable SEPT #VE if possible. +* +* If the TD is allowed to disable/enable SEPT #VEs, the ATTR_SEPT_VE_DISABLE +* attribute is no longer reliable. It reflects the initial state of the +* control for the TD, but it will not be updated if someone (e.g. bootloader) +* changes it before the kernel starts. Kernel must check TDCS_TD_CTLS bit to +* determine if SEPT #VEs are enabled or disabled. +*/ +static void disable_sept_ve (u64 td_attr) +{ +const char *msg ="TD misconfiguration: SEPT #VE has to be disabled" ; +bool debug = td_attr &ATTR_DEBUG ; +u64 config, controls; + +/* Is this TD allowed to disable SEPT #VE */ +tdg_vm_rd (TDCS_CONFIG_FLAGS , &config); +if (!(config &TDCS_CONFIG_FLEXIBLE_PENDING_VE )) { +/* No SEPT #VE controls for the guest: check the attribute */ +if (td_attr &ATTR_SEPT_VE_DISABLE ) +return ; + +/* Relax SEPT_VE_DISABLE check for debug TD for backtraces */ +if (debug) +pr_warn ("%s\n" , msg); +else +tdx_panic (msg); +return ; + } + +/* Check if SEPT #VE has been disabled before us */ +tdg_vm_rd (TDCS_TD_CTLS , &controls); +if (controls &TD_CTLS_PENDING_VE_DISABLE ) +return ; + +/* Keep #VEs enabled for splats in debugging environments */ +if (debug) +return ; + +/* Disable SEPT #VEs */ +tdg_vm_wr (TDCS_TD_CTLS ,TD_CTLS_PENDING_VE_DISABLE , +TD_CTLS_PENDING_VE_DISABLE ); +} +static void tdx_setup (u64 *cc_mask) {struct tdx_module_args args = {};
@@ -194,24 +248,12 @@ static void tdx_setup(u64 *cc_mask) gpa_width = args.rcx &GENMASK (5 ,0 ); *cc_mask =BIT_ULL (gpa_width -1 ); + td_attr = args.rdx; +/* Kernel does not use NOTIFY_ENABLES and does not need random #VEs */ tdg_vm_wr (TDCS_NOTIFY_ENABLES ,0 ,-1ULL ); -/* -* The kernel can not handle #VE's when accessing normal kernel -* memory. Ensure that no #VE will be delivered for accesses to -* TD-private memory. Only VMM-shared memory (MMIO) will #VE. -*/ - td_attr = args.rdx; -if (!(td_attr &ATTR_SEPT_VE_DISABLE )) { -const char *msg ="TD misconfiguration: SEPT_VE_DISABLE attribute must be set." ; - -/* Relax SEPT_VE_DISABLE check for debug TD. */ -if (td_attr &ATTR_DEBUG ) -pr_warn ("%s\n" , msg); -else -tdx_panic (msg); - } +disable_sept_ve (td_attr); }/*
arch/x86/include/asm/shared/tdx.h +9 -1
@@ -18,9 +18,17 @@#define TDG_VM_RD 7#define TDG_VM_WR 8 -/* TDCS fields. To be used by TDG.VM.WR and TDG.VM.RD module calls */ +/* TDX TD-Scope Metadata. To be used by TDG.VM.WR and TDG.VM.RD */ +#define TDCS_CONFIG_FLAGS 0x1110000300000016 +#define TDCS_TD_CTLS 0x1110000300000017#define TDCS_NOTIFY_ENABLES 0x9100000000000010 +/* TDCS_CONFIG_FLAGS bits */ +#define TDCS_CONFIG_FLEXIBLE_PENDING_VE BIT_ULL(1) + +/* TDCS_TD_CTLS bits */ +#define TD_CTLS_PENDING_VE_DISABLE BIT_ULL(0) +/* TDX hypercall Leaf IDs */ #define TDVMCALL_MAP_GPA 0x10001#define TDVMCALL_REPORT_FATAL_ERROR 0x10003
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 313/676 RDMA/hns: Fix out-of-order issue of requester when setting FENCE
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Junxian Huang <[email protected]>
[ Upstream commit 5dbcb1c1900f45182b5651c89257c272f1f3ead7 ]
The FENCE indicator in hns WQE doesn't ensure that response data from a previous Read/Atomic operation has been written to the requester's memory before the subsequent Send/Write operation is processed. This may result in the subsequent Send/Write operation accessing the original data in memory instead of the expected response data.
Unlike FENCE, the SO (Strong Order) indicator blocks the subsequent operation until the previous response data is written to memory and a bresp is returned. Set the SO indicator instead of FENCE to maintain strict order.
--- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 2 +- drivers/infiniband/hw/hns/hns_roce_hw_v2.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-)
drivers/infiniband/hw/hns/hns_roce_hw_v2.c +1 -1
@@ -578,7 +578,7 @@ static inline int set_rc_wqe(struct hns_roce_qp *qp,if (WARN_ON (ret))return ret; -hr_reg_write (rc_sq_wqe,RC_SEND_WQE_FENCE , +hr_reg_write (rc_sq_wqe,RC_SEND_WQE_SO , (wr->send_flags &IB_SEND_FENCE ) ?1 :0 ); hr_reg_write(rc_sq_wqe, RC_SEND_WQE_SE,
drivers/infiniband/hw/hns/hns_roce_hw_v2.h +1 -0
@@ -899,6 +899,7 @@ struct hns_roce_v2_rc_send_wqe {#define RC_SEND_WQE_OWNER RC_SEND_WQE_FIELD_LOC(7, 7)#define RC_SEND_WQE_CQE RC_SEND_WQE_FIELD_LOC(8, 8)#define RC_SEND_WQE_FENCE RC_SEND_WQE_FIELD_LOC(9, 9) +#define RC_SEND_WQE_SO RC_SEND_WQE_FIELD_LOC(10, 10)#define RC_SEND_WQE_SE RC_SEND_WQE_FIELD_LOC(11, 11)#define RC_SEND_WQE_INLINE RC_SEND_WQE_FIELD_LOC(12, 12)#define RC_SEND_WQE_WQE_INDEX RC_SEND_WQE_FIELD_LOC(30, 15)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 314/676 RDMA/hns: Fix NULL pointer derefernce in hns_roce_map_mr_sg()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Junxian Huang <[email protected]>
[ Upstream commit 6b526d17eed850352d880b93b9bf20b93006bd92 ]
ib_map_mr_sg() allows ULPs to specify NULL as the sg_offset argument. The driver needs to check whether it is a NULL pointer before dereferencing it.
--- drivers/infiniband/hw/hns/hns_roce_mr.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/infiniband/hw/hns/hns_roce_mr.c +4 -3
@@ -415,15 +415,16 @@ static int hns_roce_set_page(struct ib_mr *ibmr, u64 addr) }int hns_roce_map_mr_sg (struct ib_mr *ibmr,struct scatterlist *sg,int sg_nents, -unsigned int *sg_offset) +unsigned int *sg_offset_p) { +unsigned int sg_offset = sg_offset_p ? *sg_offset_p :0 ;struct hns_roce_dev *hr_dev =to_hr_dev (ibmr->device);struct ib_device *ibdev = &hr_dev->ib_dev;struct hns_roce_mr *mr =to_hr_mr (ibmr);struct hns_roce_mtr *mtr = &mr->pbl_mtr;int ret, sg_num =0 ; -if (!IS_ALIGNED (*sg_offset,HNS_ROCE_FRMR_ALIGN_SIZE ) || +if (!IS_ALIGNED (sg_offset,HNS_ROCE_FRMR_ALIGN_SIZE ) || ibmr->page_size <HNS_HW_PAGE_SIZE || ibmr->page_size >HNS_HW_MAX_PAGE_SIZE )return sg_num;
@@ -434,7 +435,7 @@ int hns_roce_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg, int sg_nents,if (!mr->page_list)return sg_num; - sg_num =ib_sg_to_pages (ibmr, sg, sg_nents, sg_offset, hns_roce_set_page); + sg_num =ib_sg_to_pages (ibmr, sg, sg_nents, sg_offset_p, hns_roce_set_page);if (sg_num <1 ) {ibdev_err (ibdev,"failed to store sg pages %u %u, cnt = %d.\n" , mr->npages, mr->pbl_mtr.hem_cfg.buf_pg_count, sg_num);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 315/676 cpufreq: CPPC: Fix wrong return value in cppc_get_cpu_cost()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinjie Ruan <[email protected]>
[ Upstream commit be392aa80f1e5b0b65ccc2a540b9304fefcfe3d8 ]
cppc_get_cpu_cost() return 0 if the policy is NULL. Then in em_compute_costs(), the later zero check for cost is not valid as cost is uninitialized. As Quentin pointed out, kernel energy model core check the return value of get_cost() first, so if the callback failed it should tell the core. Return -EINVAL to fix it.
--- drivers/cpufreq/cppc_cpufreq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/cpufreq/cppc_cpufreq.c +1 -1
@@ -499,7 +499,7 @@ static int cppc_get_cpu_cost(struct device *cpu_dev, unsigned long KHz, policy =cpufreq_cpu_get_raw (cpu_dev->id);if (!policy) -return 0 ; +return -EINVAL ; cpu_data = policy->driver_data; perf_caps = &cpu_data->perf_caps;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 316/676 cpufreq: CPPC: Fix wrong return value in cppc_get_cpu_power()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinjie Ruan <[email protected]>
[ Upstream commit b51eb0874d8170028434fbd259e80b78ed9b8eca ]
cppc_get_cpu_power() return 0 if the policy is NULL. Then in em_create_perf_table(), the later zero check for power is not valid as power is uninitialized. As Quentin pointed out, kernel energy model core check the return value of active_power() first, so if the callback failed it should tell the core. So return -EINVAL to fix it.
--- drivers/cpufreq/cppc_cpufreq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/cpufreq/cppc_cpufreq.c +1 -1
@@ -429,7 +429,7 @@ static int cppc_get_cpu_power(struct device *cpu_dev, policy =cpufreq_cpu_get_raw (cpu_dev->id);if (!policy) -return 0 ; +return -EINVAL ; cpu_data = policy->driver_data; perf_caps = &cpu_data->perf_caps;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 317/676 ocfs2: fix uninitialized value in ocfs2_file_read_iter()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Antipov <[email protected]>
[ Upstream commit adc77b19f62d7e80f98400b2fca9d700d2afdd6f ]
Syzbot has reported the following KMSAN splat:
BUG: KMSAN: uninit-value in ocfs2_file_read_iter+0x9a4/0xf80 ocfs2_file_read_iter+0x9a4/0xf80 __io_read+0x8d4/0x20f0 io_read+0x3e/0xf0 io_issue_sqe+0x42b/0x22c0 io_wq_submit_work+0xaf9/0xdc0 io_worker_handle_work+0xd13/0x2110 io_wq_worker+0x447/0x1410 ret_from_fork+0x6f/0x90 ret_from_fork_asm+0x1a/0x30
Uninit was created at:
__alloc_pages_noprof+0x9a7/0xe00 alloc_pages_mpol_noprof+0x299/0x990 alloc_pages_noprof+0x1bf/0x1e0 allocate_slab+0x33a/0x1250 ___slab_alloc+0x12ef/0x35e0 kmem_cache_alloc_bulk_noprof+0x486/0x1330 __io_alloc_req_refill+0x84/0x560 io_submit_sqes+0x172f/0x2f30 __se_sys_io_uring_enter+0x406/0x41c0 __x64_sys_io_uring_enter+0x11f/0x1a0 x64_sys_call+0x2b54/0x3ba0 do_syscall_64+0xcd/0x1e0 entry_SYSCALL_64_after_hwframe+0x77/0x7f
Since an instance of 'struct kiocb' may be passed from the block layer with 'private' field uninitialized, introduce 'ocfs2_iocb_init_rw_locked()' and use it from where 'ocfs2_dio_end_io()' might take care, i.e. in 'ocfs2_file_read_iter()' and 'ocfs2_file_write_iter()'.
--- fs/ocfs2/aops.h | 2 ++ fs/ocfs2/file.c | 4 ++++ 2 files changed, 6 insertions(+)
fs/ocfs2/aops.h +2 -0
@@ -70,6 +70,8 @@ enum ocfs2_iocb_lock_bits { OCFS2_IOCB_NUM_LOCKS }; +#define ocfs2_iocb_init_rw_locked (iocb) \ + (iocb->private = NULL)#define ocfs2_iocb_clear_rw_locked (iocb) \ clear_bit(OCFS2_IOCB_RW_LOCK, (unsigned long *)&iocb->private)#define ocfs2_iocb_rw_locked_level (iocb) \
fs/ocfs2/file.c +4 -0
@@ -2397,6 +2397,8 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb, }else inode_lock (inode); +ocfs2_iocb_init_rw_locked (iocb); +/* * Concurrent O_DIRECT writes are allowed with * mount_option "coherency=buffered".
@@ -2543,6 +2545,8 @@ static ssize_t ocfs2_file_read_iter(struct kiocb *iocb,if (!direct_io && nowait)return -EOPNOTSUPP ; +ocfs2_iocb_init_rw_locked (iocb); +/* * buffered reads protect themselves in ->read_folio(). O_DIRECT reads * need locks to protect pending reads from racing with truncate.
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 318/676 dax: delete a stale directory pmem
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Harshit Mogalapalli <[email protected]>
[ Upstream commit b8e6d7ce50673c39514921ac61f7af00bbb58b87 ]
After commit: 83762cb5c7c4 ("dax: Kill DEV_DAX_PMEM_COMPAT") the pmem/ directory is not needed anymore and Makefile changes were made accordingly in this commit, but there is a Makefile and pmem.c in pmem/ which are now stale and pmem.c is empty, remove them.
--- drivers/dax/pmem/Makefile | 7 ------- drivers/dax/pmem/pmem.c | 10 ---------- 2 files changed, 17 deletions(-) delete mode 100644 drivers/dax/pmem/Makefile delete mode 100644 drivers/dax/pmem/pmem.c
drivers/dax/pmem/Makefile deleted +0 -7
@@ -1,7 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -obj-$(CONFIG_DEV_DAX_PMEM) += dax_pmem.o -obj-$(CONFIG_DEV_DAX_PMEM) += dax_pmem_core.o - -dax_pmem-y := pmem.o -dax_pmem_core-y := core.o -dax_pmem_compat-y := compat.o
drivers/dax/pmem/pmem.c deleted +0 -10
@@ -1,10 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* Copyright(c) 2016 - 2018 Intel Corporation. All rights reserved. */ -#include <linux/percpu-refcount.h> -#include <linux/memremap.h> -#include <linux/module.h> -#include <linux/pfn_t.h> -#include <linux/nd.h> -#include "../bus.h" - -
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 319/676 KVM: PPC: Book3S HV: Stop using vc->dpdes for nested KVM guests
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gautam Menghani <[email protected]>
[ Upstream commit 0d3c6b28896f9889c8864dab469e0343a0ad1c0c ]
commit 6398326b9ba1 ("KVM: PPC: Book3S HV P9: Stop using vc->dpdes") introduced an optimization to use only vcpu->doorbell_request for SMT emulation for Power9 and above guests, but the code for nested guests still relies on the old way of handling doorbells, due to which an L2 guest (see [1]) cannot be booted with XICS with SMT>1. The command to repro this issue is:
// To be run in L1
qemu-system-ppc64 \ -drive file=rhel.qcow2,format=qcow2 \ -m 20G \ -smp 8,cores=1,threads=8 \ -cpu host \ -nographic \ -machine pseries,ic-mode=xics -accel kvm
Fix the plumbing to utilize vcpu->doorbell_request instead of vcore->dpdes for nested KVM guests on P9 and above.
[1] Terminology
1. L0 : PowerNV linux running with HV privileges
2. L1 : Pseries KVM guest running on top of L0
2. L2 : Nested KVM guest running on top of L1
--- arch/powerpc/kvm/book3s_hv.c | 9 +++++++++ arch/powerpc/kvm/book3s_hv_nested.c | 14 ++++++++++---- 2 files changed, 19 insertions(+), 4 deletions(-)
arch/powerpc/kvm/book3s_hv.c +9 -0
@@ -4090,6 +4090,15 @@ static int kvmhv_vcpu_entry_p9_nested(struct kvm_vcpu *vcpu, u64 time_limit, uns } hvregs.hdec_expiry = time_limit; +/* +* hvregs has the doorbell status, so zero it here which +* enables us to receive doorbells when H_ENTER_NESTED is +* in progress for this vCPU +*/ + +if (vcpu->arch.doorbell_request) + vcpu->arch.doorbell_request =0 ; +/* * When setting DEC, we must always deal with irq_work_raise * via NMI vs setting DEC. The problem occurs right as we
arch/powerpc/kvm/book3s_hv_nested.c +10 -4
@@ -32,7 +32,7 @@ void kvmhv_save_hv_regs(struct kvm_vcpu *vcpu, struct hv_guest_state *hr)struct kvmppc_vcore *vc = vcpu->arch.vcore; hr->pcr = vc->pcr |PCR_MASK ; - hr->dpdes = vc->dpdes; + hr->dpdes = vcpu->arch.doorbell_request; hr->hfscr = vcpu->arch.hfscr; hr->tb_offset = vc->tb_offset; hr->dawr0 = vcpu->arch.dawr0;
@@ -105,7 +105,7 @@ static void save_hv_return_state(struct kvm_vcpu *vcpu, {struct kvmppc_vcore *vc = vcpu->arch.vcore; - hr->dpdes = vc->dpdes; + hr->dpdes = vcpu->arch.doorbell_request; hr->purr = vcpu->arch.purr; hr->spurr = vcpu->arch.spurr; hr->ic = vcpu->arch.ic;
@@ -143,7 +143,7 @@ static void restore_hv_regs(struct kvm_vcpu *vcpu, const struct hv_guest_state *struct kvmppc_vcore *vc = vcpu->arch.vcore; vc->pcr = hr->pcr |PCR_MASK ; - vc->dpdes = hr->dpdes; + vcpu->arch.doorbell_request = hr->dpdes; vcpu->arch.hfscr = hr->hfscr; vcpu->arch.dawr0 = hr->dawr0; vcpu->arch.dawrx0 = hr->dawrx0;
@@ -170,7 +170,13 @@ void kvmhv_restore_hv_return_state(struct kvm_vcpu *vcpu, {struct kvmppc_vcore *vc = vcpu->arch.vcore; - vc->dpdes = hr->dpdes; +/* +* This L2 vCPU might have received a doorbell while H_ENTER_NESTED was being handled. +* Make sure we preserve the doorbell if it was either: +* a) Sent after H_ENTER_NESTED was called on this vCPU (arch.doorbell_request would be 1) +* b) Doorbell was not handled and L2 exited for some other reason (hr->dpdes would be 1) +*/ + vcpu->arch.doorbell_request = vcpu->arch.doorbell_request | hr->dpdes; vcpu->arch.hfscr = hr->hfscr; vcpu->arch.purr = hr->purr; vcpu->arch.spurr = hr->spurr;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 320/676 KVM: PPC: Book3S HV: Avoid returning to nested hypervisor on pending doorbells
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gautam Menghani <[email protected]>
[ Upstream commit 26686db69917399fa30e3b3135360771e90f83ec ]
Commit 6398326b9ba1 ("KVM: PPC: Book3S HV P9: Stop using vc->dpdes") dropped the use of vcore->dpdes for msgsndp / SMT emulation. Prior to that commit, the below code at L1 level (see [1] for terminology) was responsible for setting vc->dpdes for the respective L2 vCPU:
if (!nested) {
kvmppc_core_prepare_to_enter(vcpu);
if (vcpu->arch.doorbell_request) {
vc->dpdes = 1;
smp_wmb();
vcpu->arch.doorbell_request = 0;
}L1 then sent vc->dpdes to L0 via kvmhv_save_hv_regs(), and while servicing H_ENTER_NESTED at L0, the below condition at L0 level made sure to abort and go back to L1 if vcpu->arch.doorbell_request = 1 so that L1 sets vc->dpdes as per above if condition:
} else if (vcpu->arch.pending_exceptions ||
vcpu->arch.doorbell_request ||
xive_interrupt_pending(vcpu)) {
vcpu->arch.ret = RESUME_HOST;
goto out;
}This worked fine since vcpu->arch.doorbell_request was used more like a flag and vc->dpdes was used to pass around the doorbell state. But after Commit 6398326b9ba1 ("KVM: PPC: Book3S HV P9: Stop using vc->dpdes"), vcpu->arch.doorbell_request is the only variable used to pass around doorbell state.
With the plumbing for handling doorbells for nested guests updated to use vcpu->arch.doorbell_request over vc->dpdes, the above "else if" stops doorbells from working correctly as L0 aborts execution of L2 and instead goes back to L1.
Remove vcpu->arch.doorbell_request from the above "else if" condition as it is no longer needed for L0 to correctly handle the doorbell status while running L2.
[1] Terminology
1. L0 : PowerNV linux running with HV privileges
2. L1 : Pseries KVM guest running on top of L0
2. L2 : Nested KVM guest running on top of L1
--- arch/powerpc/kvm/book3s_hv.c | 1 - 1 file changed, 1 deletion(-)
arch/powerpc/kvm/book3s_hv.c +0 -1
@@ -4687,7 +4687,6 @@ int kvmhv_run_single_vcpu(struct kvm_vcpu *vcpu, u64 time_limit, lpcr |=LPCR_MER ; } }else if (vcpu->arch.pending_exceptions || - vcpu->arch.doorbell_request ||xive_interrupt_pending (vcpu)) { vcpu->arch.ret =RESUME_HOST ; goto out;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 321/676 powerpc/sstep: make emulate_vsx_load and emulate_vsx_store static
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michal Suchanek <[email protected]>
[ Upstream commit a26c4dbb3d9c1821cb0fc11cb2dbc32d5bf3463b ]
These functions are not used outside of sstep.c
--- arch/powerpc/include/asm/sstep.h | 5 ----- arch/powerpc/lib/sstep.c | 12 ++++-------- 2 files changed, 4 insertions(+), 13 deletions(-)
arch/powerpc/include/asm/sstep.h +0 -5
@@ -173,9 +173,4 @@ int emulate_step(struct pt_regs *regs, ppc_inst_t instr);*/ extern int emulate_loadstore (struct pt_regs *regs,struct instruction_op *op); -extern void emulate_vsx_load (struct instruction_op *op,union vsx_reg *reg, -const void *mem,bool cross_endian); -extern void emulate_vsx_store (struct instruction_op *op, -const union vsx_reg *reg,void *mem, -bool cross_endian);extern int emulate_dcbz (unsigned long ea,struct pt_regs *regs);
arch/powerpc/lib/sstep.c +4 -8
@@ -780,8 +780,8 @@ static nokprobe_inline int emulate_stq(struct pt_regs *regs, unsigned long ea,#endif /* __powerpc64 */ #ifdef CONFIG_VSX -void emulate_vsx_load (struct instruction_op *op,union vsx_reg *reg, -const void *mem,bool rev) +static nokprobe_inline void emulate_vsx_load(struct instruction_op *op, union vsx_reg *reg, +const void *mem,bool rev) {int size, read_size;int i, j;
@@ -863,11 +863,9 @@ void emulate_vsx_load(struct instruction_op *op, union vsx_reg *reg,break ; } } -EXPORT_SYMBOL_GPL (emulate_vsx_load); -NOKPROBE_SYMBOL (emulate_vsx_load); -void emulate_vsx_store (struct instruction_op *op,const union vsx_reg *reg, -void *mem,bool rev) +static nokprobe_inline void emulate_vsx_store(struct instruction_op *op, const union vsx_reg *reg, +void *mem,bool rev) {int size, write_size;int i, j;
@@ -955,8 +953,6 @@ void emulate_vsx_store(struct instruction_op *op, const union vsx_reg *reg,break ; } } -EXPORT_SYMBOL_GPL (emulate_vsx_store); -NOKPROBE_SYMBOL (emulate_vsx_store); static nokprobe_inline int do_vsx_load(struct instruction_op *op, unsigned long ea, struct pt_regs *regs,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 322/676 powerpc/kexec: Fix return of uninitialized variable
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhang Zekun <[email protected]>
[ Upstream commit 83b5a407fbb73e6965adfb4bd0a803724bf87f96 ]
of_property_read_u64() can fail and leave the variable uninitialized, which will then be used. Return error if reading the property failed.
--- arch/powerpc/kexec/file_load_64.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
arch/powerpc/kexec/file_load_64.c +7 -2
@@ -916,13 +916,18 @@ int setup_purgatory_ppc64(struct kimage *image, const void *slave_code,if (dn) {u64 val; -of_property_read_u64 (dn,"opal-base-address" , &val); + ret =of_property_read_u64 (dn,"opal-base-address" , &val); +if (ret) + goto out; + ret =kexec_purgatory_get_set_symbol (image,"opal_base" , &val,sizeof (val), false);if (ret) goto out; -of_property_read_u64 (dn,"opal-entry-address" , &val); + ret =of_property_read_u64 (dn,"opal-entry-address" , &val); +if (ret) + goto out; ret =kexec_purgatory_get_set_symbol (image,"opal_entry" , &val,sizeof (val), false); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 323/676 fbdev: sh7760fb: Fix a possible memory leak in sh7760fb_alloc_mem()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhen Lei <[email protected]>
[ Upstream commit f89d17ae2ac42931be2a0153fecbf8533280c927 ]
When information such as info->screen_base is not ready, calling sh7760fb_free_mem() does not release memory correctly. Call dma_free_coherent() instead.
--- drivers/video/fbdev/sh7760fb.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/video/fbdev/sh7760fb.c +1 -2
@@ -409,12 +409,11 @@ static int sh7760fb_alloc_mem(struct fb_info *info) vram =PAGE_SIZE ; fbmem =dma_alloc_coherent (info->device, vram, &par->fbdma,GFP_KERNEL ); -if (!fbmem)return -ENOMEM ;if ((par->fbdma &SH7760FB_DMA_MASK ) !=SH7760FB_DMA_MASK ) { -sh7760fb_free_mem (info); +dma_free_coherent (info->device, vram, fbmem, par->fbdma);dev_err (info->device,"kernel gave me memory at 0x%08lx, which is" "unusable for the LCDC\n" , (unsigned long )par->fbdma);return -ENOMEM ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 324/676 IB/mlx5: Allocate resources just before first QP/SRQ is created
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jianbo Liu <[email protected]>
[ Upstream commit 5895e70f2e6e8dc67b551ca554d6fcde0a7f0467 ]
Previously, all IB dev resources are initialized on driver load. As they are not always used, move the initialization to the time when they are needed.
To be more specific, move PD (p0) and CQ (c0) initialization to the time when the first SRQ is created. and move SRQs(s0 and s1) initialization to the time first QP is created. To avoid concurrent creations, two new mutexes are also added.
Stable-dep-of: ede132a5cf55 ("RDMA/mlx5: Move events notifier registration to be after device registration")
--- drivers/infiniband/hw/mlx5/main.c | 149 +++++++++++++++++++-------- drivers/infiniband/hw/mlx5/mlx5_ib.h | 4 + drivers/infiniband/hw/mlx5/qp.c | 4 + drivers/infiniband/hw/mlx5/srq.c | 4 + 4 files changed, 118 insertions(+), 43 deletions(-)
drivers/infiniband/hw/mlx5/main.c +106 -43
@@ -2796,37 +2796,72 @@ static u8 mlx5_get_umr_fence(u8 umr_fence_cap) } } -static int mlx5_ib_dev_res_init (struct mlx5_ib_dev *dev) +int mlx5_ib_dev_res_cq_init (struct mlx5_ib_dev *dev) {struct mlx5_ib_resources *devr = &dev->devr; -struct ib_srq_init_attr attr; -struct ib_device *ibdev;struct ib_cq_init_attr cq_attr = {.cqe =1 }; -int port; +struct ib_device *ibdev; +struct ib_pd *pd; +struct ib_cq *cq;int ret =0 ; - ibdev = &dev->ib_dev; -if (!MLX5_CAP_GEN (dev->mdev, xrc)) -return -EOPNOTSUPP ; +/* +* devr->c0 is set once, never changed until device unload. +* Avoid taking the mutex if initialization is already done. +*/ +if (devr->c0) +return 0 ; - devr->p0 =ib_alloc_pd (ibdev,0 ); -if (IS_ERR (devr->p0)) -return PTR_ERR (devr->p0); +mutex_lock (&devr->cq_lock); +if (devr->c0) + goto unlock; - devr->c0 =ib_create_cq (ibdev,NULL ,NULL ,NULL , &cq_attr); -if (IS_ERR (devr->c0)) { - ret =PTR_ERR (devr->c0); - goto error1; + ibdev = &dev->ib_dev; + pd =ib_alloc_pd (ibdev,0 ); +if (IS_ERR (pd)) { + ret =PTR_ERR (pd); +mlx5_ib_err (dev,"Couldn't allocate PD for res init, err=%d\n" , ret); + goto unlock; } - ret =mlx5_cmd_xrcd_alloc (dev->mdev, &devr->xrcdn0,0 ); -if (ret) - goto error2; + cq =ib_create_cq (ibdev,NULL ,NULL ,NULL , &cq_attr); +if (IS_ERR (cq)) { + ret =PTR_ERR (cq); +mlx5_ib_err (dev,"Couldn't create CQ for res init, err=%d\n" , ret); +ib_dealloc_pd (pd); + goto unlock; + } - ret =mlx5_cmd_xrcd_alloc (dev->mdev, &devr->xrcdn1,0 ); + devr->p0 = pd; + devr->c0 = cq; + +unlock: +mutex_unlock (&devr->cq_lock); +return ret; +} + +int mlx5_ib_dev_res_srq_init (struct mlx5_ib_dev *dev) +{ +struct mlx5_ib_resources *devr = &dev->devr; +struct ib_srq_init_attr attr; +struct ib_srq *s0, *s1; +int ret =0 ; + +/* +* devr->s1 is set once, never changed until device unload. +* Avoid taking the mutex if initialization is already done. +*/ +if (devr->s1) +return 0 ; + +mutex_lock (&devr->srq_lock); +if (devr->s1) + goto unlock; + + ret =mlx5_ib_dev_res_cq_init (dev);if (ret) - goto error3; + goto unlock;memset (&attr,0 ,sizeof (attr)); attr.attr.max_sge =1 ;
@@ -2834,10 +2869,11 @@ static int mlx5_ib_dev_res_init(struct mlx5_ib_dev *dev) attr.srq_type =IB_SRQT_XRC ; attr.ext.cq = devr->c0; - devr->s0 =ib_create_srq (devr->p0, &attr); -if (IS_ERR (devr->s0)) { - ret =PTR_ERR (devr->s0); - goto err_create; + s0 =ib_create_srq (devr->p0, &attr); +if (IS_ERR (s0)) { + ret =PTR_ERR (s0); +mlx5_ib_err (dev,"Couldn't create SRQ 0 for res init, err=%d\n" , ret); + goto unlock; }memset (&attr,0 ,sizeof (attr));
@@ -2845,29 +2881,48 @@ static int mlx5_ib_dev_res_init(struct mlx5_ib_dev *dev) attr.attr.max_wr =1 ; attr.srq_type =IB_SRQT_BASIC ; - devr->s1 =ib_create_srq (devr->p0, &attr); -if (IS_ERR (devr->s1)) { - ret =PTR_ERR (devr->s1); - goto error6; + s1 =ib_create_srq (devr->p0, &attr); +if (IS_ERR (s1)) { + ret =PTR_ERR (s1); +mlx5_ib_err (dev,"Couldn't create SRQ 1 for res init, err=%d\n" , ret); +ib_destroy_srq (s0); + } + + devr->s0 = s0; + devr->s1 = s1; + +unlock: +mutex_unlock (&devr->srq_lock); +return ret; +} + +static int mlx5_ib_dev_res_init (struct mlx5_ib_dev *dev) +{ +struct mlx5_ib_resources *devr = &dev->devr; +int port; +int ret; + +if (!MLX5_CAP_GEN (dev->mdev, xrc)) +return -EOPNOTSUPP ; + + ret =mlx5_cmd_xrcd_alloc (dev->mdev, &devr->xrcdn0,0 ); +if (ret) +return ret; + + ret =mlx5_cmd_xrcd_alloc (dev->mdev, &devr->xrcdn1,0 ); +if (ret) { +mlx5_cmd_xrcd_dealloc (dev->mdev, devr->xrcdn0,0 ); +return ret; }for (port =0 ; port <ARRAY_SIZE (devr->ports); ++port)INIT_WORK (&devr->ports[port].pkey_change_work, pkey_change_handler); -return 0 ; +mutex_init (&devr->cq_lock); +mutex_init (&devr->srq_lock); -error6: -ib_destroy_srq (devr->s0); -err_create: -mlx5_cmd_xrcd_dealloc (dev->mdev, devr->xrcdn1,0 ); -error3: -mlx5_cmd_xrcd_dealloc (dev->mdev, devr->xrcdn0,0 ); -error2: -ib_destroy_cq (devr->c0); -error1: -ib_dealloc_pd (devr->p0); -return ret; +return 0 ; }static void mlx5_ib_dev_res_cleanup (struct mlx5_ib_dev *dev)
@@ -2884,12 +2939,20 @@ static void mlx5_ib_dev_res_cleanup(struct mlx5_ib_dev *dev)for (port =0 ; port <ARRAY_SIZE (devr->ports); ++port)cancel_work_sync (&devr->ports[port].pkey_change_work); -ib_destroy_srq (devr->s1); -ib_destroy_srq (devr->s0); +/* After s0/s1 init, they are not unset during the device lifetime. */ +if (devr->s1) { +ib_destroy_srq (devr->s1); +ib_destroy_srq (devr->s0); + }mlx5_cmd_xrcd_dealloc (dev->mdev, devr->xrcdn1,0 );mlx5_cmd_xrcd_dealloc (dev->mdev, devr->xrcdn0,0 ); -ib_destroy_cq (devr->c0); -ib_dealloc_pd (devr->p0); +/* After p0/c0 init, they are not unset during the device lifetime. */ +if (devr->c0) { +ib_destroy_cq (devr->c0); +ib_dealloc_pd (devr->p0); + } +mutex_destroy (&devr->cq_lock); +mutex_destroy (&devr->srq_lock); } static u32 get_core_cap_flags(struct ib_device *ibdev,
drivers/infiniband/hw/mlx5/mlx5_ib.h +4 -0
@@ -820,11 +820,13 @@ struct mlx5_ib_port_resources {struct mlx5_ib_resources {struct ib_cq *c0; +struct mutex cq_lock;u32 xrcdn0;u32 xrcdn1;struct ib_pd *p0;struct ib_srq *s0;struct ib_srq *s1; +struct mutex srq_lock;struct mlx5_ib_port_resources ports[2 ]; };
@@ -1270,6 +1272,8 @@ to_mmmap(struct rdma_user_mmap_entry *rdma_entry) struct mlx5_user_mmap_entry, rdma_entry); } +int mlx5_ib_dev_res_cq_init (struct mlx5_ib_dev *dev); +int mlx5_ib_dev_res_srq_init (struct mlx5_ib_dev *dev);int mlx5_ib_db_map_user (struct mlx5_ib_ucontext *context,unsigned long virt,struct mlx5_db *db);void mlx5_ib_db_unmap_user (struct mlx5_ib_ucontext *context,struct mlx5_db *db);
drivers/infiniband/hw/mlx5/qp.c +4 -0
@@ -3247,6 +3247,10 @@ int mlx5_ib_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attr,enum ib_qp_type type;int err; + err =mlx5_ib_dev_res_srq_init (dev); +if (err) +return err; + err =check_qp_type (dev, attr, &type);if (err)return err;
drivers/infiniband/hw/mlx5/srq.c +4 -0
@@ -216,6 +216,10 @@ int mlx5_ib_create_srq(struct ib_srq *ib_srq,return -EINVAL ; } + err =mlx5_ib_dev_res_cq_init (dev); +if (err) +return err; +mutex_init (&srq->mutex);spin_lock_init (&srq->lock); srq->msrq.max =roundup_pow_of_two (init_attr->attr.max_wr +1 );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 325/676 RDMA/mlx5: Move events notifier registration to be after device registration
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Patrisious Haddad <[email protected]>
[ Upstream commit ede132a5cf559f3ab35a4c28bac4f4a6c20334d8 ]
Move pkey change work initialization and cleanup from device resources stage to notifier stage, since this is the stage which handles this work events.
Fix a race between the device deregistration and pkey change work by moving MLX5_IB_STAGE_DEVICE_NOTIFIER to be after MLX5_IB_STAGE_IB_REG in order to ensure that the notifier is deregistered before the device during cleanup. Which ensures there are no works that are being executed after the device has already unregistered which can cause the panic below.
BUG: kernel NULL pointer dereference, address: 0000000000000000 PGD 0 P4D 0 Oops: 0000 [#1] PREEMPT SMP PTI CPU: 1 PID: 630071 Comm: kworker/1:2 Kdump: loaded Tainted: G W OE --------- --- 5.14.0-162.6.1.el9_1.x86_64 #1 Hardware name: Microsoft Corporation Virtual Machine/Virtual Machine, BIOS 090008 02/27/2023 Workqueue: events pkey_change_handler [mlx5_ib] RIP: 0010:setup_qp+0x38/0x1f0 [mlx5_ib] Code: ee 41 54 45 31 e4 55 89 f5 53 48 89 fb 48 83 ec 20 8b 77 08 65 48 8b 04 25 28 00 00 00 48 89 44 24 18 48 8b 07 48 8d 4c 24 16 <4c> 8b 38 49 8b 87 80 0b 00 00 4c 89 ff 48 8b 80 08 05 00 00 8b 40 RSP: 0018:ffffbcc54068be20 EFLAGS: 00010282 RAX: 0000000000000000 RBX: ffff954054494128 RCX: ffffbcc54068be36 RDX: ffff954004934000 RSI: 0000000000000001 RDI: ffff954054494128 RBP: 0000000000000023 R08: ffff954001be2c20 R09: 0000000000000001 R10: ffff954001be2c20 R11: ffff9540260133c0 R12: 0000000000000000 R13: 0000000000000023 R14: 0000000000000000 R15: ffff9540ffcb0905 FS: 0000000000000000(0000) GS:ffff9540ffc80000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000000 CR3: 000000010625c001 CR4: 00000000003706e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: mlx5_ib_gsi_pkey_change+0x20/0x40 [mlx5_ib] process_one_work+0x1e8/0x3c0 worker_thread+0x50/0x3b0 ? rescuer_thread+0x380/0x380 kthread+0x149/0x170 ? set_kthread_struct+0x50/0x50 ret_from_fork+0x22/0x30 Modules linked in: rdma_ucm(OE) rdma_cm(OE) iw_cm(OE) ib_ipoib(OE) ib_cm(OE) ib_umad(OE) mlx5_ib(OE) mlx5_fwctl(OE) fwctl(OE) ib_uverbs(OE) mlx5_core(OE) mlxdevm(OE) ib_core(OE) mlx_compat(OE) psample mlxfw(OE) tls knem(OE) netconsole nfsv3 nfs_acl nfs lockd grace fscache netfs qrtr rfkill sunrpc intel_rapl_msr intel_rapl_common rapl hv_balloon hv_utils i2c_piix4 pcspkr joydev fuse ext4 mbcache jbd2 sr_mod sd_mod cdrom t10_pi sg ata_generic pci_hyperv pci_hyperv_intf hyperv_drm drm_shmem_helper drm_kms_helper hv_storvsc syscopyarea hv_netvsc sysfillrect sysimgblt hid_hyperv fb_sys_fops scsi_transport_fc hyperv_keyboard drm ata_piix crct10dif_pclmul crc32_pclmul crc32c_intel libata ghash_clmulni_intel hv_vmbus serio_raw [last unloaded: ib_core] CR2: 0000000000000000 ---[ end trace f6f8be4eae12f7bc ]---
--- drivers/infiniband/hw/mlx5/main.c | 40 +++++++++++++--------------- drivers/infiniband/hw/mlx5/mlx5_ib.h | 2 +- 2 files changed, 20 insertions(+), 22 deletions(-)
drivers/infiniband/hw/mlx5/main.c +19 -21
@@ -2899,7 +2899,6 @@ int mlx5_ib_dev_res_srq_init(struct mlx5_ib_dev *dev)static int mlx5_ib_dev_res_init (struct mlx5_ib_dev *dev) {struct mlx5_ib_resources *devr = &dev->devr; -int port;int ret;if (!MLX5_CAP_GEN (dev->mdev, xrc))
@@ -2915,10 +2914,6 @@ static int mlx5_ib_dev_res_init(struct mlx5_ib_dev *dev)return ret; } -for (port =0 ; port <ARRAY_SIZE (devr->ports); ++port) -INIT_WORK (&devr->ports[port].pkey_change_work, - pkey_change_handler); -mutex_init (&devr->cq_lock);mutex_init (&devr->srq_lock);
@@ -2928,16 +2923,6 @@ static int mlx5_ib_dev_res_init(struct mlx5_ib_dev *dev)static void mlx5_ib_dev_res_cleanup (struct mlx5_ib_dev *dev) {struct mlx5_ib_resources *devr = &dev->devr; -int port; - -/* -* Make sure no change P_Key work items are still executing. -* -* At this stage, the mlx5_ib_event should be unregistered -* and it ensures that no new works are added. -*/ -for (port =0 ; port <ARRAY_SIZE (devr->ports); ++port) -cancel_work_sync (&devr->ports[port].pkey_change_work);/* After s0/s1 init, they are not unset during the device lifetime. */ if (devr->s1) {
@@ -4201,6 +4186,13 @@ static void mlx5_ib_stage_delay_drop_cleanup(struct mlx5_ib_dev *dev)static int mlx5_ib_stage_dev_notifier_init (struct mlx5_ib_dev *dev) { +struct mlx5_ib_resources *devr = &dev->devr; +int port; + +for (port =0 ; port <ARRAY_SIZE (devr->ports); ++port) +INIT_WORK (&devr->ports[port].pkey_change_work, + pkey_change_handler); + dev->mdev_events.notifier_call = mlx5_ib_event;mlx5_notifier_register (dev->mdev, &dev->mdev_events);
@@ -4211,8 +4203,14 @@ static int mlx5_ib_stage_dev_notifier_init(struct mlx5_ib_dev *dev)static void mlx5_ib_stage_dev_notifier_cleanup (struct mlx5_ib_dev *dev) { +struct mlx5_ib_resources *devr = &dev->devr; +int port; +mlx5r_macsec_event_unregister (dev);mlx5_notifier_unregister (dev->mdev, &dev->mdev_events); + +for (port =0 ; port <ARRAY_SIZE (devr->ports); ++port) +cancel_work_sync (&devr->ports[port].pkey_change_work); } void __mlx5_ib_remove(struct mlx5_ib_dev *dev,
@@ -4286,9 +4284,6 @@ static const struct mlx5_ib_profile pf_profile = {STAGE_CREATE (MLX5_IB_STAGE_DEVICE_RESOURCES , mlx5_ib_dev_res_init, mlx5_ib_dev_res_cleanup), -STAGE_CREATE (MLX5_IB_STAGE_DEVICE_NOTIFIER , - mlx5_ib_stage_dev_notifier_init, - mlx5_ib_stage_dev_notifier_cleanup),STAGE_CREATE (MLX5_IB_STAGE_ODP , mlx5_ib_odp_init_one, mlx5_ib_odp_cleanup_one),
@@ -4313,6 +4308,9 @@ static const struct mlx5_ib_profile pf_profile = {STAGE_CREATE (MLX5_IB_STAGE_IB_REG , mlx5_ib_stage_ib_reg_init, mlx5_ib_stage_ib_reg_cleanup), +STAGE_CREATE (MLX5_IB_STAGE_DEVICE_NOTIFIER , + mlx5_ib_stage_dev_notifier_init, + mlx5_ib_stage_dev_notifier_cleanup),STAGE_CREATE (MLX5_IB_STAGE_POST_IB_REG_UMR , mlx5_ib_stage_post_ib_reg_umr_init, NULL),
@@ -4349,9 +4347,6 @@ const struct mlx5_ib_profile raw_eth_profile = {STAGE_CREATE (MLX5_IB_STAGE_DEVICE_RESOURCES , mlx5_ib_dev_res_init, mlx5_ib_dev_res_cleanup), -STAGE_CREATE (MLX5_IB_STAGE_DEVICE_NOTIFIER , - mlx5_ib_stage_dev_notifier_init, - mlx5_ib_stage_dev_notifier_cleanup),STAGE_CREATE (MLX5_IB_STAGE_COUNTERS , mlx5_ib_counters_init, mlx5_ib_counters_cleanup),
@@ -4373,6 +4368,9 @@ const struct mlx5_ib_profile raw_eth_profile = {STAGE_CREATE (MLX5_IB_STAGE_IB_REG , mlx5_ib_stage_ib_reg_init, mlx5_ib_stage_ib_reg_cleanup), +STAGE_CREATE (MLX5_IB_STAGE_DEVICE_NOTIFIER , + mlx5_ib_stage_dev_notifier_init, + mlx5_ib_stage_dev_notifier_cleanup),STAGE_CREATE (MLX5_IB_STAGE_POST_IB_REG_UMR , mlx5_ib_stage_post_ib_reg_umr_init, NULL),
drivers/infiniband/hw/mlx5/mlx5_ib.h +1 -1
@@ -954,7 +954,6 @@ enum mlx5_ib_stages {MLX5_IB_STAGE_QP ,MLX5_IB_STAGE_SRQ ,MLX5_IB_STAGE_DEVICE_RESOURCES , -MLX5_IB_STAGE_DEVICE_NOTIFIER ,MLX5_IB_STAGE_ODP ,MLX5_IB_STAGE_COUNTERS , MLX5_IB_STAGE_CONG_DEBUGFS,
@@ -963,6 +962,7 @@ enum mlx5_ib_stages {MLX5_IB_STAGE_PRE_IB_REG_UMR ,MLX5_IB_STAGE_WHITELIST_UID ,MLX5_IB_STAGE_IB_REG , +MLX5_IB_STAGE_DEVICE_NOTIFIER ,MLX5_IB_STAGE_POST_IB_REG_UMR ,MLX5_IB_STAGE_DELAY_DROP , MLX5_IB_STAGE_RESTRACK,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 326/676 clk: clk-apple-nco: Add NULL check in applnco_probe
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Charles Han <[email protected]>
[ Upstream commit 969c765e2b508cca9099d246c010a1e48dcfd089 ]
Add NULL check in applnco_probe, to handle kernel NULL pointer dereference error.
--- drivers/clk/clk-apple-nco.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/clk/clk-apple-nco.c +3 -0
@@ -297,6 +297,9 @@ static int applnco_probe(struct platform_device *pdev)memset (&init,0 ,sizeof (init)); init.name =devm_kasprintf (&pdev->dev,GFP_KERNEL ,"%s-%d" , np->name, i); +if (!init.name) +return -ENOMEM ; + init.ops = &applnco_ops; init.parent_data = &pdata; init.num_parents =1 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 327/676 clk: ralink: mtmips: fix clock plan for Ralink SoC RT3883
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sergio Paracuellos <[email protected]>
[ Upstream commit 33239152305567b3e9bf052f71fd4baecd626341 ]
Clock plan for Ralink SoC RT3883 needs an extra 'periph' clock to properly set some peripherals that has this clock as their parent. When this driver was mainlined we could not find any active users of this SoC so we cannot perform any real tests for it. Now, one user of a Belkin f9k1109 version 1 device which uses this SoC appear and reported some issues in openWRT:
- https://github.com/openwrt/openwrt/issues/16054
The peripherals that are wrong are 'uart', 'i2c', 'i2s' and 'uartlite' which has a not defined 'periph' clock as parent. Hence, introduce it to have a properly working clock plan for this SoC.
--- drivers/clk/ralink/clk-mtmips.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/clk/ralink/clk-mtmips.c +7 -2
@@ -267,6 +267,11 @@ static struct mtmips_clk_fixed rt305x_fixed_clocks[] = { CLK_FIXED("xtal", NULL, 40000000) }; +static struct mtmips_clk_fixed rt3883_fixed_clocks[] = { +CLK_FIXED ("xtal" ,NULL ,40000000 ), +CLK_FIXED ("periph" ,"xtal" ,40000000 ) +}; +static struct mtmips_clk_fixed rt3352_fixed_clocks[] = {CLK_FIXED ("periph" ,"xtal" ,40000000 ) };
@@ -779,8 +784,8 @@ static const struct mtmips_clk_data rt3352_clk_data = {static const struct mtmips_clk_data rt3883_clk_data = { .clk_base = rt3883_clks_base, .num_clk_base =ARRAY_SIZE (rt3883_clks_base), - .clk_fixed = rt305x_fixed_clocks, - .num_clk_fixed =ARRAY_SIZE (rt305x_fixed_clocks), + .clk_fixed = rt3883_fixed_clocks, + .num_clk_fixed =ARRAY_SIZE (rt3883_fixed_clocks), .clk_factor =NULL , .num_clk_factor =0 , .clk_periph = rt5350_pherip_clks,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 328/676 clk: ralink: mtmips: fix clocks probe order in oldest ralink SoCs
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sergio Paracuellos <[email protected]>
[ Upstream commit d34db686a3d74bd564bfce2ada15011c556269fc ]
Base clocks are the first in being probed and are real dependencies of the rest of fixed, factor and peripheral clocks. For old ralink SoCs RT2880, RT305x and RT3883 'xtal' must be defined first since in any other case, when fixed clocks are probed they are delayed until 'xtal' is probed so the following warning appears:
WARNING: CPU: 0 PID: 0 at drivers/clk/ralink/clk-mtmips.c:499 rt3883_bus_recalc_rate+0x98/0x138 Modules linked in: CPU: 0 PID: 0 Comm: swapper Not tainted 6.6.43 #0 Stack : 805e58d0 00000000 00000004 8004f950 00000000 00000004 00000000 00000000 80669c54 80830000 80700000 805ae570 80670068 00000001 80669bf8 00000000 00000000 00000000 805ae570 80669b38 00000020 804db7dc 00000000 00000000 203a6d6d 80669b78 80669e48 70617773 00000000 805ae570 00000000 00000009 00000000 00000001 00000004 00000001 00000000 00000000 83fe43b0 00000000 ... Call Trace: [<800065d0>] show_stack+0x64/0xf4 [<804bca14>] dump_stack_lvl+0x38/0x60 [<800218ac>] __warn+0x94/0xe4 [<8002195c>] warn_slowpath_fmt+0x60/0x94 [<80259ff8>] rt3883_bus_recalc_rate+0x98/0x138 [<80254530>] __clk_register+0x568/0x688 [<80254838>] of_clk_hw_register+0x18/0x2c [<8070b910>] rt2880_clk_of_clk_init_driver+0x18c/0x594 [<8070b628>] of_clk_init+0x1c0/0x23c [<806fc448>] plat_time_init+0x58/0x18c [<806fdaf0>] time_init+0x10/0x6c [<806f9bc4>] start_kernel+0x458/0x67c ---[ end trace 0000000000000000 ]---
When this driver was mainlined we could not find any active users of old ralink SoCs so we cannot perform any real tests for them. Now, one user of a Belkin f9k1109 version 1 device which uses RT3883 SoC appeared and reported some issues in openWRT:
- https://github.com/openwrt/openwrt/issues/16054
Thus, define a 'rt2880_xtal_recalc_rate()' just returning the expected frequency 40Mhz and use it along the old ralink SoCs to have a correct boot trace with no warnings and a working clock plan from the beggining.
--- drivers/clk/ralink/clk-mtmips.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-)
drivers/clk/ralink/clk-mtmips.c +13 -8
@@ -263,10 +263,6 @@ static int mtmips_register_pherip_clocks(struct device_node *np, .rate = _rate \ } -static struct mtmips_clk_fixed rt305x_fixed_clocks[] = { -CLK_FIXED ("xtal" ,NULL ,40000000 ) -}; -static struct mtmips_clk_fixed rt3883_fixed_clocks[] = {CLK_FIXED ("xtal" ,NULL ,40000000 ),CLK_FIXED ("periph" ,"xtal" ,40000000 )
@@ -371,6 +367,12 @@ static inline struct mtmips_clk *to_mtmips_clk(struct clk_hw *hw) return container_of(hw, struct mtmips_clk, hw); } +static unsigned long rt2880_xtal_recalc_rate (struct clk_hw *hw, +unsigned long parent_rate) +{ +return 40000000 ; +} +static unsigned long rt5350_xtal_recalc_rate (struct clk_hw *hw,unsigned long parent_rate) {
@@ -682,10 +684,12 @@ static unsigned long mt76x8_cpu_recalc_rate(struct clk_hw *hw, }static struct mtmips_clk rt2880_clks_base[] = { + {CLK_BASE ("xtal" ,NULL , rt2880_xtal_recalc_rate) }, {CLK_BASE ("cpu" ,"xtal" , rt2880_cpu_recalc_rate) } };static struct mtmips_clk rt305x_clks_base[] = { + {CLK_BASE ("xtal" ,NULL , rt2880_xtal_recalc_rate) }, {CLK_BASE ("cpu" ,"xtal" , rt305x_cpu_recalc_rate) } };
@@ -695,6 +699,7 @@ static struct mtmips_clk rt3352_clks_base[] = { };static struct mtmips_clk rt3883_clks_base[] = { + {CLK_BASE ("xtal" ,NULL , rt2880_xtal_recalc_rate) }, {CLK_BASE ("cpu" ,"xtal" , rt3883_cpu_recalc_rate) }, {CLK_BASE ("bus" ,"cpu" , rt3883_bus_recalc_rate) } };
@@ -751,8 +756,8 @@ static int mtmips_register_clocks(struct device_node *np,static const struct mtmips_clk_data rt2880_clk_data = { .clk_base = rt2880_clks_base, .num_clk_base =ARRAY_SIZE (rt2880_clks_base), - .clk_fixed = rt305x_fixed_clocks, - .num_clk_fixed =ARRAY_SIZE (rt305x_fixed_clocks), + .clk_fixed =NULL , + .num_clk_fixed =0 , .clk_factor = rt2880_factor_clocks, .num_clk_factor =ARRAY_SIZE (rt2880_factor_clocks), .clk_periph = rt2880_pherip_clks,
@@ -762,8 +767,8 @@ static const struct mtmips_clk_data rt2880_clk_data = {static const struct mtmips_clk_data rt305x_clk_data = { .clk_base = rt305x_clks_base, .num_clk_base =ARRAY_SIZE (rt305x_clks_base), - .clk_fixed = rt305x_fixed_clocks, - .num_clk_fixed =ARRAY_SIZE (rt305x_fixed_clocks), + .clk_fixed =NULL , + .num_clk_fixed =0 , .clk_factor = rt305x_factor_clocks, .num_clk_factor =ARRAY_SIZE (rt305x_factor_clocks), .clk_periph = rt305x_pherip_clks,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 329/676 dt-bindings: clock: axi-clkgen: include AXI clk
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nuno Sa <[email protected]>
[ Upstream commit 47f3f5a82a31527e027929c5cec3dd1ef5ef30f5 ]
In order to access the registers of the HW, we need to make sure that the AXI bus clock is enabled. Hence let's increase the number of clocks by one and add clock-names to differentiate between parent clocks and the bus clock.
--- .../bindings/clock/adi,axi-clkgen.yaml | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-)
Documentation/devicetree/bindings/clock/adi,axi-clkgen.yaml +18 -4
@@ -26,9 +26,21 @@ properties: description: Specifies the reference clock(s) from which the output frequency is derived. This must either reference one clock if only the first clock - input is connected or two if both clock inputs are connected. - minItems: 1 - maxItems: 2 + input is connected or two if both clock inputs are connected. The last + clock is the AXI bus clock that needs to be enabled so we can access the + core registers. + minItems: 2 + maxItems: 3 + + clock-names: + oneOf: + - items: + - const: clkin1 + - const: s_axi_aclk + - items: + - const: clkin1 + - const: clkin2 + - const: s_axi_aclk '#clock-cells': const: 0
@@ -40,6 +52,7 @@ required: - compatible - reg - clocks + - clock-names - '#clock-cells' additionalProperties: false
@@ -50,5 +63,6 @@ examples: compatible = "adi,axi-clkgen-2.00.a"; #clock-cells = <0>; reg = <0xff000000 0x1000>; - clocks = <&osc 1>; + clocks = <&osc 1>, <&clkc 15>; + clock-names = "clkin1", "s_axi_aclk"; };
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 330/676 clk: clk-axi-clkgen: make sure to enable the AXI bus clock
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nuno Sa <[email protected]>
[ Upstream commit c64ef7e4851d1a9abbb7f7833e4936973ac5ba79 ]
In order to access the registers of the HW, we need to make sure that the AXI bus clock is enabled. Hence let's increase the number of clocks by one.
In order to keep backward compatibility and make sure old DTs still work we check if clock-names is available or not. If it is, then we can disambiguate between really having the AXI clock or a parent clock and so we can enable the bus clock. If not, we fallback to what was done before and don't explicitly enable the AXI bus clock.
Note that if clock-names is given, the axi clock must be the last one in the phandle array (also enforced in the DT bindings) so that we can reuse as much code as possible.
--- drivers/clk/clk-axi-clkgen.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-)
drivers/clk/clk-axi-clkgen.c +20 -2
@@ -7,6 +7,7 @@*/ #include <linux/platform_device.h> +#include <linux/clk.h> #include <linux/clk-provider.h> #include <linux/slab.h> #include <linux/io.h>
@@ -512,6 +513,7 @@ static int axi_clkgen_probe(struct platform_device *pdev)struct clk_init_data init;const char *parent_names[2 ];const char *clk_name; +struct clk *axi_clk;unsigned int i;int ret;
@@ -528,8 +530,24 @@ static int axi_clkgen_probe(struct platform_device *pdev)return PTR_ERR (axi_clkgen->base); init.num_parents =of_clk_get_parent_count (pdev->dev.of_node); -if (init.num_parents <1 || init.num_parents >2 ) -return -EINVAL ; + + axi_clk =devm_clk_get_enabled (&pdev->dev,"s_axi_aclk" ); +if (!IS_ERR (axi_clk)) { +if (init.num_parents <2 || init.num_parents >3 ) +return -EINVAL ; + + init.num_parents -=1 ; + }else { +/* +* Legacy... So that old DTs which do not have clock-names still +* work. In this case we don't explicitly enable the AXI bus +* clock. +*/ +if (PTR_ERR (axi_clk) != -ENOENT ) +return PTR_ERR (axi_clk); +if (init.num_parents <1 || init.num_parents >2 ) +return -EINVAL ; + }for (i =0 ; i < init.num_parents; i++) { parent_names[i] =of_clk_get_parent_name (pdev->dev.of_node, i);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 331/676 arm64: dts: qcom: sc8180x: Add a SoC-specific compatible to cpufreq-hw
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Konrad Dybcio <[email protected]>
[ Upstream commit 5df30684415d5a902f23862ab5bbed2a2df7fbf1 ]
Comply with bindings guidelines and get rid of errors such as:
cpufreq@18323000: compatible: 'oneOf' conditional failed, one must be fixed:
['qcom,cpufreq-hw'] is too short
--- arch/arm64/boot/dts/qcom/sc8180x.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/qcom/sc8180x.dtsi +1 -1
@@ -3618,7 +3618,7 @@ lmh@18358800 { }; cpufreq_hw: cpufreq@18323000 { - compatible = "qcom,cpufreq-hw"; + compatible = "qcom,sc8180x-cpufreq-hw", "qcom,cpufreq-hw"; reg = <0 0x18323000 0 0x1400>, <0 0x18325800 0 0x1400>; reg-names = "freq-domain0", "freq-domain1";
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 332/676 pinctrl: k210: Undef K210_PC_DEFAULT
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: zhang jiao <[email protected]>
[ Upstream commit 7e86490c5dee5c41a55f32d0dc34269e200e6909 ]
When the temporary macro K210_PC_DEFAULT is not needed anymore, use its name in the #undef statement instead of
the incorrect "DEFAULT" name.
--- drivers/pinctrl/pinctrl-k210.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pinctrl/pinctrl-k210.c +1 -1
@@ -183,7 +183,7 @@ static const u32 k210_pinconf_mode_id_to_mode[] = { [K210_PC_DEFAULT_INT13] = K210_PC_MODE_IN | K210_PC_PU, }; -#undef DEFAULT +#undef K210_PC_DEFAULT/* * Pin functions configuration information.
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 333/676 smb: cached directories can be more than root file handle
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paul Aurich <[email protected]>
[ Upstream commit 128630e1dbec8074c7707aad107299169047e68f ]
Update this log message since cached fids may represent things other than the root of a mount.
--- fs/smb/client/cached_dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/smb/client/cached_dir.c +1 -1
@@ -401,7 +401,7 @@ int open_cached_dir_by_dentry(struct cifs_tcon *tcon,spin_lock (&cfids->cfid_list_lock);list_for_each_entry (cfid, &cfids->entries, entry) {if (dentry && cfid->dentry == dentry) { -cifs_dbg (FYI ,"found a cached root file handle by dentry\n" ); +cifs_dbg (FYI ,"found a cached file handle by dentry\n" );kref_get (&cfid->refcount); *ret_cfid = cfid;spin_unlock (&cfids->cfid_list_lock);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 334/676 mailbox: arm_mhuv2: clean up loop in get_irq_chan_comb()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
[ Upstream commit 192a16a3430ca459c4e986f3d10758c4d6b1aa29 ]
Both the inner and outer loops in this code use the "i" iterator. The inner loop should really use a different iterator.
It doesn't affect things in practice because the data comes from the device tree. The "protocol" and "windows" variables are going to be zero. That means we're always going to hit the "return &chans[channel];" statement and we're not going to want to iterate through the outer loop again.
Still it's worth fixing this for future use cases.
--- drivers/mailbox/arm_mhuv2.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/mailbox/arm_mhuv2.c +4 -4
@@ -500,7 +500,7 @@ static const struct mhuv2_protocol_ops mhuv2_data_transfer_ops = {static struct mbox_chan *get_irq_chan_comb (struct mhuv2 *mhu,u32 __iomem *reg) {struct mbox_chan *chans = mhu->mbox.chans; -int channel =0 , i, offset =0 , windows, protocol, ch_wn; +int channel =0 , i, j, offset =0 , windows, protocol, ch_wn;u32 stat;for (i =0 ; i <MHUV2_CMB_INT_ST_REG_CNT ; i++) {
@@ -510,9 +510,9 @@ static struct mbox_chan *get_irq_chan_comb(struct mhuv2 *mhu, u32 __iomem *reg) ch_wn = i *MHUV2_STAT_BITS +__builtin_ctz (stat); -for (i =0 ; i < mhu->length; i +=2 ) { - protocol = mhu->protocols[i]; - windows = mhu->protocols[i +1 ]; +for (j =0 ; j < mhu->length; j +=2 ) { + protocol = mhu->protocols[j]; + windows = mhu->protocols[j +1 ];if (ch_wn >= offset + windows) {if (protocol ==DOORBELL )
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 335/676 perf cs-etm: Dont flush when packet_queue fills up
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: James Clark <[email protected]>
[ Upstream commit 5afd032961e8465808c4bc385c06e7676fbe1951 ]
cs_etm__flush(), like cs_etm__sample() is an operation that generates a sample and then swaps the current with the previous packet. Calling flush after processing the queues results in two swaps which corrupts the next sample. Therefore it wasn't appropriate to call flush here so remove it.
Flushing is still done on a discontinuity to explicitly clear the last branch buffer, but when the packet_queue fills up before reaching a timestamp, that's not a discontinuity and the call to cs_etm__process_traceid_queue() already generated samples and drained the buffers correctly.
This is visible by looking for a branch that has the same target as the previous branch and the following source is before the address of the last target, which is impossible as execution would have had to have gone backwards:
ffff800080849d40 _find_next_and_bit+0x78 => ffff80008011cadc update_sg_lb_stats+0x94
(packet_queue fills here before a timestamp, resulting in a flush and
branch target ffff80008011cadc is duplicated.)
ffff80008011cb1c update_sg_lb_stats+0xd4 => ffff80008011cadc update_sg_lb_stats+0x94 ffff8000801117c4 cpu_util+0x24 => ffff8000801117d4 cpu_util+0x34
After removing the flush the correct branch target is used for the second sample, and ffff8000801117c4 is no longer before the previous address:
ffff800080849d40 _find_next_and_bit+0x78 => ffff80008011cadc update_sg_lb_stats+0x94 ffff80008011cb1c update_sg_lb_stats+0xd4 => ffff8000801117a0 cpu_util+0x0 ffff8000801117c4 cpu_util+0x24 => ffff8000801117d4 cpu_util+0x34
Make sure that a final branch stack is output at the end of the trace by calling cs_etm__end_block(). This is already done for both the timeless decode paths.
--- tools/perf/util/cs-etm.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-)
tools/perf/util/cs-etm.c +18 -7
@@ -2412,12 +2412,6 @@ static void cs_etm__clear_all_traceid_queues(struct cs_etm_queue *etmq)/* Ignore return value */ cs_etm__process_traceid_queue (etmq, tidq); - -/* -* Generate an instruction sample with the remaining -* branchstack entries. -*/ -cs_etm__flush (etmq, tidq); } }
@@ -2560,7 +2554,7 @@ static int cs_etm__process_timestamped_queues(struct cs_etm_auxtrace *etm)while (1 ) {if (!etm->heap.heap_cnt) - goto out; +break ;/* Take the entry at the top of the min heap */ cs_queue_nr = etm->heap.heap_array[0 ].queue_nr;
@@ -2643,6 +2637,23 @@ static int cs_etm__process_timestamped_queues(struct cs_etm_auxtrace *etm) ret =auxtrace_heap__add (&etm->heap, cs_queue_nr, cs_timestamp); } +for (i =0 ; i < etm->queues.nr_queues; i++) { +struct int_node *inode; + + etmq = etm->queues.queue_array[i].priv; +if (!etmq) +continue ; + +intlist__for_each_entry (inode, etmq->traceid_queues_list) { +int idx = (int )(intptr_t )inode->priv; + +/* Flush any remaining branch stack entries */ + tidq = etmq->traceid_queues[idx]; + ret =cs_etm__end_block (etmq, tidq); +if (ret) +return ret; + } + } out:return ret; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 336/676 gfs2: Get rid of gfs2_glock_queue_put in signal_our_withdraw
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andreas Gruenbacher <[email protected]>
[ Upstream commit f80d882edcf242d0256d9e51b09d5fb7a3a0d3b4 ]
In function signal_our_withdraw(), we are calling gfs2_glock_queue_put() in a context in which we are actually allowed to sleep, so replace that with a simple call to gfs2_glock_put().
Stable-dep-of: 7c6f714d8847 ("gfs2: Fix unlinked inode cleanup")
--- fs/gfs2/util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/gfs2/util.c +1 -1
@@ -255,7 +255,7 @@ static void signal_our_withdraw(struct gfs2_sbd *sdp)gfs2_glock_nq (&sdp->sd_live_gh); } -gfs2_glock_queue_put (live_gl);/* drop extra reference we acquired */ +gfs2_glock_put (live_gl);/* drop extra reference we acquired */ clear_bit (SDF_WITHDRAW_RECOVERY , &sdp->sd_flags);/*
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 337/676 gfs2: Replace gfs2_glock_queue_put with gfs2_glock_put_async
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andreas Gruenbacher <[email protected]>
[ Upstream commit ee2be7d7c7f32783f60ee5fe59b91548a4571f10 ]
Function gfs2_glock_queue_put() puts a glock reference by enqueuing glock work instead of putting the reference directly. This ensures that the operation won't sleep, but it is costly and really only necessary when putting the final glock reference. Replace it with a new gfs2_glock_put_async() function that only queues glock work when putting the last glock reference.
Stable-dep-of: 7c6f714d8847 ("gfs2: Fix unlinked inode cleanup")
--- fs/gfs2/glock.c | 27 +++++++++++++++++---------- fs/gfs2/glock.h | 2 +- fs/gfs2/log.c | 2 +- fs/gfs2/super.c | 4 ++-- 4 files changed, 21 insertions(+), 14 deletions(-)
fs/gfs2/glock.c +17 -10
@@ -311,14 +311,6 @@ static void __gfs2_glock_put(struct gfs2_glock *gl) sdp->sd_lockstruct.ls_ops->lm_put_lock (gl); } -/* -* Cause the glock to be put in work queue context. -*/ -void gfs2_glock_queue_put (struct gfs2_glock *gl) -{ -gfs2_glock_queue_work (gl,0 ); -} -/** * gfs2_glock_put() - Decrement reference count on glock * @gl: The glock to put
@@ -333,6 +325,22 @@ void gfs2_glock_put(struct gfs2_glock *gl)__gfs2_glock_put (gl); } +/* +* gfs2_glock_put_async - Decrement reference count without sleeping +* @gl: The glock to put +* +* Decrement the reference count on glock immediately unless it is the last +* reference. Defer putting the last reference to work queue context. +*/ +void gfs2_glock_put_async (struct gfs2_glock *gl) +{ +if (lockref_put_or_lock (&gl->gl_lockref)) +return ; + +__gfs2_glock_queue_work (gl,0 ); +spin_unlock (&gl->gl_lockref.lock); +} +/** * may_grant - check if it's ok to grant a new lock * @gl: The glock
@@ -2533,8 +2541,7 @@ static void gfs2_glock_iter_next(struct gfs2_glock_iter *gi, loff_t n)if (gl) {if (n ==0 )return ; -if (!lockref_put_not_zero (&gl->gl_lockref)) -gfs2_glock_queue_put (gl); +gfs2_glock_put_async (gl); }for (;;) { gl =rhashtable_walk_next (&gi->hti);
fs/gfs2/glock.h +1 -1
@@ -186,7 +186,7 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number, int create, struct gfs2_glock **glp);struct gfs2_glock *gfs2_glock_hold (struct gfs2_glock *gl);void gfs2_glock_put (struct gfs2_glock *gl); -void gfs2_glock_queue_put (struct gfs2_glock *gl); +void gfs2_glock_put_async (struct gfs2_glock *gl); void __gfs2_holder_init(struct gfs2_glock *gl, unsigned int state, u16 flags, struct gfs2_holder *gh,
fs/gfs2/log.c +1 -1
@@ -790,7 +790,7 @@ void gfs2_glock_remove_revoke(struct gfs2_glock *gl) {if (atomic_dec_return (&gl->gl_revokes) ==0 ) {clear_bit (GLF_LFLUSH , &gl->gl_flags); -gfs2_glock_queue_put (gl); +gfs2_glock_put_async (gl); } }
fs/gfs2/super.c +2 -2
@@ -1054,7 +1054,7 @@ static int gfs2_drop_inode(struct inode *inode)gfs2_glock_hold (gl);if (!gfs2_queue_try_to_evict (gl)) -gfs2_glock_queue_put (gl); +gfs2_glock_put_async (gl);return 0 ; }
@@ -1270,7 +1270,7 @@ static int gfs2_dinode_dealloc(struct gfs2_inode *ip)static void gfs2_glock_put_eventually (struct gfs2_glock *gl) {if (current->flags &PF_MEMALLOC ) -gfs2_glock_queue_put (gl); +gfs2_glock_put_async (gl);else gfs2_glock_put (gl); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 338/676 gfs2: Rename GLF_VERIFY_EVICT to GLF_VERIFY_DELETE
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andreas Gruenbacher <[email protected]>
[ Upstream commit 820ce8ed53ce2111aa5171f7349f289d7e9d0693 ]
Rename the GLF_VERIFY_EVICT flag to GLF_VERIFY_DELETE: that flag indicates that we want to delete an inode / verify that it has been deleted.
To match, rename gfs2_queue_verify_evict() togfs2_queue_verify_delete().
Stable-dep-of: 7c6f714d8847 ("gfs2: Fix unlinked inode cleanup")
--- fs/gfs2/glock.c | 14 +++++++------- fs/gfs2/incore.h | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-)
fs/gfs2/glock.c +7 -7
@@ -1028,11 +1028,11 @@ bool gfs2_queue_try_to_evict(struct gfs2_glock *gl) &gl->gl_delete, 0); } -static bool gfs2_queue_verify_evict (struct gfs2_glock *gl) +static bool gfs2_queue_verify_delete (struct gfs2_glock *gl) {struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; -if (test_and_set_bit (GLF_VERIFY_EVICT , &gl->gl_flags)) +if (test_and_set_bit (GLF_VERIFY_DELETE , &gl->gl_flags))return false;return queue_delayed_work (sdp->sd_delete_wq, &gl->gl_delete,5 *HZ );
@@ -1067,19 +1067,19 @@ static void delete_work_func(struct work_struct *work)if (gfs2_try_evict (gl)) {if (test_bit (SDF_KILL , &sdp->sd_flags)) goto out; -if (gfs2_queue_verify_evict (gl)) +if (gfs2_queue_verify_delete (gl))return ; } goto out; } -if (test_and_clear_bit (GLF_VERIFY_EVICT , &gl->gl_flags)) { +if (test_and_clear_bit (GLF_VERIFY_DELETE , &gl->gl_flags)) { inode =gfs2_lookup_by_inum (sdp, no_addr, gl->gl_no_formal_ino,GFS2_BLKST_UNLINKED );if (IS_ERR (inode)) {if (PTR_ERR (inode) == -EAGAIN && !test_bit (SDF_KILL , &sdp->sd_flags) && -gfs2_queue_verify_evict (gl)) +gfs2_queue_verify_delete (gl))return ; }else {d_prune_aliases (inode);
@@ -2125,7 +2125,7 @@ static void glock_hash_walk(glock_examiner examiner, const struct gfs2_sbd *sdp)void gfs2_cancel_delete_work (struct gfs2_glock *gl) {clear_bit (GLF_TRY_TO_EVICT , &gl->gl_flags); -clear_bit (GLF_VERIFY_EVICT , &gl->gl_flags); +clear_bit (GLF_VERIFY_DELETE , &gl->gl_flags);if (cancel_delayed_work (&gl->gl_delete))gfs2_glock_put (gl); }
@@ -2362,7 +2362,7 @@ static const char *gflags2str(char *buf, const struct gfs2_glock *gl) *p++ ='N' ;if (test_bit (GLF_TRY_TO_EVICT , gflags)) *p++ ='e' ; -if (test_bit (GLF_VERIFY_EVICT , gflags)) +if (test_bit (GLF_VERIFY_DELETE , gflags)) *p++ ='E' ; *p =0 ;return buf;
fs/gfs2/incore.h +1 -1
@@ -331,7 +331,7 @@ enum {GLF_BLOCKING =15 ,GLF_FREEING =16 ,/* Wait for glock to be freed */ GLF_TRY_TO_EVICT =17 ,/* iopen glocks only */ - GLF_VERIFY_EVICT = 18, /* iopen glocks only */ + GLF_VERIFY_DELETE = 18, /* iopen glocks only */ }; struct gfs2_glock {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 339/676 gfs2: Allow immediate GLF_VERIFY_DELETE work
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andreas Gruenbacher <[email protected]>
[ Upstream commit 160bc9555d8654464cbbd7bb1f6687048471d2f6 ]
Add an argument to gfs2_queue_verify_delete() that allows it to queue GLF_VERIFY_DELETE work for immediate execution. This is used in the next patch.
Stable-dep-of: 7c6f714d8847 ("gfs2: Fix unlinked inode cleanup")
--- fs/gfs2/glock.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
fs/gfs2/glock.c +6 -5
@@ -1028,14 +1028,15 @@ bool gfs2_queue_try_to_evict(struct gfs2_glock *gl) &gl->gl_delete, 0); } -static bool gfs2_queue_verify_delete (struct gfs2_glock *gl) +static bool gfs2_queue_verify_delete (struct gfs2_glock *gl,bool later) {struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; +unsigned long delay;if (test_and_set_bit (GLF_VERIFY_DELETE , &gl->gl_flags))return false; -return queue_delayed_work (sdp->sd_delete_wq, - &gl->gl_delete,5 *HZ ); + delay = later ?5 *HZ :0 ; +return queue_delayed_work (sdp->sd_delete_wq, &gl->gl_delete, delay); }static void delete_work_func (struct work_struct *work)
@@ -1067,7 +1068,7 @@ static void delete_work_func(struct work_struct *work)if (gfs2_try_evict (gl)) {if (test_bit (SDF_KILL , &sdp->sd_flags)) goto out; -if (gfs2_queue_verify_delete (gl)) +if (gfs2_queue_verify_delete (gl, true))return ; } goto out;
@@ -1079,7 +1080,7 @@ static void delete_work_func(struct work_struct *work)if (IS_ERR (inode)) {if (PTR_ERR (inode) == -EAGAIN && !test_bit (SDF_KILL , &sdp->sd_flags) && -gfs2_queue_verify_delete (gl)) +gfs2_queue_verify_delete (gl, true))return ; }else {d_prune_aliases (inode);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 340/676 gfs2: Fix unlinked inode cleanup
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andreas Gruenbacher <[email protected]>
[ Upstream commit 7c6f714d88475ceae5342264858a641eafa19632 ]
Before commit f0e56edc2ec7 ("gfs2: Split the two kinds of glock "delete" work"), function delete_work_func() was used to trigger the eviction of in-memory inodes from remote as well as deleting unlinked inodes at a later point. These two kinds of work were then split into two kinds of work, and the two places in the code were deferred deletion of inodes is required accidentally ended up queuing the wrong kind of work. This caused unlinked inodes to be left behind, which could in the worst case fill up filesystems and require a filesystem check to recover.
Fix that by queuing the right kind of work in try_rgrp_unlink() and gfs2_drop_inode().
--- fs/gfs2/glock.c | 2 +- fs/gfs2/glock.h | 1 + fs/gfs2/rgrp.c | 2 +- fs/gfs2/super.c | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-)
fs/gfs2/glock.c +1 -1
@@ -1028,7 +1028,7 @@ bool gfs2_queue_try_to_evict(struct gfs2_glock *gl) &gl->gl_delete, 0); } -static bool gfs2_queue_verify_delete (struct gfs2_glock *gl,bool later) +bool gfs2_queue_verify_delete (struct gfs2_glock *gl,bool later) {struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;unsigned long delay;
fs/gfs2/glock.h +1 -0
@@ -259,6 +259,7 @@ static inline int gfs2_glock_nq_init(struct gfs2_glock *gl,void gfs2_glock_cb (struct gfs2_glock *gl,unsigned int state);void gfs2_glock_complete (struct gfs2_glock *gl,int ret);bool gfs2_queue_try_to_evict (struct gfs2_glock *gl); +bool gfs2_queue_verify_delete (struct gfs2_glock *gl,bool later);void gfs2_cancel_delete_work (struct gfs2_glock *gl);void gfs2_flush_delete_work (struct gfs2_sbd *sdp);void gfs2_gl_hash_clear (struct gfs2_sbd *sdp);
fs/gfs2/rgrp.c +1 -1
@@ -1879,7 +1879,7 @@ static void try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked, u64 skip*/ ip = gl->gl_object; -if (ip || !gfs2_queue_try_to_evict (gl)) +if (ip || !gfs2_queue_verify_delete (gl, false))gfs2_glock_put (gl);else found++;
fs/gfs2/super.c +1 -1
@@ -1053,7 +1053,7 @@ static int gfs2_drop_inode(struct inode *inode)struct gfs2_glock *gl = ip->i_iopen_gh.gh_gl;gfs2_glock_hold (gl); -if (!gfs2_queue_try_to_evict (gl)) +if (!gfs2_queue_verify_delete (gl, true))gfs2_glock_put_async (gl);return 0 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 341/676 PCI: Fix reset_method_store() memory leak
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Todd Kjos <[email protected]>
[ Upstream commit 2985b1844f3f3447f2d938eff1ef6762592065a5 ]
In reset_method_store(), a string is allocated via kstrndup() and assigned to the local "options". options is then used in with strsep() to find spaces:
while ((name = strsep(&options, " ")) != NULL) {If there are no remaining spaces, then options is set to NULL by strsep(), so the subsequent kfree(options) doesn't free the memory allocated via kstrndup().
Fix by using a separate tmp_options to iterate with strsep() so options is preserved.
--- drivers/pci/pci.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/pci/pci.c +3 -2
@@ -5444,7 +5444,7 @@ static ssize_t reset_method_store(struct device *dev, const char *buf, size_t count) {struct pci_dev *pdev =to_pci_dev (dev); -char *options, *name; +char *options, *tmp_options, *name;int m, n;u8 reset_methods[PCI_NUM_RESET_METHODS ] = {0 };
@@ -5464,7 +5464,8 @@ static ssize_t reset_method_store(struct device *dev,return -ENOMEM ; n =0 ; -while ((name =strsep (&options," " )) !=NULL ) { + tmp_options = options; +while ((name =strsep (&tmp_options," " )) !=NULL ) {if (sysfs_streq (name,"" ))continue ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 342/676 perf stat: Close cork_fd when create_perf_stat_counter() failed
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Levi Yun <[email protected]>
[ Upstream commit e880a70f8046df0dd9089fa60dcb866a2cc69194 ]
When create_perf_stat_counter() failed, it doesn't close workload.cork_fd open in evlist__prepare_workload(). This could make too many open file error while __run_perf_stat() repeats.
Introduce evlist__cancel_workload to close workload.cork_fd and wait workload.child_pid until exit to clear child process when create_perf_stat_counter() is failed.
Stable-dep-of: 7f6ccb70e465 ("perf stat: Fix affinity memory leaks on error path")
--- tools/perf/builtin-stat.c | 50 +++++++++++++++++++++++++++------------ tools/perf/util/evlist.c | 19 +++++++++++++-- tools/perf/util/evlist.h | 1 + 3 files changed, 53 insertions(+), 17 deletions(-)
tools/perf/builtin-stat.c +35 -15
@@ -712,15 +712,19 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx) }if (!cpu_map__is_dummy (evsel_list->core.user_requested_cpus)) { -if (affinity__setup (&saved_affinity) <0 ) -return -1 ; +if (affinity__setup (&saved_affinity) <0 ) { + err =-1 ; + goto err_out; + } affinity = &saved_affinity; }evlist__for_each_entry (evsel_list, counter) { counter->reset_group = false; -if (bpf_counter__load (counter, &target)) -return -1 ; +if (bpf_counter__load (counter, &target)) { + err =-1 ; + goto err_out; + }if (!(evsel__is_bperf (counter))) all_counters_use_bpf = false; }
@@ -763,7 +767,8 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)switch (stat_handle_error (counter)) {case COUNTER_FATAL : -return -1 ; + err =-1 ; + goto err_out;case COUNTER_RETRY : goto try_again;case COUNTER_SKIP :
@@ -804,7 +809,8 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)switch (stat_handle_error (counter)) {case COUNTER_FATAL : -return -1 ; + err =-1 ; + goto err_out;case COUNTER_RETRY : goto try_again_reset;case COUNTER_SKIP :
@@ -829,8 +835,10 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx) stat_config.unit_width = l;if (evsel__should_store_id (counter) && -evsel__store_ids (counter, evsel_list)) -return -1 ; +evsel__store_ids (counter, evsel_list)) { + err =-1 ; + goto err_out; + } }if (evlist__apply_filters (evsel_list, &counter)) {
@@ -851,20 +859,23 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx) }if (err <0 ) -return err; + goto err_out; err =perf_event__synthesize_stat_events (&stat_config,NULL , evsel_list, process_synthesized_event, is_pipe);if (err <0 ) -return err; + goto err_out; + }if (target.initial_delay) {pr_info (EVLIST_DISABLED_MSG ); }else { err =enable_counters (); -if (err) -return -1 ; +if (err) { + err =-1 ; + goto err_out; + } }/* Exec the command, if any */
@@ -874,8 +885,10 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)if (target.initial_delay >0 ) {usleep (target.initial_delay *USEC_PER_MSEC ); err =enable_counters (); -if (err) -return -1 ; +if (err) { + err =-1 ; + goto err_out; + }pr_info (EVLIST_ENABLED_MSG ); }
@@ -895,7 +908,8 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)if (workload_exec_errno) {const char *emsg =str_error_r (workload_exec_errno, msg,sizeof (msg));pr_err ("Workload failed: %s\n" , emsg); -return -1 ; + err =-1 ; + goto err_out; }if (WIFSIGNALED (status))
@@ -942,6 +956,12 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)evlist__close (evsel_list);return WEXITSTATUS (status); + +err_out: +if (forks) +evlist__cancel_workload (evsel_list); + +return err; }static int run_perf_stat (int argc,const char **argv,int run_idx)
tools/perf/util/evlist.c +17 -2
@@ -46,6 +46,7 @@#include <sys/mman.h> #include <sys/prctl.h> #include <sys/timerfd.h> +#include <sys/wait.h> #include <linux/bitops.h> #include <linux/hash.h>
@@ -1412,6 +1413,8 @@ int evlist__prepare_workload(struct evlist *evlist, struct target *target, constint child_ready_pipe[2 ], go_pipe[2 ];char bf; + evlist->workload.cork_fd =-1 ; +if (pipe (child_ready_pipe) <0 ) {perror ("failed to create 'ready' pipe" );return -1 ;
@@ -1464,7 +1467,7 @@ int evlist__prepare_workload(struct evlist *evlist, struct target *target, const* For cancelling the workload without actually running it, * the parent will just close workload.cork_fd, without writing * anything, i.e. read will return zero and we just exit() -* here. +* here (See evlist__cancel_workload()). */ if (ret !=1 ) {if (ret ==-1 )
@@ -1528,7 +1531,7 @@ int evlist__prepare_workload(struct evlist *evlist, struct target *target, constint evlist__start_workload (struct evlist *evlist) { -if (evlist->workload.cork_fd >0 ) { +if (evlist->workload.cork_fd >=0 ) {char bf =0 ;int ret;/*
@@ -1539,12 +1542,24 @@ int evlist__start_workload(struct evlist *evlist)perror ("unable to write to pipe" );close (evlist->workload.cork_fd); + evlist->workload.cork_fd =-1 ;return ret; }return 0 ; } +void evlist__cancel_workload (struct evlist *evlist) +{ +int status; + +if (evlist->workload.cork_fd >=0 ) { +close (evlist->workload.cork_fd); + evlist->workload.cork_fd =-1 ; +waitpid (evlist->workload.pid, &status,WNOHANG ); + } +} +int evlist__parse_sample (struct evlist *evlist,union perf_event *event,struct perf_sample *sample) {struct evsel *evsel =evlist__event2evsel (evlist, event);
tools/perf/util/evlist.h +1 -0
@@ -184,6 +184,7 @@ int evlist__prepare_workload(struct evlist *evlist, struct target *target, const char *argv[], bool pipe_output, void (*exec_error)(int signo, siginfo_t *info, void *ucontext));int evlist__start_workload (struct evlist *evlist); +void evlist__cancel_workload (struct evlist *evlist);struct option ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 343/676 perf stat: Fix affinity memory leaks on error path
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ian Rogers <[email protected]>
[ Upstream commit 7f6ccb70e465bd8c9cf8973aee1c01224e4bdb3c ]
Missed cleanup when an error occurs.
--- tools/perf/builtin-stat.c | 2 ++ 1 file changed, 2 insertions(+)
tools/perf/builtin-stat.c +2 -0
@@ -823,6 +823,7 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx) } }affinity__cleanup (affinity); + affinity =NULL ;evlist__for_each_entry (evsel_list, counter) {if (!counter->supported) {
@@ -961,6 +962,7 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)if (forks)evlist__cancel_workload (evsel_list); +affinity__cleanup (affinity);return err; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 344/676 perf trace: Keep exited threads for summary
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Petlan <[email protected]>
[ Upstream commit d29d92df410e2fb523f640478b18f70c1823e55e ]
Since 9ffa6c7512ca ("perf machine thread: Remove exited threads by default") perf cleans exited threads up, but as said, sometimes they are necessary to be kept. The mentioned commit does not cover all the cases, we also need the information to construct the summary table in perf-trace.
Before:
# perf trace -s true
Summary of events:
After:
# perf trace -s -- true
Summary of events:
true (383382), 64 events, 91.4%
syscall calls errors total min avg max stddev
(msec) (msec) (msec) (msec) (%)
--------------- -------- ------ -------- --------- --------- --------- ------
mmap 8 0 0.150 0.013 0.019 0.031 11.90%
mprotect 3 0 0.045 0.014 0.015 0.017 6.47%
openat 2 0 0.014 0.006 0.007 0.007 9.73%
munmap 1 0 0.009 0.009 0.009 0.009 0.00%
access 1 1 0.009 0.009 0.009 0.009 0.00%
pread64 4 0 0.006 0.001 0.001 0.002 4.53%
fstat 2 0 0.005 0.001 0.002 0.003 37.59%
arch_prctl 2 1 0.003 0.001 0.002 0.002 25.91%
read 1 0 0.003 0.003 0.003 0.003 0.00%
close 2 0 0.003 0.001 0.001 0.001 3.86%
brk 1 0 0.002 0.002 0.002 0.002 0.00%
rseq 1 0 0.001 0.001 0.001 0.001 0.00%
prlimit64 1 0 0.001 0.001 0.001 0.001 0.00%
set_robust_list 1 0 0.001 0.001 0.001 0.001 0.00%
set_tid_address 1 0 0.001 0.001 0.001 0.001 0.00%
execve 1 0 0.000 0.000 0.000 0.000 0.00%[namhyung: simplified the condition]
--- tools/perf/builtin-trace.c | 4 ++++ 1 file changed, 4 insertions(+)
tools/perf/builtin-trace.c +4 -0
@@ -5031,6 +5031,10 @@ int cmd_trace(int argc, const char **argv)if (trace.summary_only) trace.summary = trace.summary_only; +/* Keep exited threads, otherwise information might be lost for summary */ +if (trace.summary) + symbol_conf.keep_exited_threads = true; +if (output_name !=NULL ) { err =trace__open_output (&trace, output_name);if (err <0 ) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 345/676 perf test attr: Add back missing topdown events
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Veronika Molnarova <[email protected]>
[ Upstream commit 6bff76af9635411214ca44ea38fc2781e78064b6 ]
With the patch 0b6c5371c03c "Add missing topdown metrics events" eight topdown metric events with numbers ranging from 0x8000 to 0x8700 were added to the test since they were added as 'perf stat' default events. Later the patch 951efb9976ce "Update no event/metric expectations" kept only 4 of those events(0x8000-0x8300).
Currently, the topdown events with numbers 0x8400 to 0x8700 are missing from the list of expected events resulting in a failure. Add back the missing topdown events.
--- tools/perf/tests/attr/test-stat-default | 90 ++++++++++---- tools/perf/tests/attr/test-stat-detailed-1 | 106 +++++++++++----- tools/perf/tests/attr/test-stat-detailed-2 | 130 ++++++++++++------- tools/perf/tests/attr/test-stat-detailed-3 | 138 ++++++++++++++------- 4 files changed, 320 insertions(+), 144 deletions(-)
tools/perf/tests/attr/test-stat-default +67 -23
@@ -88,98 +88,142 @@ enable_on_exec=0 read_format=15 optional=1 -# PERF_TYPE_RAW / topdown-fe-bound (0x8200) +# PERF_TYPE_RAW / topdown-bad-spec (0x8100) [event13:base-stat] fd=13 group_fd=11 type=4 -config=33280 +config=33024 disabled=0 enable_on_exec=0 read_format=15 optional=1 -# PERF_TYPE_RAW / topdown-be-bound (0x8300) +# PERF_TYPE_RAW / topdown-fe-bound (0x8200) [event14:base-stat] fd=14 group_fd=11 type=4 -config=33536 +config=33280 disabled=0 enable_on_exec=0 read_format=15 optional=1 -# PERF_TYPE_RAW / topdown-bad-spec (0x8100) +# PERF_TYPE_RAW / topdown-be-bound (0x8300) [event15:base-stat] fd=15 group_fd=11 type=4 -config=33024 +config=33536 disabled=0 enable_on_exec=0 read_format=15 optional=1 -# PERF_TYPE_RAW / INT_MISC.UOP_DROPPING +# PERF_TYPE_RAW / topdown-heavy-ops (0x8400) [event16:base-stat] fd=16 +group_fd=11 type=4 -config=4109 +config=33792 +disabled=0 +enable_on_exec=0 +read_format=15 optional=1 -# PERF_TYPE_RAW / cpu/INT_MISC.RECOVERY_CYCLES,cmask=1,edge/ +# PERF_TYPE_RAW / topdown-br-mispredict (0x8500) [event17:base-stat] fd=17 +group_fd=11 type=4 -config=17039629 +config=34048 +disabled=0 +enable_on_exec=0 +read_format=15 optional=1 -# PERF_TYPE_RAW / CPU_CLK_UNHALTED.THREAD +# PERF_TYPE_RAW / topdown-fetch-lat (0x8600) [event18:base-stat] fd=18 +group_fd=11 type=4 -config=60 +config=34304 +disabled=0 +enable_on_exec=0 +read_format=15 optional=1 -# PERF_TYPE_RAW / INT_MISC.RECOVERY_CYCLES_ANY +# PERF_TYPE_RAW / topdown-mem-bound (0x8700) [event19:base-stat] fd=19 +group_fd=11 type=4 -config=2097421 +config=34560 +disabled=0 +enable_on_exec=0 +read_format=15 optional=1 -# PERF_TYPE_RAW / CPU_CLK_UNHALTED.REF_XCLK +# PERF_TYPE_RAW / INT_MISC.UOP_DROPPING [event20:base-stat] fd=20 type=4 -config=316 +config=4109 optional=1 -# PERF_TYPE_RAW / IDQ_UOPS_NOT_DELIVERED.CORE +# PERF_TYPE_RAW / cpu/INT_MISC.RECOVERY_CYCLES,cmask=1,edge/ [event21:base-stat] fd=21 type=4 -config=412 +config=17039629 optional=1 -# PERF_TYPE_RAW / CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE +# PERF_TYPE_RAW / CPU_CLK_UNHALTED.THREAD [event22:base-stat] fd=22 type=4 -config=572 +config=60 optional=1 -# PERF_TYPE_RAW / UOPS_RETIRED.RETIRE_SLOTS +# PERF_TYPE_RAW / INT_MISC.RECOVERY_CYCLES_ANY [event23:base-stat] fd=23 type=4 -config=706 +config=2097421 optional=1 -# PERF_TYPE_RAW / UOPS_ISSUED.ANY +# PERF_TYPE_RAW / CPU_CLK_UNHALTED.REF_XCLK [event24:base-stat] fd=24 type=4 +config=316 +optional=1 + +# PERF_TYPE_RAW / IDQ_UOPS_NOT_DELIVERED.CORE +[event25:base-stat] +fd=25 +type=4 +config=412 +optional=1 + +# PERF_TYPE_RAW / CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE +[event26:base-stat] +fd=26 +type=4 +config=572 +optional=1 + +# PERF_TYPE_RAW / UOPS_RETIRED.RETIRE_SLOTS +[event27:base-stat] +fd=27 +type=4 +config=706 +optional=1 + +# PERF_TYPE_RAW / UOPS_ISSUED.ANY +[event28:base-stat] +fd=28 +type=4 config=270 optional=1
tools/perf/tests/attr/test-stat-detailed-1 +75 -31
206 lines not on this page · raw message
tools/perf/tests/attr/test-stat-detailed-2 +87 -43
266 lines not on this page · raw message
tools/perf/tests/attr/test-stat-detailed-3 +91 -47
286 lines not on this page · raw message
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 346/676 f2fs: compress: fix inconsistent update of i_blocks in release_compress_blocks and reserve_compress_blocks
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qi Han <[email protected]>
[ Upstream commit 26413ce18e85de3dda2cd3d72c3c3e8ab8f4f996 ]
After release a file and subsequently reserve it, the FSCK flag is set when the file is deleted, as shown in the following backtrace:
F2FS-fs (dm-48): Inconsistent i_blocks, ino:401231, iblocks:1448, sectors:1472
fs_rec_info_write_type+0x58/0x274 f2fs_rec_info_write+0x1c/0x2c set_sbi_flag+0x74/0x98 dec_valid_block_count+0x150/0x190 f2fs_truncate_data_blocks_range+0x2d4/0x3cc f2fs_do_truncate_blocks+0x2fc/0x5f0 f2fs_truncate_blocks+0x68/0x100 f2fs_truncate+0x80/0x128 f2fs_evict_inode+0x1a4/0x794 evict+0xd4/0x280 iput+0x238/0x284 do_unlinkat+0x1ac/0x298 __arm64_sys_unlinkat+0x48/0x68 invoke_syscall+0x58/0x11c
For clusters of the following type, i_blocks are decremented by 1 and i_compr_blocks are incremented by 7 in release_compress_blocks, while updates to i_blocks and i_compr_blocks are skipped in reserve_compress_blocks.
raw node:
D D D D D D D D
after compress:
C D D D D D D D
after reserve:
C D D D D D D D
Let's update i_blocks and i_compr_blocks properly in reserve_compress_blocks.
--- fs/f2fs/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/f2fs/file.c +1 -1
@@ -3755,7 +3755,7 @@ static int reserve_compress_blocks(struct dnode_of_data *dn, pgoff_t count, to_reserved = cluster_size - compr_blocks - reserved;/* for the case all blocks in cluster were reserved */ -if (to_reserved ==1 ) { +if (reserved && to_reserved ==1 ) { dn->ofs_in_node += cluster_size; goto next; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 347/676 f2fs: fix to account dirty data in __get_secs_required()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <[email protected]>
[ Upstream commit 1acd73edbbfef2c3c5b43cba4006a7797eca7050 ]
It will trigger system panic w/ testcase in [1]:
------------[ cut here ]------------ kernel BUG at fs/f2fs/segment.c:2752! RIP: 0010:new_curseg+0xc81/0x2110 Call Trace: f2fs_allocate_data_block+0x1c91/0x4540 do_write_page+0x163/0xdf0 f2fs_outplace_write_data+0x1aa/0x340 f2fs_do_write_data_page+0x797/0x2280 f2fs_write_single_data_page+0x16cd/0x2190 f2fs_write_cache_pages+0x994/0x1c80 f2fs_write_data_pages+0x9cc/0xea0 do_writepages+0x194/0x7a0 filemap_fdatawrite_wbc+0x12b/0x1a0 __filemap_fdatawrite_range+0xbb/0xf0 file_write_and_wait_range+0xa1/0x110 f2fs_do_sync_file+0x26f/0x1c50 f2fs_sync_file+0x12b/0x1d0 vfs_fsync_range+0xfa/0x230 do_fsync+0x3d/0x80 __x64_sys_fsync+0x37/0x50 x64_sys_call+0x1e88/0x20d0 do_syscall_64+0x4b/0x110 entry_SYSCALL_64_after_hwframe+0x76/0x7e
The root cause is if checkpoint_disabling and lfs_mode are both on, it will trigger OPU for all overwritten data, it may cost more free segment than expected, so f2fs must account those data correctly to calculate cosumed free segments later, and return ENOSPC earlier to avoid run out of free segment during block allocation.
[1] https://lore.kernel.org/fstests/[email protected]/
--- fs/f2fs/segment.h | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-)
fs/f2fs/segment.h +25 -10
@@ -559,18 +559,21 @@ static inline int reserved_sections(struct f2fs_sb_info *sbi) }static inline bool has_curseg_enough_space (struct f2fs_sb_info *sbi, -unsigned int node_blocks,unsigned int dent_blocks) +unsigned int node_blocks,unsigned int data_blocks, +unsigned int dent_blocks) { -unsigned segno, left_blocks; +unsigned int segno, left_blocks, blocks;int i; -/* check current node sections in the worst case. */ -for (i =CURSEG_HOT_NODE ; i <=CURSEG_COLD_NODE ; i++) { +/* check current data/node sections in the worst case. */ +for (i =CURSEG_HOT_DATA ; i <NR_PERSISTENT_LOG ; i++) { segno =CURSEG_I (sbi, i)->segno; left_blocks =CAP_BLKS_PER_SEC (sbi) -get_ckpt_valid_blocks (sbi, segno, true); -if (node_blocks > left_blocks) + + blocks = i <=CURSEG_COLD_DATA ? data_blocks : node_blocks; +if (blocks > left_blocks)return false; }
@@ -584,8 +587,9 @@ static inline bool has_curseg_enough_space(struct f2fs_sb_info *sbi, }/* -* calculate needed sections for dirty node/dentry -* and call has_curseg_enough_space +* calculate needed sections for dirty node/dentry and call +* has_curseg_enough_space, please note that, it needs to account +* dirty data as well in lfs mode when checkpoint is disabled. */ static inline void __get_secs_required (struct f2fs_sb_info *sbi,unsigned int *lower_p,unsigned int *upper_p,bool *curseg_p)
@@ -594,19 +598,30 @@ static inline void __get_secs_required(struct f2fs_sb_info *sbi,get_pages (sbi,F2FS_DIRTY_DENTS ) +get_pages (sbi,F2FS_DIRTY_IMETA );unsigned int total_dent_blocks =get_pages (sbi,F2FS_DIRTY_DENTS ); +unsigned int total_data_blocks =0 ;unsigned int node_secs = total_node_blocks /CAP_BLKS_PER_SEC (sbi);unsigned int dent_secs = total_dent_blocks /CAP_BLKS_PER_SEC (sbi); +unsigned int data_secs =0 ;unsigned int node_blocks = total_node_blocks %CAP_BLKS_PER_SEC (sbi);unsigned int dent_blocks = total_dent_blocks %CAP_BLKS_PER_SEC (sbi); +unsigned int data_blocks =0 ; + +if (f2fs_lfs_mode (sbi) && +unlikely (is_sbi_flag_set (sbi,SBI_CP_DISABLED ))) { + total_data_blocks =get_pages (sbi,F2FS_DIRTY_DATA ); + data_secs = total_data_blocks /CAP_BLKS_PER_SEC (sbi); + data_blocks = total_data_blocks %CAP_BLKS_PER_SEC (sbi); + }if (lower_p) - *lower_p = node_secs + dent_secs; + *lower_p = node_secs + dent_secs + data_secs;if (upper_p) *upper_p = node_secs + dent_secs + - (node_blocks ?1 :0 ) + (dent_blocks ?1 :0 ); + (node_blocks ?1 :0 ) + (dent_blocks ?1 :0 ) + + (data_blocks ?1 :0 );if (curseg_p) *curseg_p =has_curseg_enough_space (sbi, - node_blocks, dent_blocks); + node_blocks, data_blocks, dent_blocks); } static inline bool has_not_enough_free_secs(struct f2fs_sb_info *sbi,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 348/676 perf probe: Fix libdw memory leak
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ian Rogers <[email protected]>
[ Upstream commit 4585038b8e186252141ef86e9f0d8e97f11dce8d ]
Add missing dwarf_cfi_end to free memory associated with probe_finder cfi_eh which is allocated and owned via a call to dwarf_getcfi_elf. Confusingly cfi_dbg shouldn't be freed as its memory is owned by the passed in debuginfo struct. Add comments to highlight this.
This addresses leak sanitizer issues seen in:tools/perf/tests/shell/test_uprobe_from_different_cu.sh
--- tools/perf/util/probe-finder.c | 4 ++++ tools/perf/util/probe-finder.h | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-)
tools/perf/util/probe-finder.c +4 -0
@@ -1499,6 +1499,10 @@ int debuginfo__find_trace_events(struct debuginfo *dbg,if (ret >=0 && tf.pf.skip_empty_arg) ret =fill_empty_trace_arg (pev, tf.tevs, tf.ntevs); +#if _ELFUTILS_PREREQ (0 ,142 ) +dwarf_cfi_end (tf.pf.cfi_eh); +#endif +if (ret <0 || tf.ntevs ==0 ) {for (i =0 ; i < tf.ntevs; i++)clear_probe_trace_event (&tf.tevs[i]);
tools/perf/util/probe-finder.h +2 -2
@@ -81,9 +81,9 @@ struct probe_finder {/* For variable searching */ #if _ELFUTILS_PREREQ (0 ,142 ) -/* Call Frame Information from .eh_frame */ +/* Call Frame Information from .eh_frame. Owned by this struct. */ Dwarf_CFI *cfi_eh; -/* Call Frame Information from .debug_frame */ +/* Call Frame Information from .debug_frame. Not owned. */ Dwarf_CFI *cfi_dbg;#endif Dwarf_Op *fb_ops;/* Frame base attribute */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 349/676 perf probe: Correct demangled symbols in C++ program
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Leo Yan <[email protected]>
[ Upstream commit 314909f13cc12d47c468602c37dace512d225eeb ]
An issue can be observed when probe C++ demangled symbol with steps:
# nm test_cpp_mangle | grep print_data
0000000000000c94 t _GLOBAL__sub_I__Z10print_datai
0000000000000afc T _Z10print_datai
0000000000000b38 T _Z10print_dataR5Point # perf probe -x /home/niayan01/test_cpp_mangle -F --demangle
...
print_data(Point&)
print_data(int)
... # perf --debug verbose=3 probe -x test_cpp_mangle --add "test=print_data(int)"
probe-definition(0): test=print_data(int)
symbol:print_data(int) file:(null) line:0 offset:0 return:0 lazy:(null)
0 arguments
Open Debuginfo file: /home/niayan01/test_cpp_mangle
Try to find probe point from debuginfo.
Symbol print_data(int) address found : afc
Matched function: print_data [2ccf]
Probe point found: print_data+0
Found 1 probe_trace_events.
Opening /sys/kernel/tracing//uprobe_events write=1
Opening /sys/kernel/tracing//README write=0
Writing event: p:probe_test_cpp_mangle/test /home/niayan01/test_cpp_mangle:0xb38
...When tried to probe symbol "print_data(int)", the log shows:
Symbol print_data(int) address found : afc
The found address is 0xafc - which is right with verifying the output result from nm. Afterwards when write event, the command uses offset 0xb38 in the last log, which is a wrong address.
The dwarf_diename() gets a common function name, in above case, it returns string "print_data". As a result, the tool parses the offset based on the common name. This leads to probe at the wrong symbol "print_data(Point&)".
To fix the issue, use the die_get_linkage_name() function to retrieve the distinct linkage name - this is the mangled name for the C++ case. Based on this unique name, the tool can get a correct offset for probing. Based on DWARF doc, it is possible the linkage name is missed in the DIE, it rolls back to use dwarf_diename().
After:
# perf --debug verbose=3 probe -x test_cpp_mangle --add "test=print_data(int)"
probe-definition(0): test=print_data(int)
symbol:print_data(int) file:(null) line:0 offset:0 return:0 lazy:(null)
0 arguments
Open Debuginfo file: /home/niayan01/test_cpp_mangle
Try to find probe point from debuginfo.
Symbol print_data(int) address found : afc
Matched function: print_data [2d06]
Probe point found: print_data+0
Found 1 probe_trace_events.
Opening /sys/kernel/tracing//uprobe_events write=1
Opening /sys/kernel/tracing//README write=0
Writing event: p:probe_test_cpp_mangle/test /home/niayan01/test_cpp_mangle:0xafc
Added new event:
probe_test_cpp_mangle:test (on print_data(int) in /home/niayan01/test_cpp_mangle)You can now use it in all perf tools, such as:
perf record -e probe_test_cpp_mangle:test -aR sleep 1
# perf --debug verbose=3 probe -x test_cpp_mangle --add "test2=print_data(Point&)"
probe-definition(0): test2=print_data(Point&)
symbol:print_data(Point&) file:(null) line:0 offset:0 return:0 lazy:(null)
0 arguments
Open Debuginfo file: /home/niayan01/test_cpp_mangle
Try to find probe point from debuginfo.
Symbol print_data(Point&) address found : b38
Matched function: print_data [2ccf]
Probe point found: print_data+0
Found 1 probe_trace_events.
Opening /sys/kernel/tracing//uprobe_events write=1
Parsing probe_events: p:probe_test_cpp_mangle/test /home/niayan01/test_cpp_mangle:0x0000000000000afc
Group:probe_test_cpp_mangle Event:test probe:p
Opening /sys/kernel/tracing//README write=0
Writing event: p:probe_test_cpp_mangle/test2 /home/niayan01/test_cpp_mangle:0xb38
Added new event:
probe_test_cpp_mangle:test2 (on print_data(Point&) in /home/niayan01/test_cpp_mangle)You can now use it in all perf tools, such as:
perf record -e probe_test_cpp_mangle:test2 -aR sleep 1
--- tools/perf/util/probe-finder.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-)
tools/perf/util/probe-finder.c +15 -2
@@ -1745,8 +1745,21 @@ int debuginfo__find_probe_point(struct debuginfo *dbg, u64 addr,/* Find a corresponding function (name, baseline and baseaddr) */ if (die_find_realfunc (&cudie, (Dwarf_Addr )addr, &spdie)) { -/* Get function entry information */ - func = basefunc =dwarf_diename (&spdie); +/* +* Get function entry information. +* +* As described in the document DWARF Debugging Information +* Format Version 5, section 2.22 Linkage Names, "mangled names, +* are used in various ways, ... to distinguish multiple +* entities that have the same name". +* +* Firstly try to get distinct linkage name, if fail then +* rollback to get associated name in DIE. +*/ + func = basefunc =die_get_linkage_name (&spdie); +if (!func) + func = basefunc =dwarf_diename (&spdie); +if (!func ||die_entrypc (&spdie, &baseaddr) !=0 ||dwarf_decl_line (&spdie, &baseline) !=0 ) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 350/676 rust: macros: fix documentation of the paste! macro
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paolo Bonzini <[email protected]>
[ Upstream commit 15541c9263ce34ff95a06bc68f45d9bc5c990bcd ]
One of the example in this section uses a curious mix of the constant and function declaration syntaxes; fix it.
--- rust/macros/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
rust/macros/lib.rs +1 -1
@@ -298,7 +298,7 @@ pub fn pinned_drop(args: TokenStream, input: TokenStream) -> TokenStream {/// macro_rules! pub_no_prefix { /// ($prefix:ident, $($newname:ident),+) => { /// kernel::macros::paste! { -/// $(pub(crate) const fn [<$newname:lower:span>]: u32 = [<$prefix $newname:span>];)+ +/// $(pub(crate) const fn [<$newname:lower:span>]() -> u32 { [<$prefix $newname:span>] })+ /// } /// }; /// }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 351/676 PCI: cpqphp: Use PCI_POSSIBLE_ERROR() to check config reads
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: weiyufeng <[email protected]>
[ Upstream commit 87d5403378cccc557af9e02a8a2c8587ad8b7e9a ]
Use PCI_POSSIBLE_ERROR() to check the response we get when we read data from hardware. This unifies PCI error response checking and makes error checks consistent and easier to find.
Stable-dep-of: e2226dbc4a49 ("PCI: cpqphp: Fix PCIBIOS_* return value confusion")
--- drivers/pci/hotplug/cpqphp_pci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/pci/hotplug/cpqphp_pci.c +2 -2
@@ -138,7 +138,7 @@ static int PCI_RefinedAccessConfig(struct pci_bus *bus, unsigned int devfn, u8 oif (pci_bus_read_config_dword (bus, devfn,PCI_VENDOR_ID , &vendID) ==-1 )return -1 ; -if (vendID ==0xffffffff ) +if (PCI_POSSIBLE_ERROR (vendID))return -1 ;return pci_bus_read_config_dword (bus, devfn, offset, value); }
@@ -253,7 +253,7 @@ static int PCI_GetBusDevHelper(struct controller *ctrl, u8 *bus_num, u8 *dev_num *dev_num = tdevice; ctrl->pci_bus->number = tbus;pci_bus_read_config_dword (ctrl->pci_bus, *dev_num,PCI_VENDOR_ID , &work); -if (!nobridge || (work ==0xffffffff )) +if (!nobridge ||PCI_POSSIBLE_ERROR (work))return 0 ;dbg ("bus_num %d devfn %d\n" , *bus_num, *dev_num);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 352/676 PCI: cpqphp: Fix PCIBIOS_* return value confusion
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilpo Järvinen <[email protected]>
[ Upstream commit e2226dbc4a4919d9c8bd9293299b532090bdf020 ]
Code in and related to PCI_RefinedAccessConfig() has three types of return type confusion:
- PCI_RefinedAccessConfig() tests pci_bus_read_config_dword() return value against -1.
- PCI_RefinedAccessConfig() returns both -1 and PCIBIOS_* return codes.
- Callers of PCI_RefinedAccessConfig() only test for -1.
Make PCI_RefinedAccessConfig() return PCIBIOS_* codes consistently and adapt callers accordingly.
--- drivers/pci/hotplug/cpqphp_pci.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
drivers/pci/hotplug/cpqphp_pci.c +10 -5
@@ -135,11 +135,13 @@ int cpqhp_unconfigure_device(struct pci_func *func)static int PCI_RefinedAccessConfig (struct pci_bus *bus,unsigned int devfn,u8 offset,u32 *value) {u32 vendID =0 ; +int ret; -if (pci_bus_read_config_dword (bus, devfn,PCI_VENDOR_ID , &vendID) ==-1 ) -return -1 ; + ret =pci_bus_read_config_dword (bus, devfn,PCI_VENDOR_ID , &vendID); +if (ret !=PCIBIOS_SUCCESSFUL ) +return PCIBIOS_DEVICE_NOT_FOUND ;if (PCI_POSSIBLE_ERROR (vendID)) -return -1 ; +return PCIBIOS_DEVICE_NOT_FOUND ;return pci_bus_read_config_dword (bus, devfn, offset, value); }
@@ -202,13 +204,15 @@ static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 *dev_ {u16 tdevice;u32 work; +int ret;u8 tbus; ctrl->pci_bus->number = bus_num;for (tdevice =0 ; tdevice <0xFF ; tdevice++) {/* Scan for access first */ -if (PCI_RefinedAccessConfig (ctrl->pci_bus, tdevice,0x08 , &work) ==-1 ) + ret =PCI_RefinedAccessConfig (ctrl->pci_bus, tdevice,0x08 , &work); +if (ret)continue ;dbg ("Looking for nonbridge bus_num %d dev_num %d\n" , bus_num, tdevice);/* Yep we got one. Not a bridge ? */
@@ -220,7 +224,8 @@ static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 *dev_ }for (tdevice =0 ; tdevice <0xFF ; tdevice++) {/* Scan for access first */ -if (PCI_RefinedAccessConfig (ctrl->pci_bus, tdevice,0x08 , &work) ==-1 ) + ret =PCI_RefinedAccessConfig (ctrl->pci_bus, tdevice,0x08 , &work); +if (ret)continue ;dbg ("Looking for bridge bus_num %d dev_num %d\n" , bus_num, tdevice);/* Yep we got one. bridge ? */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 353/676 perf ftrace latency: Fix unit on histogram first entry when using --use-nsec
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnaldo Carvalho de Melo <[email protected]>
[ Upstream commit 064d569e20e82c065b1dec9d20c29c7087bb1a00 ]
The use_nsec arg wasn't being taken into account when printing the first histogram entry, fix it:
root@number:~# perf ftrace latency --use-nsec -T switch_mm_irqs_off -a sleep 2
# DURATION | COUNT | GRAPH |
0 - 1 us | 0 | |
1 - 2 ns | 0 | |
2 - 4 ns | 0 | |
4 - 8 ns | 0 | |
8 - 16 ns | 0 | |
16 - 32 ns | 0 | |
32 - 64 ns | 125 | |
64 - 128 ns | 335 | |
128 - 256 ns | 2155 | #### |
256 - 512 ns | 9996 | ################### |
512 - 1024 ns | 4958 | ######### |
1 - 2 us | 4636 | ######### |
2 - 4 us | 1053 | ## |
4 - 8 us | 15 | |
8 - 16 us | 1 | |
16 - 32 us | 0 | |
32 - 64 us | 0 | |
64 - 128 us | 0 | |
128 - 256 us | 0 | |
256 - 512 us | 0 | |
512 - 1024 us | 0 | |
1 - ... ms | 0 | |
root@number:~#After:
root@number:~# perf ftrace latency --use-nsec -T switch_mm_irqs_off -a sleep 2
# DURATION | COUNT | GRAPH |
0 - 1 ns | 0 | |
1 - 2 ns | 0 | |
2 - 4 ns | 0 | |
4 - 8 ns | 0 | |
8 - 16 ns | 0 | |
16 - 32 ns | 0 | |
32 - 64 ns | 19 | |
64 - 128 ns | 94 | |
128 - 256 ns | 2191 | #### |
256 - 512 ns | 9719 | #################### |
512 - 1024 ns | 5330 | ########### |
1 - 2 us | 4104 | ######## |
2 - 4 us | 807 | # |
4 - 8 us | 9 | |
8 - 16 us | 0 | |
16 - 32 us | 0 | |
32 - 64 us | 0 | |
64 - 128 us | 0 | |
128 - 256 us | 0 | |
256 - 512 us | 0 | |
512 - 1024 us | 0 | |
1 - ... ms | 0 | |
root@number:~#--- tools/perf/builtin-ftrace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/builtin-ftrace.c +1 -1
@@ -771,7 +771,7 @@ static void display_histogram(int buckets[], bool use_nsec) bar_len = buckets[0 ] * bar_total / total;printf (" %4d - %-4d %s | %10d | %.*s%*s |\n" , -0 ,1 ,"us" , buckets[0 ], bar_len, bar, bar_total - bar_len,"" ); +0 ,1 , use_nsec ?"ns" :"us" , buckets[0 ], bar_len, bar, bar_total - bar_len,"" );for (i =1 ; i <NUM_BUCKET -1 ; i++) {int start = (1 << (i -1 ));
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 354/676 f2fs: fix the wrong f2fs_bug_on condition in f2fs_do_replace_block
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: LongPing Wei <[email protected]>
[ Upstream commit c3af1f13476ec23fd99c98d060a89be28c1e8871 ]
This f2fs_bug_on was introduced by commit 2c1905042c8c ("f2fs: check segment type in __f2fs_replace_block") when there were only 6 curseg types. After commit d0b9e42ab615 ("f2fs: introduce inmem curseg") was introduced, the condition should be changed to checking curseg->seg_type.
--- fs/f2fs/segment.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/f2fs/segment.c +1 -1
@@ -3757,8 +3757,8 @@ void f2fs_do_replace_block(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, } } -f2fs_bug_on (sbi, !IS_DATASEG (type)); curseg =CURSEG_I (sbi, type); +f2fs_bug_on (sbi, !IS_DATASEG (curseg->seg_type));mutex_lock (&curseg->curseg_mutex);down_write (&sit_i->sentry_lock);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 355/676 f2fs: check curseg->inited before write_sum_page in change_curseg
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yongpeng Yang <[email protected]>
[ Upstream commit 43563069e1c1df417d2eed6eca8a22fc6b04691d ]
In the __f2fs_init_atgc_curseg->get_atssr_segment calling, curseg->segno is NULL_SEGNO, indicating that there is no summary block that needs to be written.
--- fs/f2fs/segment.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/f2fs/segment.c +2 -1
@@ -2848,7 +2848,8 @@ static void change_curseg(struct f2fs_sb_info *sbi, int type)struct f2fs_summary_block *sum_node;struct page *sum_page; -write_sum_page (sbi, curseg->sum_blk,GET_SUM_BLOCK (sbi, curseg->segno)); +if (curseg->inited) +write_sum_page (sbi, curseg->sum_blk,GET_SUM_BLOCK (sbi, curseg->segno));__set_test_and_inuse (sbi, new_segno);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 356/676 f2fs: fix to avoid potential deadlock in f2fs_record_stop_reason()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <[email protected]>
[ Upstream commit f10a890308a7cd8794e21f646f09827c6cb4bf5d ]
syzbot reports deadlock issue of f2fs as below:
======================================================
WARNING: possible circular locking dependency detected 6.12.0-rc3-syzkaller-00087-gc964ced77262 #0 Not tainted
------------------------------------------------------
kswapd0/79 is trying to acquire lock:ffff888011824088 (&sbi->sb_lock){++++}-{3:3}, at: f2fs_down_write fs/f2fs/f2fs.h:2199 [inline] ffff888011824088 (&sbi->sb_lock){++++}-{3:3}, at: f2fs_record_stop_reason+0x52/0x1d0 fs/f2fs/super.c:4068
but task is already holding lock:ffff88804bd92610 (sb_internal#2){.+.+}-{0:0}, at: f2fs_evict_inode+0x662/0x15c0 fs/f2fs/inode.c:842
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #2 (sb_internal#2){.+.+}-{0:0}:
lock_acquire+0x1ed/0x550 kernel/locking/lockdep.c:5825
percpu_down_read include/linux/percpu-rwsem.h:51 [inline]
__sb_start_write include/linux/fs.h:1716 [inline]
sb_start_intwrite+0x4d/0x1c0 include/linux/fs.h:1899
f2fs_evict_inode+0x662/0x15c0 fs/f2fs/inode.c:842
evict+0x4e8/0x9b0 fs/inode.c:725
f2fs_evict_inode+0x1a4/0x15c0 fs/f2fs/inode.c:807
evict+0x4e8/0x9b0 fs/inode.c:725
dispose_list fs/inode.c:774 [inline]
prune_icache_sb+0x239/0x2f0 fs/inode.c:963
super_cache_scan+0x38c/0x4b0 fs/super.c:223
do_shrink_slab+0x701/0x1160 mm/shrinker.c:435
shrink_slab+0x1093/0x14d0 mm/shrinker.c:662
shrink_one+0x43b/0x850 mm/vmscan.c:4818
shrink_many mm/vmscan.c:4879 [inline]
lru_gen_shrink_node mm/vmscan.c:4957 [inline]
shrink_node+0x3799/0x3de0 mm/vmscan.c:5937
kswapd_shrink_node mm/vmscan.c:6765 [inline]
balance_pgdat mm/vmscan.c:6957 [inline]
kswapd+0x1ca3/0x3700 mm/vmscan.c:7226
kthread+0x2f0/0x390 kernel/kthread.c:389
ret_from_fork+0x4b/0x80 arch/x86/kernel/process.c:147
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244-> #1 (fs_reclaim){+.+.}-{0:0}:
lock_acquire+0x1ed/0x550 kernel/locking/lockdep.c:5825
__fs_reclaim_acquire mm/page_alloc.c:3834 [inline]
fs_reclaim_acquire+0x88/0x130 mm/page_alloc.c:3848
might_alloc include/linux/sched/mm.h:318 [inline]
prepare_alloc_pages+0x147/0x5b0 mm/page_alloc.c:4493
__alloc_pages_noprof+0x16f/0x710 mm/page_alloc.c:4722
alloc_pages_mpol_noprof+0x3e8/0x680 mm/mempolicy.c:2265
alloc_pages_noprof mm/mempolicy.c:2345 [inline]
folio_alloc_noprof+0x128/0x180 mm/mempolicy.c:2352
filemap_alloc_folio_noprof+0xdf/0x500 mm/filemap.c:1010
do_read_cache_folio+0x2eb/0x850 mm/filemap.c:3787
read_mapping_folio include/linux/pagemap.h:1011 [inline]
f2fs_commit_super+0x3c0/0x7d0 fs/f2fs/super.c:4032
f2fs_record_stop_reason+0x13b/0x1d0 fs/f2fs/super.c:4079
f2fs_handle_critical_error+0x2ac/0x5c0 fs/f2fs/super.c:4174
f2fs_write_inode+0x35f/0x4d0 fs/f2fs/inode.c:785
write_inode fs/fs-writeback.c:1503 [inline]
__writeback_single_inode+0x711/0x10d0 fs/fs-writeback.c:1723
writeback_single_inode+0x1f3/0x660 fs/fs-writeback.c:1779
sync_inode_metadata+0xc4/0x120 fs/fs-writeback.c:2849
f2fs_release_file+0xa8/0x100 fs/f2fs/file.c:1941
__fput+0x23f/0x880 fs/file_table.c:431
task_work_run+0x24f/0x310 kernel/task_work.c:228
resume_user_mode_work include/linux/resume_user_mode.h:50 [inline]
exit_to_user_mode_loop kernel/entry/common.c:114 [inline]
exit_to_user_mode_prepare include/linux/entry-common.h:328 [inline]
__syscall_exit_to_user_mode_work kernel/entry/common.c:207 [inline]
syscall_exit_to_user_mode+0x168/0x370 kernel/entry/common.c:218
do_syscall_64+0x100/0x230 arch/x86/entry/common.c:89
entry_SYSCALL_64_after_hwframe+0x77/0x7f-> #0 (&sbi->sb_lock){++++}-{3:3}:
check_prev_add kernel/locking/lockdep.c:3161 [inline]
check_prevs_add kernel/locking/lockdep.c:3280 [inline]
validate_chain+0x18ef/0x5920 kernel/locking/lockdep.c:3904
__lock_acquire+0x1384/0x2050 kernel/locking/lockdep.c:5202
lock_acquire+0x1ed/0x550 kernel/locking/lockdep.c:5825
down_write+0x99/0x220 kernel/locking/rwsem.c:1577
f2fs_down_write fs/f2fs/f2fs.h:2199 [inline]
f2fs_record_stop_reason+0x52/0x1d0 fs/f2fs/super.c:4068
f2fs_handle_critical_error+0x2ac/0x5c0 fs/f2fs/super.c:4174
f2fs_evict_inode+0xa61/0x15c0 fs/f2fs/inode.c:883
evict+0x4e8/0x9b0 fs/inode.c:725
f2fs_evict_inode+0x1a4/0x15c0 fs/f2fs/inode.c:807
evict+0x4e8/0x9b0 fs/inode.c:725
dispose_list fs/inode.c:774 [inline]
prune_icache_sb+0x239/0x2f0 fs/inode.c:963
super_cache_scan+0x38c/0x4b0 fs/super.c:223
do_shrink_slab+0x701/0x1160 mm/shrinker.c:435
shrink_slab+0x1093/0x14d0 mm/shrinker.c:662
shrink_one+0x43b/0x850 mm/vmscan.c:4818
shrink_many mm/vmscan.c:4879 [inline]
lru_gen_shrink_node mm/vmscan.c:4957 [inline]
shrink_node+0x3799/0x3de0 mm/vmscan.c:5937
kswapd_shrink_node mm/vmscan.c:6765 [inline]
balance_pgdat mm/vmscan.c:6957 [inline]
kswapd+0x1ca3/0x3700 mm/vmscan.c:7226
kthread+0x2f0/0x390 kernel/kthread.c:389
ret_from_fork+0x4b/0x80 arch/x86/kernel/process.c:147
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244other info that might help us debug this:
Chain exists of: &sbi->sb_lock --> fs_reclaim --> sb_internal#2 Possible unsafe locking scenario:
CPU0 CPU1
---- ----
rlock(sb_internal#2);
lock(fs_reclaim);
lock(sb_internal#2); lock(&sbi->sb_lock);
Root cause is there will be potential deadlock in between below tasks:
Thread A Kswapd
- f2fs_ioc_commit_atomic_write
- mnt_want_write_file -- down_read lock A
- balance_pgdat
- __fs_reclaim_acquire -- lock B
- shrink_node
- prune_icache_sb
- dispose_list
- f2fs_evict_inode
- sb_start_intwrite -- down_read lock A
- f2fs_do_sync_file
- f2fs_write_inode
- f2fs_handle_critical_error
- f2fs_record_stop_reason
- f2fs_commit_super
- read_mapping_folio
- filemap_alloc_folio_noprof
- fs_reclaim_acquire -- lock B
Both threads try to acquire read lock of lock A, then its upcoming write lock grabber will trigger deadlock.
Let's always create an asynchronous task in f2fs_handle_critical_error() rather than calling f2fs_record_stop_reason() synchronously to avoid this potential deadlock issue.
--- fs/f2fs/checkpoint.c | 2 +- fs/f2fs/f2fs.h | 3 +-- fs/f2fs/super.c | 13 +++++++------ 3 files changed, 9 insertions(+), 9 deletions(-)
fs/f2fs/checkpoint.c +1 -1
@@ -32,7 +32,7 @@ void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io,f2fs_build_fault_attr (sbi,0 ,0 );if (!end_io)f2fs_flush_merged_writes (sbi); -f2fs_handle_critical_error (sbi, reason, end_io); +f2fs_handle_critical_error (sbi, reason); }/*
fs/f2fs/f2fs.h +1 -2
@@ -3588,8 +3588,7 @@ int f2fs_quota_sync(struct super_block *sb, int type);loff_t max_file_blocks (struct inode *inode);void f2fs_quota_off_umount (struct super_block *sb);void f2fs_save_errors (struct f2fs_sb_info *sbi,unsigned char flag); -void f2fs_handle_critical_error (struct f2fs_sb_info *sbi,unsigned char reason, -bool irq_context); +void f2fs_handle_critical_error (struct f2fs_sb_info *sbi,unsigned char reason);void f2fs_handle_error (struct f2fs_sb_info *sbi,unsigned char error);void f2fs_handle_error_async (struct f2fs_sb_info *sbi,unsigned char error);int f2fs_commit_super (struct f2fs_sb_info *sbi,bool recover);
fs/f2fs/super.c +7 -6
@@ -4093,8 +4093,7 @@ static bool system_going_down(void) || system_state == SYSTEM_RESTART; } -void f2fs_handle_critical_error (struct f2fs_sb_info *sbi,unsigned char reason, -bool irq_context) +void f2fs_handle_critical_error (struct f2fs_sb_info *sbi,unsigned char reason) {struct super_block *sb = sbi->sb;bool shutdown = reason ==STOP_CP_REASON_SHUTDOWN ;
@@ -4106,10 +4105,12 @@ void f2fs_handle_critical_error(struct f2fs_sb_info *sbi, unsigned char reason,if (!f2fs_hw_is_readonly (sbi)) {save_stop_reason (sbi, reason); -if (irq_context && !shutdown) -schedule_work (&sbi->s_error_work); -else -f2fs_record_stop_reason (sbi); +/* +* always create an asynchronous task to record stop_reason +* in order to avoid potential deadlock when running into +* f2fs_record_stop_reason() synchronously. +*/ +schedule_work (&sbi->s_error_work); }/*
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 357/676 f2fs: fix to avoid use GC_AT when setting gc_mode as GC_URGENT_LOW or GC_URGENT_MID
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhiguo Niu <[email protected]>
[ Upstream commit 296b8cb34e65fa93382cf919be5a056f719c9a26 ]
If gc_mode is set to GC_URGENT_LOW or GC_URGENT_MID, cost benefit GC approach should be used, but if ATGC is enabled at the same time, Age-threshold approach will be selected, which can only do amount of GC and it is much less than the numbers of CB approach.
some traces:
f2fs_gc-254:48-396 [007] ..... 2311600.684028: f2fs_gc_begin: dev = (254,48), gc_type = Background GC, no_background_GC = 0, nr_free_secs = 0, nodes = 1053, dents = 2, imeta = 18, free_sec:44898, free_seg:44898, rsv_seg:239, prefree_seg:0 f2fs_gc-254:48-396 [007] ..... 2311600.684527: f2fs_get_victim: dev = (254,48), type = No TYPE, policy = (Background GC, LFS-mode, Age-threshold), victim = 10, cost = 4294364975, ofs_unit = 1, pre_victim_secno = -1, prefree = 0, free = 44898 f2fs_gc-254:48-396 [007] ..... 2311600.714835: f2fs_gc_end: dev = (254,48), ret = 0, seg_freed = 0, sec_freed = 0, nodes = 1562, dents = 2, imeta = 18, free_sec:44898, free_seg:44898, rsv_seg:239, prefree_seg:0 f2fs_gc-254:48-396 [007] ..... 2311600.714843: f2fs_background_gc: dev = (254,48), wait_ms = 50, prefree = 0, free = 44898 f2fs_gc-254:48-396 [007] ..... 2311600.771785: f2fs_gc_begin: dev = (254,48), gc_type = Background GC, no_background_GC = 0, nr_free_secs = 0, nodes = 1562, dents = 2, imeta = 18, free_sec:44898, free_seg:44898, rsv_seg:239, prefree_seg: f2fs_gc-254:48-396 [007] ..... 2311600.772275: f2fs_gc_end: dev = (254,48), ret = -61, seg_freed = 0, sec_freed = 0, nodes = 1562, dents = 2, imeta = 18, free_sec:44898, free_seg:44898, rsv_seg:239, prefree_seg:0
--- Documentation/ABI/testing/sysfs-fs-f2fs | 7 +++++-- fs/f2fs/gc.c | 2 ++ 2 files changed, 7 insertions(+), 2 deletions(-)
Documentation/ABI/testing/sysfs-fs-f2fs +5 -2
@@ -311,10 +311,13 @@ Description: Do background GC aggressively when set. Set to 0 by default. GC approach and turns SSR mode on. gc urgent low(2): lowers the bar of checking I/O idling in order to process outstanding discard commands and GC a - little bit aggressively. uses cost benefit GC approach. + little bit aggressively. always uses cost benefit GC approach, + and will override age-threshold GC approach if ATGC is enabled + at the same time. gc urgent mid(3): does GC forcibly in a period of given gc_urgent_sleep_time and executes a mid level of I/O idling check. - uses cost benefit GC approach. + always uses cost benefit GC approach, and will override + age-threshold GC approach if ATGC is enabled at the same time. What: /sys/fs/f2fs/<disk>/gc_urgent_sleep_time Date: August 2017
fs/f2fs/gc.c +2 -0
@@ -228,6 +228,8 @@ static int select_gc_type(struct f2fs_sb_info *sbi, int gc_type)switch (sbi->gc_mode) {case GC_IDLE_CB : +case GC_URGENT_LOW : +case GC_URGENT_MID : gc_mode =GC_CB ;break ;case GC_IDLE_GREEDY :
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 358/676 PCI: Add T_PVPERL macro
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yoshihiro Shimoda <[email protected]>
[ Upstream commit 164f66be0c2523e65df41b755c41b7c9ff58035a ]
According to the PCIe CEM r5.0, sec 2.9.2, Power stable to PERST# inactive interval is 100 ms as minimum. Add a macro so that the PCIe controller drivers can make use of it.
Stable-dep-of: 22a9120479a4 ("PCI: j721e: Deassert PERST# after a delay of PCIE_T_PVPERL_MS milliseconds")
--- drivers/pci/pci.h | 3 +++ 1 file changed, 3 insertions(+)
drivers/pci/pci.h +3 -0
@@ -13,6 +13,9 @@#define PCIE_LINK_RETRAIN_TIMEOUT_MS 1000 +/* Power stable to PERST# inactive from PCIe card Electromechanical Spec */ +#define PCIE_T_PVPERL_MS 100 +/* * PCIe r6.0, sec 5.3.3.2.1 <PME Synchronization> * Recommends 1ms to 10ms timeout to check L2 ready.
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 359/676 PCI: j721e: Add per platform maximum lane settings
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matt Ranostay <[email protected]>
[ Upstream commit 3ac7f14084f54bff9c31573d1ed59d047a34fe03 ]
Various platforms have different maximum amount of lanes that can be selected. Add max_lanes to struct j721e_pcie to allow for detection of this which is needed to calculate the needed bitmask size for the possible lane count.
Stable-dep-of: 22a9120479a4 ("PCI: j721e: Deassert PERST# after a delay of PCIE_T_PVPERL_MS milliseconds")
--- drivers/pci/controller/cadence/pci-j721e.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
drivers/pci/controller/cadence/pci-j721e.c +10 -3
@@ -47,8 +47,6 @@ enum link_status {#define GENERATION_SEL_MASK GENMASK(1, 0) -#define MAX_LANES 2 -struct j721e_pcie {struct cdns_pcie *cdns_pcie;struct clk *refclk;
@@ -71,6 +69,7 @@ struct j721e_pcie_data { unsigned int quirk_disable_flr:1;u32 linkdown_irq_regfield; unsigned int byte_access_allowed:1; +unsigned int max_lanes; };static inline u32 j721e_pcie_user_readl (struct j721e_pcie *pcie,u32 offset)
@@ -290,11 +289,13 @@ static const struct j721e_pcie_data j721e_pcie_rc_data = { .quirk_retrain_flag = true, .byte_access_allowed = false, .linkdown_irq_regfield = LINK_DOWN, + .max_lanes = 2, };static const struct j721e_pcie_data j721e_pcie_ep_data = { .mode =PCI_MODE_EP , .linkdown_irq_regfield =LINK_DOWN , + .max_lanes =2 , };static const struct j721e_pcie_data j7200_pcie_rc_data = {
@@ -302,23 +303,27 @@ static const struct j721e_pcie_data j7200_pcie_rc_data = { .quirk_detect_quiet_flag = true, .linkdown_irq_regfield = J7200_LINK_DOWN, .byte_access_allowed = true, + .max_lanes = 2, };static const struct j721e_pcie_data j7200_pcie_ep_data = { .mode =PCI_MODE_EP , .quirk_detect_quiet_flag = true, .quirk_disable_flr = true, + .max_lanes =2 , };static const struct j721e_pcie_data am64_pcie_rc_data = { .mode =PCI_MODE_RC , .linkdown_irq_regfield =J7200_LINK_DOWN , .byte_access_allowed = true, + .max_lanes =1 , };static const struct j721e_pcie_data am64_pcie_ep_data = { .mode =PCI_MODE_EP , .linkdown_irq_regfield =J7200_LINK_DOWN , + .max_lanes =1 , };static const struct of_device_id of_j721e_pcie_match[] = {
@@ -432,8 +437,10 @@ static int j721e_pcie_probe(struct platform_device *pdev) pcie->user_cfg_base = base; ret =of_property_read_u32 (node,"num-lanes" , &num_lanes); -if (ret || num_lanes >MAX_LANES ) +if (ret || num_lanes > data->max_lanes) { +dev_warn (dev,"num-lanes property not provided or invalid, setting num-lanes to 1\n" ); num_lanes =1 ; + } pcie->num_lanes = num_lanes;if (dma_set_mask_and_coherent (dev,DMA_BIT_MASK (48 )))
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 360/676 PCI: j721e: Add PCIe 4x lane selection support
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matt Ranostay <[email protected]>
[ Upstream commit 4490f559f75514d5a6f0e729e85235a7be6216bf ]
Add support for setting of two-bit field that allows selection of 4x lane PCIe which was previously limited to only 2x lanes.
Stable-dep-of: 22a9120479a4 ("PCI: j721e: Deassert PERST# after a delay of PCIE_T_PVPERL_MS milliseconds")
--- drivers/pci/controller/cadence/pci-j721e.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
drivers/pci/controller/cadence/pci-j721e.c +8 -2
@@ -42,7 +42,6 @@ enum link_status { };#define J721E_MODE_RC BIT(7) -#define LANE_COUNT_MASK BIT(8)#define LANE_COUNT (n) ((n) << 8)#define GENERATION_SEL_MASK GENMASK(1, 0)
@@ -52,6 +51,7 @@ struct j721e_pcie {struct clk *refclk;u32 mode;u32 num_lanes; +u32 max_lanes;void __iomem *user_cfg_base;void __iomem *intd_cfg_base;u32 linkdown_irq_regfield;
@@ -205,11 +205,15 @@ static int j721e_pcie_set_lane_count(struct j721e_pcie *pcie, {struct device *dev = pcie->cdns_pcie->dev;u32 lanes = pcie->num_lanes; +u32 mask =BIT (8 );u32 val =0 ;int ret; +if (pcie->max_lanes ==4 ) + mask =GENMASK (9 ,8 ); + val =LANE_COUNT (lanes -1 ); - ret =regmap_update_bits (syscon, offset,LANE_COUNT_MASK , val); + ret =regmap_update_bits (syscon, offset, mask, val);if (ret)dev_err (dev,"failed to set link count\n" );
@@ -441,7 +445,9 @@ static int j721e_pcie_probe(struct platform_device *pdev)dev_warn (dev,"num-lanes property not provided or invalid, setting num-lanes to 1\n" ); num_lanes =1 ; } + pcie->num_lanes = num_lanes; + pcie->max_lanes = data->max_lanes;if (dma_set_mask_and_coherent (dev,DMA_BIT_MASK (48 )))return -EINVAL ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 361/676 PCI: cadence: Extract link setup sequence from cdns_pcie_host_setup()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Richard <[email protected]>
[ Upstream commit d1b6f2e2ce4d8b17d9f3558c98a1517b864bfd03 ]
The function cdns_pcie_host_setup() mixes probe structure and link setup.
The link setup must be done during the resume sequence. So extract it from cdns_pcie_host_setup() and create a dedicated function.
Stable-dep-of: 22a9120479a4 ("PCI: j721e: Deassert PERST# after a delay of PCIE_T_PVPERL_MS milliseconds")
--- .../controller/cadence/pcie-cadence-host.c | 39 ++++++++++++------- drivers/pci/controller/cadence/pcie-cadence.h | 6 +++ 2 files changed, 32 insertions(+), 13 deletions(-)
drivers/pci/controller/cadence/pcie-cadence-host.c +26 -13
@@ -497,6 +497,30 @@ static int cdns_pcie_host_init(struct device *dev,return cdns_pcie_host_init_address_translation (rc); } +int cdns_pcie_host_link_setup (struct cdns_pcie_rc *rc) +{ +struct cdns_pcie *pcie = &rc->pcie; +struct device *dev = rc->pcie.dev; +int ret; + +if (rc->quirk_detect_quiet_flag) +cdns_pcie_detect_quiet_min_delay_set (&rc->pcie); + +cdns_pcie_host_enable_ptm_response (pcie); + + ret =cdns_pcie_start_link (pcie); +if (ret) { +dev_err (dev,"Failed to start link\n" ); +return ret; + } + + ret =cdns_pcie_host_start_link (rc); +if (ret) +dev_dbg (dev,"PCIe link never came up\n" ); + +return 0 ; +} +int cdns_pcie_host_setup (struct cdns_pcie_rc *rc) {struct device *dev = rc->pcie.dev;
@@ -533,20 +557,9 @@ int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)return PTR_ERR (rc->cfg_base); rc->cfg_res = res; -if (rc->quirk_detect_quiet_flag) -cdns_pcie_detect_quiet_min_delay_set (&rc->pcie); - -cdns_pcie_host_enable_ptm_response (pcie); - - ret =cdns_pcie_start_link (pcie); -if (ret) { -dev_err (dev,"Failed to start link\n" ); -return ret; - } - - ret =cdns_pcie_host_start_link (rc); + ret =cdns_pcie_host_link_setup (rc);if (ret) -dev_dbg (dev,"PCIe link never came up\n" ); +return ret;for (bar =RP_BAR0 ; bar <=RP_NO_BAR ; bar++) rc->avail_ib_bar[bar] = true;
drivers/pci/controller/cadence/pcie-cadence.h +6 -0
@@ -515,10 +515,16 @@ static inline bool cdns_pcie_link_up(struct cdns_pcie *pcie) }#ifdef CONFIG_PCIE_CADENCE_HOST +int cdns_pcie_host_link_setup (struct cdns_pcie_rc *rc);int cdns_pcie_host_setup (struct cdns_pcie_rc *rc);void __iomem *cdns_pci_map_bus (struct pci_bus *bus,unsigned int devfn,int where);#else +static inline int cdns_pcie_host_link_setup (struct cdns_pcie_rc *rc) +{ +return 0 ; +} +static inline int cdns_pcie_host_setup (struct cdns_pcie_rc *rc) {return 0 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 362/676 PCI: cadence: Set cdns_pcie_host_init() global
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Richard <[email protected]>
[ Upstream commit 063c938928dc80c2bfd66f34df48344db22e009b ]
During the resume sequence of the host, cdns_pcie_host_init() needs to be called, so set it global.
The dev function parameter is removed, as it isn't used.
Stable-dep-of: 22a9120479a4 ("PCI: j721e: Deassert PERST# after a delay of PCIE_T_PVPERL_MS milliseconds")
--- drivers/pci/controller/cadence/pcie-cadence-host.c | 5 ++--- drivers/pci/controller/cadence/pcie-cadence.h | 6 ++++++ 2 files changed, 8 insertions(+), 3 deletions(-)
drivers/pci/controller/cadence/pcie-cadence-host.c +2 -3
@@ -485,8 +485,7 @@ static int cdns_pcie_host_init_address_translation(struct cdns_pcie_rc *rc)return cdns_pcie_host_map_dma_ranges (rc); } -static int cdns_pcie_host_init (struct device *dev, -struct cdns_pcie_rc *rc) +int cdns_pcie_host_init (struct cdns_pcie_rc *rc) {int err;
@@ -564,7 +563,7 @@ int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)for (bar =RP_BAR0 ; bar <=RP_NO_BAR ; bar++) rc->avail_ib_bar[bar] = true; - ret =cdns_pcie_host_init (dev, rc); + ret =cdns_pcie_host_init (rc);if (ret)return ret;
drivers/pci/controller/cadence/pcie-cadence.h +6 -0
@@ -516,6 +516,7 @@ static inline bool cdns_pcie_link_up(struct cdns_pcie *pcie)#ifdef CONFIG_PCIE_CADENCE_HOST int cdns_pcie_host_link_setup (struct cdns_pcie_rc *rc); +int cdns_pcie_host_init (struct cdns_pcie_rc *rc);int cdns_pcie_host_setup (struct cdns_pcie_rc *rc);void __iomem *cdns_pci_map_bus (struct pci_bus *bus,unsigned int devfn,int where);
@@ -525,6 +526,11 @@ static inline int cdns_pcie_host_link_setup(struct cdns_pcie_rc *rc)return 0 ; } +static inline int cdns_pcie_host_init (struct cdns_pcie_rc *rc) +{ +return 0 ; +} +static inline int cdns_pcie_host_setup (struct cdns_pcie_rc *rc) {return 0 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 363/676 PCI: j721e: Add reset GPIO to struct j721e_pcie
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Théo Lebrun <[email protected]>
[ Upstream commit b8600b8791cb2b7c8be894846b1ecddba7291680 ]
Add reset GPIO to struct j721e_pcie, so it can be used at suspend and resume stages.
Stable-dep-of: 22a9120479a4 ("PCI: j721e: Deassert PERST# after a delay of PCIE_T_PVPERL_MS milliseconds")
--- drivers/pci/controller/cadence/pci-j721e.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/pci/controller/cadence/pci-j721e.c +2 -0
@@ -52,6 +52,7 @@ struct j721e_pcie {u32 mode;u32 num_lanes;u32 max_lanes; +struct gpio_desc *reset_gpio;void __iomem *user_cfg_base;void __iomem *intd_cfg_base;u32 linkdown_irq_regfield;
@@ -488,6 +489,7 @@ static int j721e_pcie_probe(struct platform_device *pdev)dev_err (dev,"Failed to get reset GPIO\n" ); goto err_get_sync; } + pcie->reset_gpio = gpiod; ret =cdns_pcie_init_phy (dev, cdns_pcie);if (ret) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 364/676 PCI: j721e: Use T_PERST_CLK_US macro
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Richard <[email protected]>
[ Upstream commit f96b6971373382855bc964f1c067bd6dc41cf0ab ]
Use the T_PERST_CLK_US macro, and the fsleep() function instead of usleep_range().
Stable-dep-of: 22a9120479a4 ("PCI: j721e: Deassert PERST# after a delay of PCIE_T_PVPERL_MS milliseconds")
--- drivers/pci/controller/cadence/pci-j721e.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pci/controller/cadence/pci-j721e.c +1 -1
@@ -520,7 +520,7 @@ static int j721e_pcie_probe(struct platform_device *pdev)* after 100 us. */ if (gpiod) { -usleep_range (100 ,200 ); +fsleep (PCIE_T_PERST_CLK_US );gpiod_set_value_cansleep (gpiod,1 ); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 365/676 PCI: j721e: Add suspend and resume support
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Théo Lebrun <[email protected]>
[ Upstream commit c538d40f365b5b6d7433d371710f58e8b266fb19 ]
Add suspend and resume support. Only the Root Complex mode is supported.
During the suspend stage PERST# is asserted, then deasserted during the resume stage.
Stable-dep-of: 22a9120479a4 ("PCI: j721e: Deassert PERST# after a delay of PCIE_T_PVPERL_MS milliseconds")
--- drivers/pci/controller/cadence/pci-j721e.c | 98 ++++++++++++++++++++-- 1 file changed, 92 insertions(+), 6 deletions(-)
drivers/pci/controller/cadence/pci-j721e.c +92 -6
@@ -7,6 +7,8 @@*/ #include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/container_of.h> #include <linux/delay.h> #include <linux/gpio/consumer.h> #include <linux/io.h>
@@ -22,6 +24,8 @@#include "../../pci.h" #include "pcie-cadence.h" +#define cdns_pcie_to_rc (p) container_of(p, struct cdns_pcie_rc, pcie) +#define ENABLE_REG_SYS_2 0x108#define STATUS_REG_SYS_2 0x508#define STATUS_CLR_REG_SYS_2 0x708
@@ -512,12 +516,12 @@ static int j721e_pcie_probe(struct platform_device *pdev) pcie->refclk = clk;/* -* "Power Sequencing and Reset Signal Timings" table in -* PCI EXPRESS CARD ELECTROMECHANICAL SPECIFICATION, REV. 3.0 -* indicates PERST# should be deasserted after minimum of 100us -* once REFCLK is stable. The REFCLK to the connector in RC -* mode is selected while enabling the PHY. So deassert PERST# -* after 100 us. +* The "Power Sequencing and Reset Signal Timings" table of the +* PCI Express Card Electromechanical Specification, Revision +* 5.1, Section 2.9.2, Symbol "T_PERST-CLK", indicates PERST# +* should be deasserted after minimum of 100us once REFCLK is +* stable. The REFCLK to the connector in RC mode is selected +* while enabling the PHY. So deassert PERST# after 100 us. */ if (gpiod) {fsleep (PCIE_T_PERST_CLK_US );
@@ -569,6 +573,87 @@ static void j721e_pcie_remove(struct platform_device *pdev)pm_runtime_disable (dev); } +static int j721e_pcie_suspend_noirq (struct device *dev) +{ +struct j721e_pcie *pcie =dev_get_drvdata (dev); + +if (pcie->mode ==PCI_MODE_RC ) { +gpiod_set_value_cansleep (pcie->reset_gpio,0 ); +clk_disable_unprepare (pcie->refclk); + } + +cdns_pcie_disable_phy (pcie->cdns_pcie); + +return 0 ; +} + +static int j721e_pcie_resume_noirq (struct device *dev) +{ +struct j721e_pcie *pcie =dev_get_drvdata (dev); +struct cdns_pcie *cdns_pcie = pcie->cdns_pcie; +int ret; + + ret =j721e_pcie_ctrl_init (pcie); +if (ret <0 ) +return ret; + +j721e_pcie_config_link_irq (pcie); + +/* +* This is not called explicitly in the probe, it is called by +* cdns_pcie_init_phy(). +*/ + ret =cdns_pcie_enable_phy (pcie->cdns_pcie); +if (ret <0 ) +return ret; + +if (pcie->mode ==PCI_MODE_RC ) { +struct cdns_pcie_rc *rc =cdns_pcie_to_rc (cdns_pcie); + + ret =clk_prepare_enable (pcie->refclk); +if (ret <0 ) +return ret; + +/* +* The "Power Sequencing and Reset Signal Timings" table of the +* PCI Express Card Electromechanical Specification, Revision +* 5.1, Section 2.9.2, Symbol "T_PERST-CLK", indicates PERST# +* should be deasserted after minimum of 100us once REFCLK is +* stable. The REFCLK to the connector in RC mode is selected +* while enabling the PHY. So deassert PERST# after 100 us. +*/ +if (pcie->reset_gpio) { +fsleep (PCIE_T_PERST_CLK_US ); +gpiod_set_value_cansleep (pcie->reset_gpio,1 ); + } + + ret =cdns_pcie_host_link_setup (rc); +if (ret <0 ) { +clk_disable_unprepare (pcie->refclk); +return ret; + } + +/* +* Reset internal status of BARs to force reinitialization in +* cdns_pcie_host_init(). +*/ +for (enum cdns_pcie_rp_bar bar =RP_BAR0 ; bar <=RP_NO_BAR ; bar++) + rc->avail_ib_bar[bar] = true; + + ret =cdns_pcie_host_init (rc); +if (ret) { +clk_disable_unprepare (pcie->refclk); +return ret; + } + } + +return 0 ; +} + +static DEFINE_NOIRQ_DEV_PM_OPS(j721e_pcie_pm_ops, + j721e_pcie_suspend_noirq, + j721e_pcie_resume_noirq); +static struct platform_driver j721e_pcie_driver = { .probe = j721e_pcie_probe, .remove_new = j721e_pcie_remove,
@@ -576,6 +661,7 @@ static struct platform_driver j721e_pcie_driver = { .name = "j721e-pcie", .of_match_table = of_j721e_pcie_match, .suppress_bind_attrs = true, + .pm = pm_sleep_ptr(&j721e_pcie_pm_ops), }, };builtin_platform_driver (j721e_pcie_driver);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 366/676 PCI: j721e: Deassert PERST# after a delay of PCIE_T_PVPERL_MS milliseconds
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Siddharth Vadapalli <[email protected]>
[ Upstream commit 22a9120479a40a56c13c5e473a0100fad2e017c0 ]
According to Section 2.2 of the PCI Express Card Electromechanical Specification (Revision 5.1), in order to ensure that the power and the reference clock are stable, PERST# has to be deasserted after a delay of 100 milliseconds (TPVPERL).
Currently, it is being assumed that the power is already stable, which is not necessarily true.
Hence, change the delay to PCIE_T_PVPERL_MS to guarantee that power and reference clock are stable.
--- drivers/pci/controller/cadence/pci-j721e.c | 26 ++++++++++------------ 1 file changed, 12 insertions(+), 14 deletions(-)
drivers/pci/controller/cadence/pci-j721e.c +12 -14
@@ -516,15 +516,14 @@ static int j721e_pcie_probe(struct platform_device *pdev) pcie->refclk = clk;/* -* The "Power Sequencing and Reset Signal Timings" table of the -* PCI Express Card Electromechanical Specification, Revision -* 5.1, Section 2.9.2, Symbol "T_PERST-CLK", indicates PERST# -* should be deasserted after minimum of 100us once REFCLK is -* stable. The REFCLK to the connector in RC mode is selected -* while enabling the PHY. So deassert PERST# after 100 us. +* Section 2.2 of the PCI Express Card Electromechanical +* Specification (Revision 5.1) mandates that the deassertion +* of the PERST# signal should be delayed by 100 ms (TPVPERL). +* This shall ensure that the power and the reference clock +* are stable. */ if (gpiod) { -fsleep (PCIE_T_PERST_CLK_US ); +msleep (PCIE_T_PVPERL_MS );gpiod_set_value_cansleep (gpiod,1 ); }
@@ -615,15 +614,14 @@ static int j721e_pcie_resume_noirq(struct device *dev)return ret;/* -* The "Power Sequencing and Reset Signal Timings" table of the -* PCI Express Card Electromechanical Specification, Revision -* 5.1, Section 2.9.2, Symbol "T_PERST-CLK", indicates PERST# -* should be deasserted after minimum of 100us once REFCLK is -* stable. The REFCLK to the connector in RC mode is selected -* while enabling the PHY. So deassert PERST# after 100 us. +* Section 2.2 of the PCI Express Card Electromechanical +* Specification (Revision 5.1) mandates that the deassertion +* of the PERST# signal should be delayed by 100 ms (TPVPERL). +* This shall ensure that the power and the reference clock +* are stable. */ if (pcie->reset_gpio) { -fsleep (PCIE_T_PERST_CLK_US ); +msleep (PCIE_T_PVPERL_MS );gpiod_set_value_cansleep (pcie->reset_gpio,1 ); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 367/676 f2fs: fix race in concurrent f2fs_stop_gc_thread
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Long Li <[email protected]>
[ Upstream commit 7b0033dbc48340a1c1c3f12448ba17d6587ca092 ]
In my test case, concurrent calls to f2fs shutdown report the following stack trace:
Oops: general protection fault, probably for non-canonical address 0xc6cfff63bb5513fc: 0000 [#1] PREEMPT SMP PTI CPU: 0 UID: 0 PID: 678 Comm: f2fs_rep_shutdo Not tainted 6.12.0-rc5-next-20241029-g6fb2fa9805c5-dirty #85 Call Trace: <TASK> ? show_regs+0x8b/0xa0 ? __die_body+0x26/0xa0 ? die_addr+0x54/0x90 ? exc_general_protection+0x24b/0x5c0 ? asm_exc_general_protection+0x26/0x30 ? kthread_stop+0x46/0x390 f2fs_stop_gc_thread+0x6c/0x110 f2fs_do_shutdown+0x309/0x3a0 f2fs_ioc_shutdown+0x150/0x1c0 __f2fs_ioctl+0xffd/0x2ac0 f2fs_ioctl+0x76/0xe0 vfs_ioctl+0x23/0x60 __x64_sys_ioctl+0xce/0xf0 x64_sys_call+0x2b1b/0x4540 do_syscall_64+0xa7/0x240 entry_SYSCALL_64_after_hwframe+0x76/0x7e
The root cause is a race condition in f2fs_stop_gc_thread() called from different f2fs shutdown paths:
[CPU0] [CPU1]
---------------------- -----------------------
f2fs_stop_gc_thread f2fs_stop_gc_thread
gc_th = sbi->gc_thread
gc_th = sbi->gc_thread
kfree(gc_th)
sbi->gc_thread = NULL
< gc_th != NULL >
kthread_stop(gc_th->f2fs_gc_task) //UAFThe commit c7f114d864ac ("f2fs: fix to avoid use-after-free in f2fs_stop_gc_thread()") attempted to fix this issue by using a read semaphore to prevent races between shutdown and remount threads, but it fails to prevent all race conditions.
Fix it by converting to write lock of s_umount in f2fs_do_shutdown().
--- fs/f2fs/file.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
fs/f2fs/file.c +6 -3
@@ -2308,9 +2308,12 @@ int f2fs_do_shutdown(struct f2fs_sb_info *sbi, unsigned int flag,if (readonly) goto out; -/* grab sb->s_umount to avoid racing w/ remount() */ +/* +* grab sb->s_umount to avoid racing w/ remount() and other shutdown +* paths. +*/ if (need_lock) -down_read (&sbi->sb->s_umount); +down_write (&sbi->sb->s_umount);f2fs_stop_gc_thread (sbi);f2fs_stop_discard_thread (sbi);
@@ -2319,7 +2322,7 @@ int f2fs_do_shutdown(struct f2fs_sb_info *sbi, unsigned int flag,clear_opt (sbi,DISCARD );if (need_lock) -up_read (&sbi->sb->s_umount); +up_write (&sbi->sb->s_umount);f2fs_update_time (sbi,REQ_TIME ); out:
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 368/676 f2fs: fix to avoid forcing direct write to use buffered IO on inline_data inode
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <[email protected]>
[ Upstream commit 26e6f59d0bbaac76fa3413462d780bd2b5f9f653 ]
Jinsu Lee reported a performance regression issue, after commit 5c8764f8679e ("f2fs: fix to force buffered IO on inline_data inode"), we forced direct write to use buffered IO on inline_data inode, it will cause performace regression due to memory copy and data flush.
It's fine to not force direct write to use buffered IO, as it can convert inline inode before committing direct write IO.
--- fs/f2fs/file.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
fs/f2fs/file.c +5 -1
@@ -846,7 +846,11 @@ static bool f2fs_force_buffered_io(struct inode *inode, int rw)return true;if (f2fs_compressed_file (inode))return true; -if (f2fs_has_inline_data (inode)) +/* +* only force direct read to use buffered IO, for direct write, +* it expects inline data conversion before committing IO. +*/ +if (f2fs_has_inline_data (inode) && rw ==READ )return true;/* disallow direct IO if any of devices has unaligned blksize */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 369/676 perf trace: avoid garbage when not printing a trace events arguments
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Benjamin Peterson <[email protected]>
[ Upstream commit 5fb8e56542a3cf469fdf25d77f50e21cbff3ae7e ]
trace__fprintf_tp_fields may not print any tracepoint arguments. E.g., if the argument values are all zero. Previously, this would result in a totally uninitialized buffer being passed to fprintf, which could lead to garbage on the console. Fix the problem by passing the number of initialized bytes fprintf.
--- tools/perf/builtin-trace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/builtin-trace.c +1 -1
@@ -2803,7 +2803,7 @@ static size_t trace__fprintf_tp_fields(struct trace *trace, struct evsel *evsel, printed +=syscall_arg_fmt__scnprintf_val (arg, bf + printed, size - printed, &syscall_arg, val); } -return printed +fprintf (trace->output,"%s" , bf); +return printed +fprintf (trace->output,"%.*s" , (int )printed, bf); } static int trace__event_handler(struct trace *trace, struct evsel *evsel,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 370/676 m68k: mcfgpio: Fix incorrect register offset for CONFIG_M5441x
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jean-Michel Hautbois <[email protected]>
[ Upstream commit f212140962c93cd5da43283a18e31681540fc23d ]
Fix a typo in the CONFIG_M5441x preprocessor condition, where the GPIO register offset was incorrectly set to 8 instead of 0. This prevented proper GPIO configuration for m5441x targets.
--- arch/m68k/include/asm/mcfgpio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/m68k/include/asm/mcfgpio.h +1 -1
@@ -136,7 +136,7 @@ static inline void gpio_free(unsigned gpio)* read-modify-write as well as those controlled by the EPORT and GPIO modules. */ #define MCFGPIO_SCR_START 40 -#elif defined(CONFIGM5441x) +#elif defined(CONFIG_M5441x)/* The m5441x EPORT doesn't have its own GPIO port, uses PORT C */ #define MCFGPIO_SCR_START 0#else
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 371/676 m68k: coldfire/device.c: only build FEC when HW macros are defined
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Antonio Quartulli <[email protected]>
[ Upstream commit 63a24cf8cc330e5a68ebd2e20ae200096974c475 ]
When CONFIG_FEC is set (due to COMPILE_TEST) along with CONFIG_M54xx, coldfire/device.c has compile errors due to missing MCFEC_* and MCF_IRQ_FEC_* symbols.
Make the whole FEC blocks dependent on having the HW macros defined, rather than on CONFIG_FEC itself.
This fix is very similar to commit e6e1e7b19fa1 ("m68k: coldfire/device.c: only build for MCF_EDMA when h/w macros are defined")
To: Greg Ungerer <[email protected]>
To: Geert Uytterhoeven <[email protected]>
--- arch/m68k/coldfire/device.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
arch/m68k/coldfire/device.c +4 -4
@@ -93,7 +93,7 @@ static struct platform_device mcf_uart = { .dev.platform_data = mcf_uart_platform_data, }; -#if IS_ENABLED (CONFIG_FEC ) +#ifdef MCFFEC_BASE0 #ifdef CONFIG_M5441x#define FEC_NAME "enet-fec"
@@ -145,6 +145,7 @@ static struct platform_device mcf_fec0 = { .platform_data = FEC_PDATA, } }; +#endif /* MCFFEC_BASE0 */ #ifdef MCFFEC_BASE1 static struct resource mcf_fec1_resources[] = {
@@ -182,7 +183,6 @@ static struct platform_device mcf_fec1 = { } };#endif /* MCFFEC_BASE1 */ -#endif /* CONFIG_FEC */ #if IS_ENABLED (CONFIG_SPI_COLDFIRE_QSPI )/*
@@ -624,12 +624,12 @@ static struct platform_device mcf_flexcan0 = {static struct platform_device *mcf_devices[]__initdata = { &mcf_uart, -#if IS_ENABLED(CONFIG_FEC) +#ifdef MCFFEC_BASE0 &mcf_fec0, +#endif #ifdef MCFFEC_BASE1 &mcf_fec1, #endif -#endif #if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) &mcf_qspi, #endif
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 372/676 svcrdma: Address an integer overflow
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 3c63d8946e578663b868cb9912dac616ea68bfd0 ]
Dan Carpenter reports:
Quoted 20 lines
Commit
78147ca8b4a9("svcrdma: Add a "parsed chunk list" data structure") from Jun 22, 2020 (linux-next), leads to the following Smatch static checker warning:
net/sunrpc/xprtrdma/svc_rdma_recvfrom.c:498xdr_check_write_chunk()
warn: potential user controlled sizeof overflow 'segcount * 4 * 4'
net/sunrpc/xprtrdma/svc_rdma_recvfrom.c488 static bool xdr_check_write_chunk(struct svc_rdma_recv_ctxt *rctxt) 489 { 490 u32 segcount; 491 __be32 *p; 492 493 if (xdr_stream_decode_u32(&rctxt->rc_stream, &segcount)) ^^^^^^^^ 494 return false; 495 496 /* A bogus segcount causes this buffer overflow check to fail. */ 497 p = xdr_inline_decode(&rctxt->rc_stream,
Quoted 6 lines
--> 498 segcount *
rpcrdma_segment_maxsz*sizeof(*p));segcount is an untrusted u32. On 32bit systems anything >=
SIZE_MAX/ 16 will have an integer overflow and some those values will be accepted byxdr_inline_decode().
--- net/sunrpc/xprtrdma/svc_rdma_recvfrom.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
net/sunrpc/xprtrdma/svc_rdma_recvfrom.c +7 -1
@@ -478,7 +478,13 @@ static bool xdr_check_write_chunk(struct svc_rdma_recv_ctxt *rctxt)if (xdr_stream_decode_u32 (&rctxt->rc_stream, &segcount))return false; -/* A bogus segcount causes this buffer overflow check to fail. */ +/* Before trusting the segcount value enough to use it in +* a computation, perform a simple range check. This is an +* arbitrary but sensible limit (ie, not architectural). +*/ +if (unlikely (segcount >RPCSVC_MAXPAGES )) +return false; + p =xdr_inline_decode (&rctxt->rc_stream, segcount * rpcrdma_segment_maxsz *sizeof (*p));return p !=NULL ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 373/676 perf list: Fix topic and pmu_name argument order
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jean-Philippe Romain <[email protected]>
[ Upstream commit d99b3125726aade4f5ec4aae04805134ab4b0abd ]
Fix function definitions to match header file declaration. Fix two callers to pass the arguments in the right order.
On Intel Tigerlake, before:
```
$ perf list -j|grep "\"Topic\""|sort|uniq
"Topic": "cache",
"Topic": "cpu",
"Topic": "floating point",
"Topic": "frontend",
"Topic": "memory",
"Topic": "other",
"Topic": "pfm icl",
"Topic": "pfm ix86arch",
"Topic": "pfm perf_raw",
"Topic": "pipeline",
"Topic": "tool",
"Topic": "uncore interconnect",
"Topic": "uncore memory",
"Topic": "uncore other",
"Topic": "virtual memory",
$ perf list -j|grep "\"Unit\""|sort|uniq
"Unit": "cache",
"Unit": "cpu",
"Unit": "cstate_core",
"Unit": "cstate_pkg",
"Unit": "i915",
"Unit": "icl",
"Unit": "intel_bts",
"Unit": "intel_pt",
"Unit": "ix86arch",
"Unit": "msr",
"Unit": "perf_raw",
"Unit": "power",
"Unit": "tool",
"Unit": "uncore_arb",
"Unit": "uncore_clock",
"Unit": "uncore_imc_free_running_0",
"Unit": "uncore_imc_free_running_1",
```After:
```
$ perf list -j|grep "\"Topic\""|sort|uniq
"Topic": "cache",
"Topic": "floating point",
"Topic": "frontend",
"Topic": "memory",
"Topic": "other",
"Topic": "pfm icl",
"Topic": "pfm ix86arch",
"Topic": "pfm perf_raw",
"Topic": "pipeline",
"Topic": "tool",
"Topic": "uncore interconnect",
"Topic": "uncore memory",
"Topic": "uncore other",
"Topic": "virtual memory",
$ perf list -j|grep "\"Unit\""|sort|uniq
"Unit": "cpu",
"Unit": "cstate_core",
"Unit": "cstate_pkg",
"Unit": "i915",
"Unit": "icl",
"Unit": "intel_bts",
"Unit": "intel_pt",
"Unit": "ix86arch",
"Unit": "msr",
"Unit": "perf_raw",
"Unit": "power",
"Unit": "tool",
"Unit": "uncore_arb",
"Unit": "uncore_clock",
"Unit": "uncore_imc_free_running_0",
"Unit": "uncore_imc_free_running_1",
```--- tools/perf/builtin-list.c | 4 ++-- tools/perf/util/pfm.c | 4 ++-- tools/perf/util/pmus.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-)
tools/perf/builtin-list.c +2 -2
@@ -95,7 +95,7 @@ static void wordwrap(const char *s, int start, int max, int corr) } } -static void default_print_event(void *ps, const char *pmu_name, const char *topic, +static void default_print_event(void *ps, const char *topic, const char *pmu_name, const char *event_name, const char *event_alias, const char *scale_unit __maybe_unused, bool deprecated, const char *event_type_desc,
@@ -321,7 +321,7 @@ static void fix_escape_printf(struct strbuf *buf, const char *fmt, ...)fputs (buf->buf, stdout); } -static void json_print_event(void *ps, const char *pmu_name, const char *topic, +static void json_print_event(void *ps, const char *topic, const char *pmu_name, const char *event_name, const char *event_alias, const char *scale_unit, bool deprecated, const char *event_type_desc,
tools/perf/util/pfm.c +2 -2
@@ -220,7 +220,7 @@ print_libpfm_event(const struct print_callbacks *print_cb, void *print_state, }if (is_libpfm_event_supported (name, cpus, threads)) { - print_cb->print_event(print_state, pinfo->name, topic, + print_cb->print_event(print_state, topic, pinfo->name, name, info->equiv, /*scale_unit=*/NULL, /*deprecated=*/NULL, "PFM event",
@@ -254,8 +254,8 @@ print_libpfm_event(const struct print_callbacks *print_cb, void *print_state,continue ; print_cb->print_event(print_state, - pinfo->name, topic, + pinfo->name, name, /*alias=*/NULL, /*scale_unit=*/NULL, /*deprecated=*/NULL, "PFM event",
tools/perf/util/pmus.c +1 -1
@@ -474,8 +474,8 @@ void perf_pmus__print_pmu_events(const struct print_callbacks *print_cb, void *p goto free; print_cb->print_event(print_state, - aliases[j].pmu_name, aliases[j].topic, + aliases[j].pmu_name, aliases[j].name, aliases[j].alias, aliases[j].scale_unit,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 374/676 perf trace: Fix tracing itself, creating feedback loops
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Howard Chu <[email protected]>
[ Upstream commit fe4f9b4124967ffb75d66994520831231b779550 ]
There exists a pids_filtered map in augmented_raw_syscalls.bpf.c that ceases to provide functionality after the BPF skeleton migration done in:
5e6da6be3082f77b ("perf trace: Migrate BPF augmentation to use a skeleton")
Before the migration, pid_filtered map works, courtesy of Arnaldo Carvalho de Melo <[email protected]>:
⬢ [acme@toolbox perf-tools]$ git log --oneline -5
6f769c3458b6cf2d (HEAD) perf tests trace+probe_vfs_getname.sh: Accept quotes surrounding the filename 7777ac3dfe29f55d perf test trace+probe_vfs_getname.sh: Remove stray \ before /
33d9c5062113a4bd perf script python: Add stub for PMU symbol to the python binding
e59fea47f83e8a9a perf symbols: Fix DSO kernel load and symbol process to correctly map DSO to its long_name, type and adjust_symbols 878460e8d0ff84a0 perf build: Remove -Wno-unused-but-set-variable from the flex flags when building with clang < 13.0.0
root@x1:/home/acme/git/perf-tools# perf trace -e /tmp/augmented_raw_syscalls.o -e write* --max-events=30 &
[1] 180632
root@x1:/home/acme/git/perf-tools# 0.000 ( 0.051 ms): NetworkManager/1127 write(fd: 3, buf: 0x7ffeb508ef70, count: 8) = 8
0.115 ( 0.010 ms): NetworkManager/1127 write(fd: 3, buf: 0x7ffeb508ef70, count: 8) = 8
0.916 ( 0.068 ms): sudo/156867 write(fd: 8, buf: 0x55cb4cd2f650, count: 246) = 246
1.699 ( 0.047 ms): sudo/156867 write(fd: 8, buf: 0x55cb4cd2f650, count: 121) = 121
2.167 ( 0.041 ms): sudo/156867 write(fd: 8, buf: 0x55cb4cd2f650, count: 121) = 121
2.739 ( 0.042 ms): sudo/156867 write(fd: 8, buf: 0x55cb4cd2f650, count: 121) = 121
3.138 ( 0.027 ms): sudo/156867 write(fd: 8, buf: 0x55cb4cd2f650, count: 121) = 121
3.477 ( 0.027 ms): sudo/156867 write(fd: 8, buf: 0x55cb4cd2f650, count: 121) = 121
3.738 ( 0.023 ms): sudo/156867 write(fd: 8, buf: 0x55cb4cd2f650, count: 121) = 121
3.946 ( 0.024 ms): sudo/156867 write(fd: 8, buf: 0x55cb4cd2f650, count: 121) = 121
4.195 ( 0.024 ms): sudo/156867 write(fd: 8, buf: 0x55cb4cd2f650, count: 121) = 121
4.212 ( 0.026 ms): NetworkManager/1127 write(fd: 3, buf: 0x7ffeb508ef70, count: 8) = 8
4.285 ( 0.006 ms): NetworkManager/1127 write(fd: 3, buf: 0x7ffeb508ef70, count: 8) = 8
4.445 ( 0.018 ms): sudo/156867 write(fd: 8, buf: 0x55cb4cd2f650, count: 260) = 260
4.508 ( 0.009 ms): sudo/156867 write(fd: 8, buf: 0x55cb4cd2f650, count: 124) = 124
4.592 ( 0.010 ms): sudo/156867 write(fd: 8, buf: 0x55cb4cd2f650, count: 116) = 116
4.666 ( 0.009 ms): sudo/156867 write(fd: 8, buf: 0x55cb4cd2f650, count: 130) = 130
4.715 ( 0.010 ms): sudo/156867 write(fd: 8, buf: 0x55cb4cd2f650, count: 95) = 95
4.765 ( 0.007 ms): sudo/156867 write(fd: 8, buf: 0x55cb4cd2f650, count: 102) = 102
4.815 ( 0.009 ms): sudo/156867 write(fd: 8, buf: 0x55cb4cd2f650, count: 79) = 79
4.890 ( 0.008 ms): sudo/156867 write(fd: 8, buf: 0x55cb4cd2f650, count: 57) = 57
4.937 ( 0.007 ms): sudo/156867 write(fd: 8, buf: 0x55cb4cd2f650, count: 89) = 89
5.009 ( 0.010 ms): sudo/156867 write(fd: 8, buf: 0x55cb4cd2f650, count: 112) = 112
5.059 ( 0.010 ms): sudo/156867 write(fd: 8, buf: 0x55cb4cd2f650, count: 112) = 112
5.116 ( 0.007 ms): sudo/156867 write(fd: 8, buf: 0x55cb4cd2f650, count: 79) = 79
5.152 ( 0.009 ms): sudo/156867 write(fd: 8, buf: 0x55cb4cd2f650, count: 33) = 33
5.215 ( 0.008 ms): sudo/156867 write(fd: 8, buf: 0x55cb4cd2f650, count: 37) = 37
5.293 ( 0.010 ms): sudo/156867 write(fd: 8, buf: 0x55cb4cd2f650, count: 128) = 128
5.339 ( 0.009 ms): sudo/156867 write(fd: 8, buf: 0x55cb4cd2f650, count: 89) = 89
5.384 ( 0.008 ms): sudo/156867 write(fd: 8, buf: 0x55cb4cd2f650, count: 100) = 100[1]+ Done perf trace -e /tmp/augmented_raw_syscalls.o -e write* --max-events=30 root@x1:/home/acme/git/perf-tools#
No events for the 'perf trace' (pid 180632), i.e. no feedback loop.
If we leave it running:
root@x1:/home/acme/git/perf-tools# perf trace -e /tmp/augmented_raw_syscalls.o -e landlock_add_rule & [1] 181068 root@x1:/home/acme/git/perf-tools#
And then look at what maps it sets up:
root@x1:/home/acme/git/perf-tools# bpftool map | grep pids_filtered -A3
1190: hash name pids_filtered flags 0x0
key 4B value 1B max_entries 64 memlock 7264B
btf_id 1613
pids perf(181068)
root@x1:/home/acme/git/perf-tools#And ask for dumping its contents:
We see that we are _also_ setting it to filter those:
root@x1:/home/acme/git/perf-tools# bpftool map dump id 1190
[{
"key": 181068,
"value": 1
},{
"key": 156801,
"value": 1
}
]Now testing the migration commit:
perf $ git log
commit 5e6da6be3082f77be06894a1a94d52a90b4007dc (HEAD)
Author: Ian Rogers <[email protected]>
Date: Thu Aug 10 11:48:51 2023 -0700
perf trace: Migrate BPF augmentation to use a skeleton
perf $ ./perf trace -e write --max-events=10 & echo #!
[1] 1808653
perf $
0.000 ( 0.010 ms): :1808671/1808671 write(fd: 1, buf: 0x6003f5b26fc0, count: 11) = 11
0.162 ( ): perf/1808653 write(fd: 2, buf: 0x7fffc2174e50, count: 11) ...
0.174 ( ): perf/1808653 write(fd: 2, buf: 0x74ce21804563, count: 1) ...
0.184 ( ): perf/1808653 write(fd: 2, buf: 0x57b936589052, count: 5)The feedback loop is there.
Keep it running, look into the bpf map:
perf $ bpftool map | grep pids_filtered
10675: hash name pids_filtered flags 0x0
perf $ bpftool map dump id 10675
[]
The map is empty.
Now, this commit:
64917f4df048a064 ("perf trace: Use heuristic when deciding if a syscall tracepoint "const char *" field is really a string")
Temporarily fixed the feedback loop for perf trace -e write, that's because before using the heuristic, write is hooked to sys_enter_openat:
perf $ git log
commit 83a0943b1870944612a8aa0049f910826ebfd4f7 (HEAD)
Author: Arnaldo Carvalho de Melo <[email protected]>
Date: Thu Aug 17 12:11:51 2023 -0300
perf trace: Use the augmented_raw_syscall BPF skel only for tracing syscalls
perf $ ./perf trace -e write --max-events=10 -v 2>&1 | grep Reusing Reusing "openat" BPF sys_enter augmenter for "write"
And after the heuristic fix, it's unaugmented:
perf $ git log
commit 64917f4df048a0649ea7901c2321f020e71e6f24 (HEAD)
Author: Arnaldo Carvalho de Melo <[email protected]>
Date: Thu Aug 17 15:14:21 2023 -0300
perf trace: Use heuristic when deciding if a syscall tracepoint "const char *" field is really a string
perf $ ./perf trace -e write --max-events=10 -v 2>&1 | grep Reusing perf $
After using the heuristic, write is hooked to syscall_unaugmented, which returns 1.
SEC("tp/raw_syscalls/sys_enter")
int syscall_unaugmented(struct syscall_enter_args *args)
{
return 1;
}If the BPF program returns 1, the tracepoint filter will filter it (since the tracepoint filter for perf is correctly set), but before the heuristic, when it was hooked to a sys_enter_openat(), which is a BPF program that calls bpf_perf_event_output() and writes to the buffer, it didn't get filtered, thus creating feedback loop. So switching write to unaugmented accidentally fixed the problem.
But some syscalls are not so lucky, for example newfstatat:
perf $ ./perf trace -e newfstatat --max-events=100 & echo #!
[1] 2166948
457.718 ( ): perf/2166948 newfstatat(dfd: CWD, filename: "/proc/self/ns/mnt", statbuf: 0x7fff0132a9f0) ... 457.749 ( ): perf/2166948 newfstatat(dfd: CWD, filename: "/proc/2166950/ns/mnt", statbuf: 0x7fff0132aa80) ... 457.962 ( ): perf/2166948 newfstatat(dfd: CWD, filename: "/proc/self/ns/mnt", statbuf: 0x7fff0132a9f0) ...
Currently, write is augmented by the new BTF general augmenter (which calls bpf_perf_event_output()). The problem, which luckily got fixed, resurfaced, and that’s how it was discovered.
--- tools/perf/builtin-trace.c | 3 +++ 1 file changed, 3 insertions(+)
tools/perf/builtin-trace.c +3 -0
@@ -3923,6 +3923,9 @@ static int trace__run(struct trace *trace, int argc, const char **argv) sizeof(__u32), BPF_ANY); } } + +if (trace->skel) + trace->filter_pids.map = trace->skel->maps.pids_filtered;#endif err =trace__set_filter_pids (trace);if (err <0 )
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 375/676 perf trace: Do not lose last events in a race
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Benjamin Peterson <[email protected]>
[ Upstream commit 3fd7c36973a250e17a4ee305a31545a9426021f4 ]
If a perf trace event selector specifies a maximum number of events to output (i.e., "/nr=N/" syntax), the event printing handler, trace__event_handler, disables the event selector after the maximum number events are printed.
Furthermore, trace__event_handler checked if the event selector was disabled before doing any work. This avoided exceeding the maximum number of events to print if more events were in the buffer before the selector was disabled.
However, the event selector can be disabled for reasons other than exceeding the maximum number of events. In particular, when the traced subprocess exits, the main loop disables all event selectors. This meant the last events of a traced subprocess might be lost to the printing handler's short-circuiting logic.
This nondeterministic problem could be seen by running the following many times:
$ perf trace -e syscalls:sys_enter_exit_group true
trace__event_handler should simply check for exceeding the maximum number of events to print rather than the state of the event selector.
--- tools/perf/builtin-trace.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-)
tools/perf/builtin-trace.c +2 -7
@@ -2812,13 +2812,8 @@ static int trace__event_handler(struct trace *trace, struct evsel *evsel, {struct thread *thread;int callchain_ret =0 ; -/* -* Check if we called perf_evsel__disable(evsel) due to, for instance, -* this event's max_events having been hit and this is an entry coming -* from the ring buffer that we should discard, since the max events -* have already been considered/printed. -*/ -if (evsel->disabled) + +if (evsel->nr_events_printed >= evsel->max_events)return 0 ; thread =machine__findnew_thread (trace->host, sample->pid, sample->tid);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 376/676 perf trace: Avoid garbage when not printing a syscalls arguments
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Benjamin Peterson <[email protected]>
[ Upstream commit 1302e352b26f34991b619b5d0b621b76d20a3883 ]
syscall__scnprintf_args may not place anything in the output buffer (e.g., because the arguments are all zero). If that happened in trace__fprintf_sys_enter, its fprintf would receive an unitialized buffer leading to garbage output.
Fix the problem by passing the (possibly zero) bounds of the argument buffer to the output fprintf.
--- tools/perf/builtin-trace.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
tools/perf/builtin-trace.c +3 -2
@@ -2414,6 +2414,7 @@ static int trace__fprintf_sys_enter(struct trace *trace, struct evsel *evsel,char msg[1024 ];void *args, *augmented_args =NULL ;int augmented_args_size; +size_t printed =0 ;if (sc ==NULL )return -1 ;
@@ -2429,8 +2430,8 @@ static int trace__fprintf_sys_enter(struct trace *trace, struct evsel *evsel, args =perf_evsel__sc_tp_ptr (evsel, args, sample); augmented_args =syscall__augmented_args (sc, sample, &augmented_args_size, trace->raw_augmented_syscalls_args_size); -syscall__scnprintf_args (sc, msg,sizeof (msg), args, augmented_args, augmented_args_size, trace, thread); -fprintf (trace->output,"%s" , msg); + printed +=syscall__scnprintf_args (sc, msg,sizeof (msg), args, augmented_args, augmented_args_size, trace, thread); +fprintf (trace->output,"%.*s" , (int )printed, msg); err =0 ; out_put:thread__put (thread);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 377/676 remoteproc: qcom: pas: add minidump_id to SM8350 resources
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Baryshkov <[email protected]>
[ Upstream commit e8983156d54f59f57e648ecd44f01c16572da842 ]
Specify minidump_id for the SM8350 DSPs. It was omitted for in the original commit e8b4e9a21af7 ("remoteproc: qcom: pas: Add SM8350 PAS remoteprocs").
--- drivers/remoteproc/qcom_q6v5_pas.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/remoteproc/qcom_q6v5_pas.c +2 -0
@@ -832,6 +832,7 @@ static const struct adsp_data sm8250_adsp_resource = { .crash_reason_smem = 423, .firmware_name = "adsp.mdt", .pas_id = 1, + .minidump_id = 5, .auto_boot = true, .proxy_pd_names = (char *[]){"lcx" ,
@@ -973,6 +974,7 @@ static const struct adsp_data sm8350_cdsp_resource = { .crash_reason_smem = 601, .firmware_name = "cdsp.mdt", .pas_id = 18, + .minidump_id = 7, .auto_boot = true, .proxy_pd_names = (char *[]){"cx" ,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 378/676 rpmsg: glink: use only lower 16-bits of param2 for CMD_OPEN name length
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonathan Marek <[email protected]>
[ Upstream commit 06c59d97f63c1b8af521fa5aef8a716fb988b285 ]
The name len field of the CMD_OPEN packet is only 16-bits and the upper 16-bits of "param2" are a different "prio" field, which can be nonzero in certain situations, and CMD_OPEN packets can be unexpectedly dropped because of this.
Fix this by masking out the upper 16 bits of param2.
--- drivers/rpmsg/qcom_glink_native.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/rpmsg/qcom_glink_native.c +2 -1
@@ -1117,7 +1117,8 @@ void qcom_glink_native_rx(struct qcom_glink *glink)qcom_glink_rx_advance (glink,ALIGN (sizeof (msg),8 ));break ;case GLINK_CMD_OPEN : - ret =qcom_glink_rx_defer (glink, param2); +/* upper 16 bits of param2 are the "prio" field */ + ret =qcom_glink_rx_defer (glink, param2 &0xffff );break ;case GLINK_CMD_TX_DATA :case GLINK_CMD_TX_DATA_CONT :
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 379/676 remoteproc: qcom_q6v5_mss: Re-order writes to the IMEM region
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sibi Sankar <[email protected]>
[ Upstream commit 7b22b7719fc17d5979a991c918c868ab041be5c8 ]
Any write access to the IMEM region when the Q6 is setting up XPU protection on it will result in a XPU violation. Fix this by ensuring IMEM writes related to the MBA post-mortem logs happen before the Q6 is brought out of reset.
--- drivers/remoteproc/qcom_q6v5_mss.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/remoteproc/qcom_q6v5_mss.c +3 -3
@@ -1161,6 +1161,9 @@ static int q6v5_mba_load(struct q6v5 *qproc) goto disable_active_clks; } +if (qproc->has_mba_logs) +qcom_pil_info_store ("mba" , qproc->mba_phys,MBA_LOG_SIZE ); +writel (qproc->mba_phys, qproc->rmb_base +RMB_MBA_IMAGE_REG );if (qproc->dp_size) {writel (qproc->mba_phys +SZ_1M , qproc->rmb_base +RMB_PMI_CODE_START_REG );
@@ -1171,9 +1174,6 @@ static int q6v5_mba_load(struct q6v5 *qproc)if (ret) goto reclaim_mba; -if (qproc->has_mba_logs) -qcom_pil_info_store ("mba" , qproc->mba_phys,MBA_LOG_SIZE ); - ret =q6v5_rmb_mba_wait (qproc,0 ,5000 );if (ret == -ETIMEDOUT ) {dev_err (qproc->dev,"MBA boot timed out\n" );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 380/676 PCI: endpoint: epf-mhi: Avoid NULL dereference if DT lacks mmio
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhongqiu Han <[email protected]>
[ Upstream commit 5089b3d874e9933d9842e90410d3af1520494757 ]
If platform_get_resource_byname() fails and returns NULL because DT lacks an 'mmio' property for the MHI endpoint, dereferencing res->start will cause a NULL pointer access. Add a check to prevent it.
--- drivers/pci/endpoint/functions/pci-epf-mhi.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/pci/endpoint/functions/pci-epf-mhi.c +6 -0
@@ -600,12 +600,18 @@ static int pci_epf_mhi_bind(struct pci_epf *epf) {struct pci_epf_mhi *epf_mhi =epf_get_drvdata (epf);struct pci_epc *epc = epf->epc; +struct device *dev = &epf->dev;struct platform_device *pdev =to_platform_device (epc->dev.parent);struct resource *res;int ret;/* Get MMIO base address from Endpoint controller */ res =platform_get_resource_byname (pdev,IORESOURCE_MEM ,"mmio" ); +if (!res) { +dev_err (dev,"Failed to get \"mmio\" resource\n" ); +return -ENODEV ; + } + epf_mhi->mmio_phys = res->start; epf_mhi->mmio_size =resource_size (res);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 381/676 NFSD: Prevent NULL dereference in nfsd4_process_cb_update()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 1e02c641c3a43c88cecc08402000418e15578d38 ]
@ses is initialized to NULL. If __nfsd4_find_backchannel() finds no available backchannel session, setup_callback_client() will try to dereference @ses and segfault.
--- fs/nfsd/nfs4callback.c | 2 ++ 1 file changed, 2 insertions(+)
fs/nfsd/nfs4callback.c +2 -0
@@ -1379,6 +1379,8 @@ static void nfsd4_process_cb_update(struct nfsd4_callback *cb) ses = c->cn_session; }spin_unlock (&clp->cl_lock); +if (!c) +return ; err =setup_callback_client (clp, &conn, ses);if (err) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 382/676 NFSD: Cap the number of bytes copied by nfs4_reset_recoverydir()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit f64ea4af43161bb86ffc77e6aeb5bcf5c3229df0 ]
It's only current caller already length-checks the string, but let's be safe.
--- fs/nfsd/nfs4recover.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/nfsd/nfs4recover.c +2 -1
@@ -658,7 +658,8 @@ nfs4_reset_recoverydir(char *recdir)return status; status = -ENOTDIR ;if (d_is_dir (path.dentry)) { -strcpy (user_recovery_dirname, recdir); +strscpy (user_recovery_dirname, recdir, +sizeof (user_recovery_dirname)); status =0 ; }path_put (&path);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 383/676 nfsd: release svc_expkey/svc_export with rcu_work
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yang Erkun <[email protected]>
[ Upstream commit f8c989a0c89a75d30f899a7cabdc14d72522bb8d ]
The last reference for cache_head can be reduced to zero in c_show and e_show(using rcu_read_lock and rcu_read_unlock). Consequently, svc_export_put and expkey_put will be invoked, leading to two issues:
1. The svc_export_put will directly free ex_uuid. However, e_show/c_show will access ex_uuid after cache_put, which can trigger a use-after-free issue, shown below.
==================================================================
BUG: KASAN: slab-use-after-free in svc_export_show+0x362/0x430 [nfsd]
Read of size 1 at addr ff11000010fdc120 by task cat/870
CPU: 1 UID: 0 PID: 870 Comm: cat Not tainted 6.12.0-rc3+ #1
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
1.16.1-2.fc37 04/01/2014
Call Trace:
<TASK>
dump_stack_lvl+0x53/0x70
print_address_description.constprop.0+0x2c/0x3a0
print_report+0xb9/0x280
kasan_report+0xae/0xe0
svc_export_show+0x362/0x430 [nfsd]
c_show+0x161/0x390 [sunrpc]
seq_read_iter+0x589/0x770
seq_read+0x1e5/0x270
proc_reg_read+0xe1/0x140
vfs_read+0x125/0x530
ksys_read+0xc1/0x160
do_syscall_64+0x5f/0x170
entry_SYSCALL_64_after_hwframe+0x76/0x7e
Allocated by task 830:
kasan_save_stack+0x20/0x40
kasan_save_track+0x14/0x30
__kasan_kmalloc+0x8f/0xa0
__kmalloc_node_track_caller_noprof+0x1bc/0x400
kmemdup_noprof+0x22/0x50
svc_export_parse+0x8a9/0xb80 [nfsd]
cache_do_downcall+0x71/0xa0 [sunrpc]
cache_write_procfs+0x8e/0xd0 [sunrpc]
proc_reg_write+0xe1/0x140
vfs_write+0x1a5/0x6d0
ksys_write+0xc1/0x160
do_syscall_64+0x5f/0x170
entry_SYSCALL_64_after_hwframe+0x76/0x7e
Freed by task 868:
kasan_save_stack+0x20/0x40
kasan_save_track+0x14/0x30
kasan_save_free_info+0x3b/0x60
__kasan_slab_free+0x37/0x50
kfree+0xf3/0x3e0
svc_export_put+0x87/0xb0 [nfsd]
cache_purge+0x17f/0x1f0 [sunrpc]
nfsd_destroy_serv+0x226/0x2d0 [nfsd]
nfsd_svc+0x125/0x1e0 [nfsd]
write_threads+0x16a/0x2a0 [nfsd]
nfsctl_transaction_write+0x74/0xa0 [nfsd]
vfs_write+0x1a5/0x6d0
ksys_write+0xc1/0x160
do_syscall_64+0x5f/0x170
entry_SYSCALL_64_after_hwframe+0x76/0x7e2. We cannot sleep while using rcu_read_lock/rcu_read_unlock. However, svc_export_put/expkey_put will call path_put, which subsequently triggers a sleeping operation due to the following dput.
=============================
WARNING: suspicious RCU usage
5.10.0-dirty #141 Not tainted
-----------------------------
...
Call Trace: dump_stack+0x9a/0xd0 ___might_sleep+0x231/0x240 dput+0x39/0x600 path_put+0x1b/0x30 svc_export_put+0x17/0x80 e_show+0x1c9/0x200 seq_read_iter+0x63f/0x7c0 seq_read+0x226/0x2d0 vfs_read+0x113/0x2c0 ksys_read+0xc9/0x170 do_syscall_64+0x33/0x40 entry_SYSCALL_64_after_hwframe+0x67/0xd1
Fix these issues by using rcu_work to help release svc_expkey/svc_export. This approach allows for an asynchronous context to invoke path_put and also facilitates the freeing of uuid/exp/key after an RCU grace period.
--- fs/nfsd/export.c | 31 +++++++++++++++++++++++++------ fs/nfsd/export.h | 4 ++-- 2 files changed, 27 insertions(+), 8 deletions(-)
fs/nfsd/export.c +25 -6
@@ -40,15 +40,24 @@#define EXPKEY_HASHMAX (1 << EXPKEY_HASHBITS)#define EXPKEY_HASHMASK (EXPKEY_HASHMAX -1) -static void expkey_put (struct kref *ref) +static void expkey_put_work (struct work_struct *work) { - struct svc_expkey *key = container_of(ref, struct svc_expkey, h.ref); +struct svc_expkey *key = + container_of(to_rcu_work(work), struct svc_expkey, ek_rcu_work);if (test_bit (CACHE_VALID , &key->h.flags) && !test_bit (CACHE_NEGATIVE , &key->h.flags))path_put (&key->ek_path);auth_domain_put (key->ek_client); -kfree_rcu (key, ek_rcu); +kfree (key); +} + +static void expkey_put (struct kref *ref) +{ + struct svc_expkey *key = container_of(ref, struct svc_expkey, h.ref); + +INIT_RCU_WORK (&key->ek_rcu_work, expkey_put_work); +queue_rcu_work (system_wq, &key->ek_rcu_work); }static int expkey_upcall (struct cache_detail *cd,struct cache_head *h)
@@ -351,16 +360,26 @@ static void export_stats_destroy(struct export_stats *stats) EXP_STATS_COUNTERS_NUM); } -static void svc_export_put (struct kref *ref) +static void svc_export_put_work (struct work_struct *work) { - struct svc_export *exp = container_of(ref, struct svc_export, h.ref); +struct svc_export *exp = + container_of(to_rcu_work(work), struct svc_export, ex_rcu_work); +path_put (&exp->ex_path);auth_domain_put (exp->ex_client);nfsd4_fslocs_free (&exp->ex_fslocs);export_stats_destroy (exp->ex_stats);kfree (exp->ex_stats);kfree (exp->ex_uuid); -kfree_rcu (exp, ex_rcu); +kfree (exp); +} + +static void svc_export_put (struct kref *ref) +{ + struct svc_export *exp = container_of(ref, struct svc_export, h.ref); + +INIT_RCU_WORK (&exp->ex_rcu_work, svc_export_put_work); +queue_rcu_work (system_wq, &exp->ex_rcu_work); }static int svc_export_upcall (struct cache_detail *cd,struct cache_head *h)
fs/nfsd/export.h +2 -2
@@ -75,7 +75,7 @@ struct svc_export {u32 ex_layout_types;struct nfsd4_deviceid_map *ex_devid_map;struct cache_detail *cd; -struct rcu_head ex_rcu; +struct rcu_work ex_rcu_work;unsigned long ex_xprtsec_modes;struct export_stats *ex_stats; };
@@ -92,7 +92,7 @@ struct svc_expkey {u32 ek_fsid[6 ];struct path ek_path; -struct rcu_head ek_rcu; +struct rcu_work ek_rcu_work; };#define EX_ISSYNC (exp) (!((exp)->ex_flags & NFSEXP_ASYNC))
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 384/676 svcrdma: fix miss destroy percpu_counter in svc_rdma_proc_init()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ye Bin <[email protected]>
[ Upstream commit ce89e742a4c12b20f09a43fec1b21db33f2166cd ]
There's issue as follows:
RPC: Registered rdma transport module.
RPC: Registered rdma backchannel transport module.
RPC: Unregistered rdma transport module.
RPC: Unregistered rdma backchannel transport module.
BUG: unable to handle page fault for address: fffffbfff80c609a PGD 123fee067 P4D 123fee067 PUD 123fea067 PMD 10c624067 PTE 0 Oops: Oops: 0000 [#1] PREEMPT SMP KASAN NOPTI RIP: 0010:percpu_counter_destroy_many+0xf7/0x2a0 Call Trace: <TASK> __die+0x1f/0x70 page_fault_oops+0x2cd/0x860 spurious_kernel_fault+0x36/0x450 do_kern_addr_fault+0xca/0x100 exc_page_fault+0x128/0x150 asm_exc_page_fault+0x26/0x30 percpu_counter_destroy_many+0xf7/0x2a0 mmdrop+0x209/0x350 finish_task_switch.isra.0+0x481/0x840 schedule_tail+0xe/0xd0 ret_from_fork+0x23/0x80 ret_from_fork_asm+0x1a/0x30 </TASK>
If register_sysctl() return NULL, then svc_rdma_proc_cleanup() will not destroy the percpu counters which init in svc_rdma_proc_init(). If CONFIG_HOTPLUG_CPU is enabled, residual nodes may be in the 'percpu_counters' list. The above issue may occur once the module is removed. If the CONFIG_HOTPLUG_CPU configuration is not enabled, memory leakage occurs.
To solve above issue just destroy all percpu counters when register_sysctl() return NULL.
--- net/sunrpc/xprtrdma/svc_rdma.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-)
net/sunrpc/xprtrdma/svc_rdma.c +14 -5
@@ -234,25 +234,34 @@ static int svc_rdma_proc_init(void) rc =percpu_counter_init (&svcrdma_stat_read,0 ,GFP_KERNEL );if (rc) - goto out_err; + goto err; rc =percpu_counter_init (&svcrdma_stat_recv,0 ,GFP_KERNEL );if (rc) - goto out_err; + goto err_read; rc =percpu_counter_init (&svcrdma_stat_sq_starve,0 ,GFP_KERNEL );if (rc) - goto out_err; + goto err_recv; rc =percpu_counter_init (&svcrdma_stat_write,0 ,GFP_KERNEL );if (rc) - goto out_err; + goto err_sq; svcrdma_table_header =register_sysctl ("sunrpc/svc_rdma" , svcrdma_parm_table); +if (!svcrdma_table_header) + goto err_write; +return 0 ; -out_err: +err_write: + rc = -ENOMEM ; +percpu_counter_destroy (&svcrdma_stat_write); +err_sq:percpu_counter_destroy (&svcrdma_stat_sq_starve); +err_recv:percpu_counter_destroy (&svcrdma_stat_recv); +err_read:percpu_counter_destroy (&svcrdma_stat_read); +err:return rc; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 385/676 NFSD: Fix nfsd4_shutdown_copy()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 62a8642ba00aa8ceb0a02ade942f5ec52e877c95 ]
nfsd4_shutdown_copy() is just this:
while ((copy = nfsd4_get_copy(clp)) != NULL) nfsd4_stop_copy(copy);
nfsd4_get_copy() bumps @copy's reference count, preventing nfsd4_stop_copy() from releasing @copy.
A while loop like this usually works by removing the first element of the list, but neither nfsd4_get_copy() nor nfsd4_stop_copy() alters the async_copies list.
Best I can tell, then, is that nfsd4_shutdown_copy() continues to loop until other threads manage to remove all the items from this list. The spinning loop blocks shutdown until these items are gone.
Possibly the reason we haven't seen this issue in the field is because client_has_state() prevents __destroy_client() from calling nfsd4_shutdown_copy() if there are any items on this list. In a subsequent patch I plan to remove that restriction.
--- fs/nfsd/nfs4proc.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
fs/nfsd/nfs4proc.c +5 -2
@@ -1285,7 +1285,7 @@ static void nfsd4_stop_copy(struct nfsd4_copy *copy)nfs4_put_copy (copy); } -static struct nfsd4_copy *nfsd4_get_copy (struct nfs4_client *clp) +static struct nfsd4_copy *nfsd4_unhash_copy (struct nfs4_client *clp) {struct nfsd4_copy *copy =NULL ;
@@ -1294,6 +1294,9 @@ static struct nfsd4_copy *nfsd4_get_copy(struct nfs4_client *clp) copy = list_first_entry(&clp->async_copies, struct nfsd4_copy, copies);refcount_inc (©->refcount); + copy->cp_clp =NULL ; +if (!list_empty (©->copies)) +list_del_init (©->copies); }spin_unlock (&clp->async_lock);return copy;
@@ -1303,7 +1306,7 @@ void nfsd4_shutdown_copy(struct nfs4_client *clp) {struct nfsd4_copy *copy; -while ((copy =nfsd4_get_copy (clp)) !=NULL ) +while ((copy =nfsd4_unhash_copy (clp)) !=NULL )nfsd4_stop_copy (copy); }#ifdef CONFIG_NFSD_V4_2_INTER_SSC
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 386/676 hwmon: (tps23861) Fix reporting of negative temperatures
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Murad Masimov <[email protected]>
[ Upstream commit de2bf507fabba9c0c678cf5ed54beb546f5ca29a ]
Negative temperatures are reported as large positive temperatures due to missing sign extension from unsigned int to long. Cast unsigned raw register values to signed before performing the calculations to fix the problem.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Message-ID: <[email protected]>
--- drivers/hwmon/tps23861.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/hwmon/tps23861.c +1 -1
@@ -132,7 +132,7 @@ static int tps23861_read_temp(struct tps23861_data *data, long *val)if (err <0 )return err; - *val = (regval *TEMPERATURE_LSB ) -20000 ; + *val = ((long )regval *TEMPERATURE_LSB ) -20000 ;return 0 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 387/676 vdpa/mlx5: Fix suboptimal range on iotlb iteration
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Si-Wei Liu <[email protected]>
[ Upstream commit 35025963326e44d8bced3eecd42d2f040f4f0024 ]
The starting iova address to iterate iotlb map entry within a range was set to an irrelevant value when passing to the itree_next() iterator, although luckily it doesn't affect the outcome of finding out the granule of the smallest iotlb map size. Fix the code to make it consistent with the following for-loop.
Message-Id: <[email protected]>
--- drivers/vdpa/mlx5/core/mr.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/vdpa/mlx5/core/mr.c +1 -3
@@ -227,7 +227,6 @@ static int map_direct_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_direct_mrunsigned long lgcd =0 ;int log_entity_size;unsigned long size; -u64 start =0 ;int err;struct page *pg;unsigned int nsg;
@@ -238,10 +237,9 @@ static int map_direct_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_direct_mrstruct device *dma = mvdev->vdev.dma_dev;for (map =vhost_iotlb_itree_first (iotlb, mr->start, mr->end -1 ); - map; map =vhost_iotlb_itree_next (map, start, mr->end -1 )) { + map; map =vhost_iotlb_itree_next (map, mr->start, mr->end -1 )) { size =maplen (map, mr); lgcd =gcd (lgcd, size); - start += size; } log_entity_size =ilog2 (lgcd);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 388/676 selftests/mount_setattr: Fix failures on 64K PAGE_SIZE kernels
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Ellerman <[email protected]>
[ Upstream commit f13242a46438e690067a4bf47068fde4d5719947 ]
Currently the mount_setattr_test fails on machines with a 64K PAGE_SIZE, with errors such as:
# RUN mount_setattr_idmapped.invalid_fd_negative ...
mkfs.ext4: No space left on device while writing out and closing file system
# mount_setattr_test.c:1055:invalid_fd_negative:Expected system("mkfs.ext4 -q /mnt/C/ext4.img") (256) == 0 (0) # invalid_fd_negative: Test terminated by assertion
# FAIL mount_setattr_idmapped.invalid_fd_negative
not ok 12 mount_setattr_idmapped.invalid_fd_negative
The code creates a 100,000 byte tmpfs:
ASSERT_EQ(mount("testing", "/mnt", "tmpfs", MS_NOATIME | MS_NODEV,
"size=100000,mode=700"), 0);And then a little later creates a 2MB ext4 filesystem in that tmpfs:
ASSERT_EQ(ftruncate(img_fd, 1024 * 2048), 0);
ASSERT_EQ(system("mkfs.ext4 -q /mnt/C/ext4.img"), 0);At first glance it seems like that should never work, after all 2MB is larger than 100,000 bytes. However the filesystem image doesn't actually occupy 2MB on "disk" (actually RAM, due to tmpfs). On 4K kernels the ext4.img uses ~84KB of actual space (according to du), which just fits.
However on 64K PAGE_SIZE kernels the ext4.img takes at least 256KB, which is too large to fit in the tmpfs, hence the errors.
It seems fraught to rely on the ext4.img taking less space on disk than the allocated size, so instead create the tmpfs with a size of 2MB. With that all 21 tests pass on 64K PAGE_SIZE kernels.
--- tools/testing/selftests/mount_setattr/mount_setattr_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/testing/selftests/mount_setattr/mount_setattr_test.c +1 -1
@@ -1026,7 +1026,7 @@ FIXTURE_SETUP(mount_setattr_idmapped) "size=100000,mode=700"), 0);ASSERT_EQ (mount ("testing" ,"/mnt" ,"tmpfs" ,MS_NOATIME |MS_NODEV , -"size=100000,mode=700" ),0 ); +"size=2m,mode=700" ),0 );ASSERT_EQ (mkdir ("/mnt/A" ,0777 ),0 );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 389/676 gpio: zevio: Add missed label initialisation
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko <[email protected]>
[ Upstream commit 5bbed54ba66925ebca19092d0750630f943d7bf2 ]
Initialise the GPIO chip label correctly as it was done by of_mm_gpiochip_add_data() before the below mentioned change.
--- drivers/gpio/gpio-zevio.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/gpio/gpio-zevio.c +6 -0
@@ -11,6 +11,7 @@#include <linux/io.h> #include <linux/mod_devicetable.h> #include <linux/platform_device.h> +#include <linux/property.h> #include <linux/slab.h> #include <linux/spinlock.h>
@@ -169,6 +170,7 @@ static const struct gpio_chip zevio_gpio_chip = {/* Initialization */ static int zevio_gpio_probe (struct platform_device *pdev) { +struct device *dev = &pdev->dev;struct zevio_gpio *controller;int status, i;
@@ -180,6 +182,10 @@ static int zevio_gpio_probe(struct platform_device *pdev) controller->chip = zevio_gpio_chip; controller->chip.parent = &pdev->dev; + controller->chip.label =devm_kasprintf (dev,GFP_KERNEL ,"%pfw" ,dev_fwnode (dev)); +if (!controller->chip.label) +return -ENOMEM ; + controller->regs =devm_platform_ioremap_resource (pdev,0 );if (IS_ERR (controller->regs)) return dev_err_probe(&pdev->dev, PTR_ERR(controller->regs),
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 390/676 vfio/pci: Properly hide first-in-list PCIe extended capability
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Avihai Horon <[email protected]>
[ Upstream commit fe4bf8d0b6716a423b16495d55b35d3fe515905d ]
There are cases where a PCIe extended capability should be hidden from the user. For example, an unknown capability (i.e., capability with ID greater than PCI_EXT_CAP_ID_MAX) or a capability that is intentionally chosen to be hidden from the user.
Hiding a capability is done by virtualizing and modifying the 'Next Capability Offset' field of the previous capability so it points to the capability after the one that should be hidden.
The special case where the first capability in the list should be hidden is handled differently because there is no previous capability that can be modified. In this case, the capability ID and version are zeroed while leaving the next pointer intact. This hides the capability and leaves an anchor for the rest of the capability list.
However, today, hiding the first capability in the list is not done properly if the capability is unknown, as struct vfio_pci_core_device->pci_config_map is set to the capability ID during initialization but the capability ID is not properly checked later when used in vfio_config_do_rw(). This leads to the following warning [1] and to an out-of-bounds access to ecap_perms array.
Fix it by checking cap_id in vfio_config_do_rw(), and if it is greater than PCI_EXT_CAP_ID_MAX, use an alternative struct perm_bits for direct read only access instead of the ecap_perms array.
Note that this is safe since the above is the only case where cap_id can exceed PCI_EXT_CAP_ID_MAX (except for the special capabilities, which are already checked before).
[1]
WARNING: CPU: 118 PID: 5329 at drivers/vfio/pci/vfio_pci_config.c:1900 vfio_pci_config_rw+0x395/0x430 [vfio_pci_core] CPU: 118 UID: 0 PID: 5329 Comm: simx-qemu-syste Not tainted 6.12.0+ #1 (snip) Call Trace: <TASK> ? show_regs+0x69/0x80 ? __warn+0x8d/0x140 ? vfio_pci_config_rw+0x395/0x430 [vfio_pci_core] ? report_bug+0x18f/0x1a0 ? handle_bug+0x63/0xa0 ? exc_invalid_op+0x19/0x70 ? asm_exc_invalid_op+0x1b/0x20 ? vfio_pci_config_rw+0x395/0x430 [vfio_pci_core] ? vfio_pci_config_rw+0x244/0x430 [vfio_pci_core] vfio_pci_rw+0x101/0x1b0 [vfio_pci_core] vfio_pci_core_read+0x1d/0x30 [vfio_pci_core] vfio_device_fops_read+0x27/0x40 [vfio] vfs_read+0xbd/0x340 ? vfio_device_fops_unl_ioctl+0xbb/0x740 [vfio] ? __rseq_handle_notify_resume+0xa4/0x4b0 __x64_sys_pread64+0x96/0xc0 x64_sys_call+0x1c3d/0x20d0 do_syscall_64+0x4d/0x120 entry_SYSCALL_64_after_hwframe+0x76/0x7e
--- drivers/vfio/pci/vfio_pci_config.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-)
drivers/vfio/pci/vfio_pci_config.c +14 -2
@@ -313,6 +313,10 @@ static int vfio_virt_config_read(struct vfio_pci_core_device *vdev, int pos,return count; } +static struct perm_bits direct_ro_perms = { + .readfn = vfio_direct_config_read, +}; +/* Default capability regions to read-only, no-virtualization */ static struct perm_bits cap_perms[PCI_CAP_ID_MAX +1 ] = { [0 ...PCI_CAP_ID_MAX ] = { .readfn = vfio_direct_config_read }
@@ -1897,9 +1901,17 @@ static ssize_t vfio_config_do_rw(struct vfio_pci_core_device *vdev, char __user cap_start = *ppos; }else {if (*ppos >=PCI_CFG_SPACE_SIZE ) { -WARN_ON (cap_id >PCI_EXT_CAP_ID_MAX ); +/* +* We can get a cap_id that exceeds PCI_EXT_CAP_ID_MAX +* if we're hiding an unknown capability at the start +* of the extended capability list. Use default, ro +* access, which will virtualize the id and next values. +*/ +if (cap_id >PCI_EXT_CAP_ID_MAX ) + perm = &direct_ro_perms; +else + perm = &ecap_perms[cap_id]; - perm = &ecap_perms[cap_id]; cap_start =vfio_find_cap_start (vdev, *ppos); }else {WARN_ON (cap_id >PCI_CAP_ID_MAX );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 391/676 fs_parser: update mount_api doc to match function signature
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Randy Dunlap <[email protected]>
[ Upstream commit c66f759832a83cb273ba5a55c66dcc99384efa74 ]
Add the missing 'name' parameter to the mount_api documentation for fs_validate_description().
--- Documentation/filesystems/mount_api.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
Documentation/filesystems/mount_api.rst +2 -1
@@ -766,7 +766,8 @@ process the parameters it is given. * :: - bool fs_validate_description(const struct fs_parameter_description *desc); + bool fs_validate_description(const char *name, + const struct fs_parameter_description *desc); This performs some validation checks on a parameter description. It returns true if the description is good and false if it is not. It will
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 392/676 LoongArch: Fix build failure with GCC 15 (-std=gnu23)
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tiezhu Yang <[email protected]>
[ Upstream commit 947d5d036c788156f09e83e7f16322ffe8124384 ]
Whenever I try to build the kernel with upcoming GCC 15 which defaults to -std=gnu23 I get a build failure:
CC arch/loongarch/vdso/vgetcpu.o
In file included from ./include/uapi/linux/posix_types.h:5,
from ./include/uapi/linux/types.h:14,
from ./include/linux/types.h:6,
from ./include/linux/kasan-checks.h:5,
from ./include/asm-generic/rwonce.h:26,
from ./arch/loongarch/include/generated/asm/rwonce.h:1,
from ./include/linux/compiler.h:317,
from ./include/asm-generic/bug.h:5,
from ./arch/loongarch/include/asm/bug.h:60,
from ./include/linux/bug.h:5,
from ./include/linux/mmdebug.h:5,
from ./include/linux/mm.h:6,
from ./arch/loongarch/include/asm/vdso.h:10,
from arch/loongarch/vdso/vgetcpu.c:6:
./include/linux/stddef.h:11:9: error: expected identifier before 'false'
11 | false = 0,
| ^~~~~
./include/linux/types.h:35:33: error: two or more data types in declaration specifiers
35 | typedef _Bool bool;
| ^~~~
./include/linux/types.h:35:1: warning: useless type name in empty declaration
35 | typedef _Bool bool;
| ^~~~~~~The kernel builds explicitly with -std=gnu11 in top Makefile, but arch/loongarch/vdso does not use KBUILD_CFLAGS from the rest of the kernel, just add -std=gnu11 flag to arch/loongarch/vdso/Makefile.
By the way, commit e8c07082a810 ("Kbuild: move to -std=gnu11") did a similar change for arch/arm64/kernel/vdso32/Makefile.
--- arch/loongarch/vdso/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/loongarch/vdso/Makefile +1 -1
@@ -22,7 +22,7 @@ ccflags-vdso := \ cflags-vdso := $(ccflags-vdso) \ -isystem $(shell $(CC) -print-file-name=include) \ $(filter -W%,$(filter-out -Wa$(comma)%,$(KBUILD_CFLAGS))) \ - -O2 -g -fno-strict-aliasing -fno-common -fno-builtin \ + -std=gnu11 -O2 -g -fno-strict-aliasing -fno-common -fno-builtin \ -fno-stack-protector -fno-jump-tables -DDISABLE_BRANCH_PROFILING \ $(call cc-option, -fno-asynchronous-unwind-tables) \ $(call cc-option, -fno-stack-protector)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 393/676 LoongArch: BPF: Sign-extend return values
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tiezhu Yang <[email protected]>
[ Upstream commit 73c359d1d356cf10236ccd358bd55edab33e9424 ]
(1) Description of Problem:
When testing BPF JIT with the latest compiler toolchains on LoongArch, there exist some strange failed test cases, dmesg shows something like this:
# dmesg -t | grep FAIL | head -1 ... ret -3 != -3 (0xfffffffd != 0xfffffffd)FAIL ...
(2) Steps to Reproduce:
# echo 1 > /proc/sys/net/core/bpf_jit_enable # modprobe test_bpf
(3) Additional Info:
There are no failed test cases compiled with the lower version of GCC such as 13.3.0, while the problems only appear with higher version of GCC such as 14.2.0.
This is because the problems were hidden by the lower version of GCC due to redundant sign extension instructions generated by compiler, but with optimization of higher version of GCC, the sign extension instructions have been removed.
(4) Root Cause Analysis:
The LoongArch architecture does not expose sub-registers, and hold all 32-bit values in a sign-extended format. While BPF, on the other hand, exposes sub-registers, and use zero-extension (similar to arm64/x86).
This has led to some subtle bugs, where a BPF JITted program has not sign-extended the a0 register (return value in LoongArch land), passed the return value up the kernel, for example:
| int from_bpf(void);
|
| long foo(void)
| {
| return from_bpf();
| }Here, a0 would be 0xffffffff instead of the expected 0xffffffffffffffff.
Internally, the LoongArch JIT uses a5 as a dedicated register for BPF return values. That is to say, the LoongArch BPF uses a5 for BPF return values, which are zero-extended, whereas the LoongArch ABI uses a0 which is sign-extended.
(5) Final Solution:
Keep a5 zero-extended, but explicitly sign-extend a0 (which is used outside BPF land). Because libbpf currently defines the return value of an ebpf program as a 32-bit unsigned integer, just use addi.w to extend bit 31 into bits 63 through 32 of a5 to a0. This is similar to commit 2f1b0d3d7331 ("riscv, bpf: Sign-extend return values").
--- arch/loongarch/net/bpf_jit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/loongarch/net/bpf_jit.c +1 -1
@@ -179,7 +179,7 @@ static void __build_epilogue(struct jit_ctx *ctx, bool is_tail_call)if (!is_tail_call) {/* Set return value */ -move_reg (ctx,LOONGARCH_GPR_A0 , regmap[BPF_REG_0 ]); +emit_insn (ctx, addiw,LOONGARCH_GPR_A0 , regmap[BPF_REG_0 ],0 );/* Return to the caller */ emit_insn (ctx, jirl,LOONGARCH_GPR_RA ,LOONGARCH_GPR_ZERO ,0 ); }else {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 394/676 power: supply: core: Remove might_sleep() from power_supply_put()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bart Van Assche <[email protected]>
[ Upstream commit f6da4553ff24a5d1c959c9627c965323adc3d307 ]
The put_device() call in power_supply_put() may call power_supply_dev_release(). The latter function does not sleep so power_supply_put() doesn't sleep either. Hence, remove the might_sleep() call from power_supply_put(). This patch suppresses false positive complaints about calling a sleeping function from atomic context if power_supply_put() is called from atomic context.
--- drivers/power/supply/power_supply_core.c | 2 -- 1 file changed, 2 deletions(-)
drivers/power/supply/power_supply_core.c +0 -2
@@ -480,8 +480,6 @@ EXPORT_SYMBOL_GPL(power_supply_get_by_name);*/ void power_supply_put (struct power_supply *psy) { -might_sleep (); -atomic_dec (&psy->use_cnt);put_device (&psy->dev); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 395/676 power: supply: bq27xxx: Fix registers of bq27426
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Barnabás Czémán <[email protected]>
[ Upstream commit 34f99d3b706a519e556841f405c224ca708b1f54 ]
Correct bq27426 registers, according to technical reference manual it does not have Design Capacity register so it is not register compatible with bq27421.
--- drivers/power/supply/bq27xxx_battery.c | 37 ++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-)
drivers/power/supply/bq27xxx_battery.c +35 -2
@@ -449,9 +449,29 @@ static u8 [BQ27XXX_REG_AP ] =0x18 ,BQ27XXX_DM_REG_ROWS , }, + bq27426_regs[BQ27XXX_REG_MAX ] = { + [BQ27XXX_REG_CTRL ] =0x00 , + [BQ27XXX_REG_TEMP ] =0x02 , + [BQ27XXX_REG_INT_TEMP ] =0x1e , + [BQ27XXX_REG_VOLT ] =0x04 , + [BQ27XXX_REG_AI ] =0x10 , + [BQ27XXX_REG_FLAGS ] =0x06 , + [BQ27XXX_REG_TTE ] =INVALID_REG_ADDR , + [BQ27XXX_REG_TTF ] =INVALID_REG_ADDR , + [BQ27XXX_REG_TTES ] =INVALID_REG_ADDR , + [BQ27XXX_REG_TTECP ] =INVALID_REG_ADDR , + [BQ27XXX_REG_NAC ] =0x08 , + [BQ27XXX_REG_RC ] =0x0c , + [BQ27XXX_REG_FCC ] =0x0e , + [BQ27XXX_REG_CYCT ] =INVALID_REG_ADDR , + [BQ27XXX_REG_AE ] =INVALID_REG_ADDR , + [BQ27XXX_REG_SOC ] =0x1c , + [BQ27XXX_REG_DCAP ] =INVALID_REG_ADDR , + [BQ27XXX_REG_AP ] =0x18 , +BQ27XXX_DM_REG_ROWS , + }, #define bq27411_regs bq27421_regs #define bq27425_regs bq27421_regs -#define bq27426_regs bq27421_regs #define bq27441_regs bq27421_regs #define bq27621_regs bq27421_regs bq27z561_regs[BQ27XXX_REG_MAX ] = {
@@ -769,10 +789,23 @@ static enum power_supply_property bq27421_props[] = { };#define bq27411_props bq27421_props#define bq27425_props bq27421_props -#define bq27426_props bq27421_props#define bq27441_props bq27421_props#define bq27621_props bq27421_props +static enum power_supply_property bq27426_props[] = { +POWER_SUPPLY_PROP_STATUS , +POWER_SUPPLY_PROP_PRESENT , +POWER_SUPPLY_PROP_VOLTAGE_NOW , +POWER_SUPPLY_PROP_CURRENT_NOW , +POWER_SUPPLY_PROP_CAPACITY , +POWER_SUPPLY_PROP_CAPACITY_LEVEL , +POWER_SUPPLY_PROP_TEMP , +POWER_SUPPLY_PROP_TECHNOLOGY , +POWER_SUPPLY_PROP_CHARGE_FULL , +POWER_SUPPLY_PROP_CHARGE_NOW , +POWER_SUPPLY_PROP_MANUFACTURER , +}; +static enum power_supply_property bq27z561_props[] = {POWER_SUPPLY_PROP_STATUS ,POWER_SUPPLY_PROP_PRESENT ,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 396/676 power: supply: rt9471: Fix wrong WDT function regfield declaration
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: ChiYuan Huang <[email protected]>
[ Upstream commit d10ff07dd2b933e3864c592ca932996b07bbf22a ]
Fix F_WDT and F_WDT_RST wrong regfield declaration.
--- drivers/power/supply/rt9471.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/power/supply/rt9471.c +2 -2
@@ -153,8 +153,8 @@ struct rt9471_chip { };static const struct reg_field rt9471_reg_fields[F_MAX_FIELDS ] = { - [F_WDT ] =REG_FIELD (RT9471_REG_TOP ,0 ,0 ), - [F_WDT_RST ] =REG_FIELD (RT9471_REG_TOP ,1 ,1 ), + [F_WDT ] =REG_FIELD (RT9471_REG_TOP ,0 ,1 ), + [F_WDT_RST ] =REG_FIELD (RT9471_REG_TOP ,2 ,2 ), [F_CHG_EN ] =REG_FIELD (RT9471_REG_FUNC ,0 ,0 ), [F_HZ ] =REG_FIELD (RT9471_REG_FUNC ,5 ,5 ), [F_BATFET_DIS ] =REG_FIELD (RT9471_REG_FUNC ,7 ,7 ),
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 397/676 power: supply: rt9471: Use IC status regfield to report real charger status
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: ChiYuan Huang <[email protected]>
[ Upstream commit c46a9ee5c6210682611d3d4276436c23a95e1996 ]
Use IC status regfield to rewrite the 'get_staus' function. The original one cannot cover some special scenario like as charger OTG or JEITA case.
--- drivers/power/supply/rt9471.c | 48 ++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 17 deletions(-)
drivers/power/supply/rt9471.c +31 -17
@@ -139,6 +139,19 @@ enum { RT9471_PORTSTAT_DCP, }; +enum { +RT9471_ICSTAT_SLEEP =0 , +RT9471_ICSTAT_VBUSRDY , +RT9471_ICSTAT_TRICKLECHG , +RT9471_ICSTAT_PRECHG , +RT9471_ICSTAT_FASTCHG , +RT9471_ICSTAT_IEOC , +RT9471_ICSTAT_BGCHG , +RT9471_ICSTAT_CHGDONE , +RT9471_ICSTAT_CHGFAULT , +RT9471_ICSTAT_OTG =15 , +}; +struct rt9471_chip {struct device *dev;struct regmap *regmap;
@@ -255,31 +268,32 @@ static int rt9471_get_ieoc(struct rt9471_chip *chip, int *microamp)static int rt9471_get_status (struct rt9471_chip *chip,int *status) { -unsigned int chg_ready, chg_done, fault_stat; +unsigned int ic_stat;int ret; - ret =regmap_field_read (chip->rm_fields[F_ST_CHG_RDY ], &chg_ready); -if (ret) -return ret; - - ret =regmap_field_read (chip->rm_fields[F_ST_CHG_DONE ], &chg_done); + ret =regmap_field_read (chip->rm_fields[F_IC_STAT ], &ic_stat);if (ret)return ret; - ret =regmap_read (chip->regmap,RT9471_REG_STAT1 , &fault_stat); -if (ret) -return ret; - - fault_stat &=RT9471_CHGFAULT_MASK ; - -if (chg_ready && chg_done) - *status =POWER_SUPPLY_STATUS_FULL ; -else if (chg_ready && fault_stat) +switch (ic_stat) { +case RT9471_ICSTAT_VBUSRDY : +case RT9471_ICSTAT_CHGFAULT : *status =POWER_SUPPLY_STATUS_NOT_CHARGING ; -else if (chg_ready && !fault_stat) +break ; + case RT9471_ICSTAT_TRICKLECHG ... RT9471_ICSTAT_BGCHG: *status =POWER_SUPPLY_STATUS_CHARGING ; -else +break ; +case RT9471_ICSTAT_CHGDONE : + *status =POWER_SUPPLY_STATUS_FULL ; +break ; +case RT9471_ICSTAT_SLEEP : +case RT9471_ICSTAT_OTG : *status =POWER_SUPPLY_STATUS_DISCHARGING ; +break ; +default : + *status =POWER_SUPPLY_STATUS_UNKNOWN ; +break ; + }return 0 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 398/676 net: usb: lan78xx: Fix double free issue with interrupt buffer allocation
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oleksij Rempel <[email protected]>
[ Upstream commit 03819abbeb11117dcbba40bfe322b88c0c88a6b6 ]
In lan78xx_probe(), the buffer buf was being freed twice: once implicitly through usb_free_urb(dev->urb_intr) with the URB_FREE_BUFFER flag and again explicitly by kfree(buf). This caused a double free issue.
To resolve this, reordered kmalloc() and usb_alloc_urb() calls to simplify the initialization sequence and removed the redundant kfree(buf). Now, buf is allocated after usb_alloc_urb(), ensuring it is correctly managed by usb_fill_int_urb() and freed by usb_free_urb() as intended.
--- drivers/net/usb/lan78xx.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-)
drivers/net/usb/lan78xx.c +14 -15
@@ -4414,29 +4414,30 @@ static int lan78xx_probe(struct usb_interface *intf, period = ep_intr->desc.bInterval; maxp =usb_maxpacket (dev->udev, dev->pipe_intr); - buf =kmalloc (maxp,GFP_KERNEL ); -if (!buf) { + + dev->urb_intr =usb_alloc_urb (0 ,GFP_KERNEL ); +if (!dev->urb_intr) { ret = -ENOMEM ; goto out5; } - dev->urb_intr =usb_alloc_urb (0 ,GFP_KERNEL ); -if (!dev->urb_intr) { + buf =kmalloc (maxp,GFP_KERNEL ); +if (!buf) { ret = -ENOMEM ; - goto out6; - }else { -usb_fill_int_urb (dev->urb_intr, dev->udev, - dev->pipe_intr, buf, maxp, - intr_complete, dev, period); - dev->urb_intr->transfer_flags |=URB_FREE_BUFFER ; + goto free_urbs; } +usb_fill_int_urb (dev->urb_intr, dev->udev, + dev->pipe_intr, buf, maxp, + intr_complete, dev, period); + dev->urb_intr->transfer_flags |=URB_FREE_BUFFER ; + dev->maxpacket =usb_maxpacket (dev->udev, dev->pipe_out);/* Reject broken descriptors. */ if (dev->maxpacket ==0 ) { ret = -ENODEV ; - goto out6; + goto free_urbs; }/* driver requires remote-wakeup capability during autosuspend. */
@@ -4444,7 +4445,7 @@ static int lan78xx_probe(struct usb_interface *intf, ret =lan78xx_phy_init (dev);if (ret <0 ) - goto out7; + goto free_urbs; ret =register_netdev (netdev);if (ret !=0 ) {
@@ -4466,10 +4467,8 @@ static int lan78xx_probe(struct usb_interface *intf, out8:phy_disconnect (netdev->phydev); -out7: +free_urbs:usb_free_urb (dev->urb_intr); -out6: -kfree (buf); out5:lan78xx_unbind (dev, intf); out4:
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 399/676 net: usb: lan78xx: Fix memory leak on device unplug by freeing PHY device
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oleksij Rempel <[email protected]>
[ Upstream commit ae7370e61c5d8f5bcefc2d4fca724bd4e9bbf789 ]
Add calls to phy_device_free after fixed_phy_unregister to fix a memory leak that occurs when the device is unplugged. This ensures proper cleanup of pseudo fixed-link PHYs.
--- drivers/net/usb/lan78xx.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/net/usb/lan78xx.c +4 -1
@@ -2387,6 +2387,7 @@ static int lan78xx_phy_init(struct lan78xx_net *dev)if (dev->chipid ==ID_REV_CHIP_ID_7801_ ) {if (phy_is_pseudo_fixed_link (phydev)) {fixed_phy_unregister (phydev); +phy_device_free (phydev); }else {phy_unregister_fixup_for_uid (PHY_KSZ9031RNX ,0xfffffff0 );
@@ -4246,8 +4247,10 @@ static void lan78xx_disconnect(struct usb_interface *intf)phy_disconnect (net->phydev); -if (phy_is_pseudo_fixed_link (phydev)) +if (phy_is_pseudo_fixed_link (phydev)) {fixed_phy_unregister (phydev); +phy_device_free (phydev); + }usb_scuttle_anchored_urbs (&dev->deferred);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 400/676 tg3: Set coherent DMA mask bits to 31 for BCM57766 chipsets
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pavan Chebbi <[email protected]>
[ Upstream commit 614f4d166eeeb9bd709b0ad29552f691c0f45776 ]
The hardware on Broadcom 1G chipsets have a known limitation where they cannot handle DMA addresses that cross over 4GB. When such an address is encountered, the hardware sets the address overflow error bit in the DMA status register and triggers a reset.
However, BCM57766 hardware is setting the overflow bit and triggering a reset in some cases when there is no actual underlying address overflow. The hardware team analyzed the issue and concluded that it is happening when the status block update has an address with higher (b16 to b31) bits as 0xffff following a previous update that had lowest bits as 0xffff.
To work around this bug in the BCM57766 hardware, set the coherent dma mask from the current 64b to 31b. This will ensure that upper bits of the status block DMA address are always at most 0x7fff, thus avoiding the improper overflow check described above. This work around is intended for only status block and ring memories and has no effect on TX and RX buffers as they do not require coherent memory.
--- drivers/net/ethernet/broadcom/tg3.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/ethernet/broadcom/tg3.c +3 -0
@@ -17731,6 +17731,9 @@ static int tg3_init_one(struct pci_dev *pdev, }else persist_dma_mask = dma_mask =DMA_BIT_MASK (64 ); +if (tg3_asic_rev (tp) ==ASIC_REV_57766 ) + persist_dma_mask =DMA_BIT_MASK (31 ); +/* Configure DMA attributes. */ if (dma_mask >DMA_BIT_MASK (32 )) { err =dma_set_mask (&pdev->dev, dma_mask);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 401/676 net: usb: lan78xx: Fix refcounting and autosuspend on invalid WoL configuration
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oleksij Rempel <[email protected]>
[ Upstream commit e863ff806f72098bccaf8fa89c80d9ad6187c3b0 ]
Validate Wake-on-LAN (WoL) options in lan78xx_set_wol before calling usb_autopm_get_interface. This prevents USB autopm refcounting issues and ensures the adapter can properly enter autosuspend when invalid WoL options are provided.
--- drivers/net/usb/lan78xx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/net/usb/lan78xx.c +3 -3
@@ -1657,13 +1657,13 @@ static int lan78xx_set_wol(struct net_device *netdev,struct lan78xx_priv *pdata = (struct lan78xx_priv *)(dev->data[0 ]);int ret; +if (wol->wolopts & ~WAKE_ALL ) +return -EINVAL ; + ret =usb_autopm_get_interface (dev->intf);if (ret <0 )return ret; -if (wol->wolopts & ~WAKE_ALL ) -return -EINVAL ; - pdata->wol = wol->wolopts;device_set_wakeup_enable (&dev->udev->dev, (bool )wol->wolopts);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 402/676 net: microchip: vcap: Add typegroup table terminators in kunit tests
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guenter Roeck <[email protected]>
[ Upstream commit f164b296638d1eb1fb1c537e93ab5c8b49966546 ]
VCAP API unit tests fail randomly with errors such as
# vcap_api_iterator_init_test: EXPECTATION FAILED at drivers/net/ethernet/microchip/vcap/vcap_api_kunit.c:387 Expected 134 + 7 == iter.offset, but
134 + 7 == 141 (0x8d)
iter.offset == 17214 (0x433e)
# vcap_api_iterator_init_test: EXPECTATION FAILED at drivers/net/ethernet/microchip/vcap/vcap_api_kunit.c:388
Expected 5 == iter.reg_idx, but
iter.reg_idx == 702 (0x2be)
# vcap_api_iterator_init_test: EXPECTATION FAILED at drivers/net/ethernet/microchip/vcap/vcap_api_kunit.c:389
Expected 11 == iter.reg_bitpos, but
iter.reg_bitpos == 15 (0xf) # vcap_api_iterator_init_test: pass:0 fail:1 skip:0 total:1
Comments in the code state that "A typegroup table ends with an all-zero terminator". Add the missing terminators.
Some of the typegroups did have a terminator of ".offset = 0, .width = 0, .value = 0,". Replace those terminators with "{ }" (no trailing ',') for consistency and to excplicitly state "this is a terminator".
--- .../ethernet/microchip/vcap/vcap_api_kunit.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-)
drivers/net/ethernet/microchip/vcap/vcap_api_kunit.c +10 -7
@@ -366,12 +366,13 @@ static void vcap_api_iterator_init_test(struct kunit *test)struct vcap_typegroup typegroups[] = { { .offset =0 , .width =2 , .value =2 , }, { .offset =156 , .width =1 , .value =0 , }, - { .offset =0 , .width =0 , .value =0 , }, + { } };struct vcap_typegroup typegroups2[] = { { .offset =0 , .width =3 , .value =4 , }, { .offset =49 , .width =2 , .value =0 , }, { .offset =98 , .width =2 , .value =0 , }, + { } };vcap_iter_init (&iter,52 , typegroups,86 );
@@ -399,6 +400,7 @@ static void vcap_api_iterator_next_test(struct kunit *test) { .offset = 147, .width = 3, .value = 0, }, { .offset = 196, .width = 2, .value = 0, }, { .offset = 245, .width = 1, .value = 0, }, + { } }; int idx;
@@ -433,7 +435,7 @@ static void vcap_api_encode_typegroups_test(struct kunit *test) { .offset = 147, .width = 3, .value = 5, }, { .offset = 196, .width = 2, .value = 2, }, { .offset = 245, .width = 5, .value = 27, }, - { .offset = 0, .width = 0, .value = 0, }, + { } }; vcap_encode_typegroups(stream, 49, typegroups, false);
@@ -463,6 +465,7 @@ static void vcap_api_encode_bit_test(struct kunit *test) { .offset = 147, .width = 3, .value = 5, }, { .offset = 196, .width = 2, .value = 2, }, { .offset = 245, .width = 1, .value = 0, }, + { } }; vcap_iter_init(&iter, 49, typegroups, 44);
@@ -489,7 +492,7 @@ static void vcap_api_encode_field_test(struct kunit *test) { .offset = 147, .width = 3, .value = 5, }, { .offset = 196, .width = 2, .value = 2, }, { .offset = 245, .width = 5, .value = 27, }, - { .offset = 0, .width = 0, .value = 0, }, + { } }; struct vcap_field rf = { .type = VCAP_FIELD_U32,
@@ -538,7 +541,7 @@ static void vcap_api_encode_short_field_test(struct kunit *test) { .offset = 0, .width = 3, .value = 7, }, { .offset = 21, .width = 2, .value = 3, }, { .offset = 42, .width = 1, .value = 1, }, - { .offset = 0, .width = 0, .value = 0, }, + { } }; struct vcap_field rf = { .type = VCAP_FIELD_U32,
@@ -608,7 +611,7 @@ static void vcap_api_encode_keyfield_test(struct kunit *test)struct vcap_typegroup tgt[] = { { .offset =0 , .width =2 , .value =2 , }, { .offset =156 , .width =1 , .value =1 , }, - { .offset =0 , .width =0 , .value =0 , }, + { } };vcap_test_api_init (&admin);
@@ -671,7 +674,7 @@ static void vcap_api_encode_max_keyfield_test(struct kunit *test)struct vcap_typegroup tgt[] = { { .offset =0 , .width =2 , .value =2 , }, { .offset =156 , .width =1 , .value =1 , }, - { .offset =0 , .width =0 , .value =0 , }, + { } };u32 keyres[] = {0x928e8a84 ,
@@ -732,7 +735,7 @@ static void vcap_api_encode_actionfield_test(struct kunit *test) { .offset = 0, .width = 2, .value = 2, }, { .offset = 21, .width = 1, .value = 1, }, { .offset = 42, .width = 1, .value = 0, }, - { .offset = 0, .width = 0, .value = 0, }, + { } }; vcap_encode_actionfield(&rule, &caf, &rf, tgt);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 403/676 s390/iucv: MSG_PEEK causes memory leak in iucv_sock_destruct()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sidraya Jayagond <[email protected]>
[ Upstream commit ebaf81317e42aa990ad20b113cfe3a7b20d4e937 ]
Passing MSG_PEEK flag to skb_recv_datagram() increments skb refcount (skb->users) and iucv_sock_recvmsg() does not decrement skb refcount at exit.
This results in skb memory leak in skb_queue_purge() and WARN_ON in iucv_sock_destruct() during socket close. To fix this decrease skb refcount by one if MSG_PEEK is set in order to prevent memory leak and WARN_ON.
WARNING: CPU: 2 PID: 6292 at net/iucv/af_iucv.c:286 iucv_sock_destruct+0x144/0x1a0 [af_iucv]
CPU: 2 PID: 6292 Comm: afiucv_test_msg Kdump: loaded Tainted: G W 6.10.0-rc7 #1
Hardware name: IBM 3931 A01 704 (z/VM 7.3.0)
Call Trace:
[<001587c682c4aa98>] iucv_sock_destruct+0x148/0x1a0 [af_iucv]
[<001587c682c4a9d0>] iucv_sock_destruct+0x80/0x1a0 [af_iucv]
[<001587c704117a32>] __sk_destruct+0x52/0x550
[<001587c704104a54>] __sock_release+0xa4/0x230
[<001587c704104c0c>] sock_close+0x2c/0x40
[<001587c702c5f5a8>] __fput+0x2e8/0x970
[<001587c7024148c4>] task_work_run+0x1c4/0x2c0
[<001587c7023b0716>] do_exit+0x996/0x1050
[<001587c7023b13aa>] do_group_exit+0x13a/0x360
[<001587c7023b1626>] __s390x_sys_exit_group+0x56/0x60
[<001587c7022bccca>] do_syscall+0x27a/0x380
[<001587c7049a6a0c>] __do_syscall+0x9c/0x160
[<001587c7049ce8a8>] system_call+0x70/0x98
Last Breaking-Event-Address:
[<001587c682c4a9d4>] iucv_sock_destruct+0x84/0x1a0 [af_iucv]--- net/iucv/af_iucv.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-)
net/iucv/af_iucv.c +17 -9
@@ -1238,7 +1238,9 @@ static int iucv_sock_recvmsg(struct socket *sock, struct msghdr *msg,return -EOPNOTSUPP ;/* receive/dequeue next skb: -* the function understands MSG_PEEK and, thus, does not dequeue skb */ +* the function understands MSG_PEEK and, thus, does not dequeue skb +* only refcount is increased. +*/ skb =skb_recv_datagram (sk, flags, &err);if (!skb) {if (sk->sk_shutdown &RCV_SHUTDOWN )
@@ -1254,9 +1256,8 @@ static int iucv_sock_recvmsg(struct socket *sock, struct msghdr *msg, cskb = skb;if (skb_copy_datagram_msg (cskb, offset, msg, copied)) { -if (!(flags &MSG_PEEK )) -skb_queue_head (&sk->sk_receive_queue, skb); -return -EFAULT ; + err = -EFAULT ; + goto err_out; }/* SOCK_SEQPACKET: set MSG_TRUNC if recv buf size is too small */
@@ -1273,11 +1274,8 @@ static int iucv_sock_recvmsg(struct socket *sock, struct msghdr *msg, err =put_cmsg (msg,SOL_IUCV ,SCM_IUCV_TRGCLS ,sizeof (IUCV_SKB_CB (skb)->class), (void *)&IUCV_SKB_CB (skb)->class); -if (err) { -if (!(flags &MSG_PEEK )) -skb_queue_head (&sk->sk_receive_queue, skb); -return err; - } +if (err) + goto err_out;/* Mark read part of skb as used */ if (!(flags &MSG_PEEK )) {
@@ -1333,8 +1331,18 @@ static int iucv_sock_recvmsg(struct socket *sock, struct msghdr *msg,/* SOCK_SEQPACKET: return real length if MSG_TRUNC is set */ if (sk->sk_type ==SOCK_SEQPACKET && (flags &MSG_TRUNC )) copied = rlen; +if (flags &MSG_PEEK ) +skb_unref (skb);return copied; + +err_out: +if (!(flags &MSG_PEEK )) +skb_queue_head (&sk->sk_receive_queue, skb); +else +skb_unref (skb); + +return err; }static inline __poll_t iucv_accept_poll (struct sock *parent)
Signature · 1 line
2.43.0