[tip: timers/core] posix-timers: Preserve return value in clock_adjtime32()
The following commit has been merged into the timers/core branch of tip: Commit-ID: 2d036dfa5f10df9782f5278fc591d79d283c1fad Gitweb: https://git.kernel.org/tip/2d036dfa5f10df9782f5278fc591d79d283c1fad Author:Chen Jun AuthorDate:Wed, 14 Apr 2021 03:04:49 Committer: Thomas Gleixner CommitterDate: Sat, 17 Apr 2021 14:55:06 +02:00 posix-timers: Preserve return value in clock_adjtime32() The return value on success (>= 0) is overwritten by the return value of put_old_timex32(). That works correct in the fault case, but is wrong for the success case where put_old_timex32() returns 0. Just check the return value of put_old_timex32() and return -EFAULT in case it is not zero. [ tglx: Massage changelog ] Fixes: 3a4d44b61625 ("ntp: Move adjtimex related compat syscalls to native counterparts") Signed-off-by: Chen Jun Signed-off-by: Thomas Gleixner Reviewed-by: Richard Cochran Cc: sta...@vger.kernel.org Link: https://lore.kernel.org/r/20210414030449.90692-1-chenjun...@huawei.com --- kernel/time/posix-timers.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c index bf540f5..dd5697d 100644 --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -1191,8 +1191,8 @@ SYSCALL_DEFINE2(clock_adjtime32, clockid_t, which_clock, err = do_clock_adjtime(which_clock, ); - if (err >= 0) - err = put_old_timex32(utp, ); + if (err >= 0 && put_old_timex32(utp, )) + return -EFAULT; return err; }
[PATCH v2] time: Fix overwrite err unexpected in clock_adjtime32
the correct error is covered by put_old_timex32. Fixes: 3a4d44b61625 ("ntp: Move adjtimex related compat syscalls to native counterparts") Signed-off-by: Chen Jun --- v2: Make "Fixes" tag correct kernel/time/posix-timers.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c index bf540f5a..dd5697d 100644 --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -1191,8 +1191,8 @@ SYSCALL_DEFINE2(clock_adjtime32, clockid_t, which_clock, err = do_clock_adjtime(which_clock, ); - if (err >= 0) - err = put_old_timex32(utp, ); + if (err >= 0 && put_old_timex32(utp, )) + return -EFAULT; return err; } -- 2.9.4
[PATCH] time: Fix overwrite err unexpected in clock_adjtime32
the correct error is covered by put_old_timex32. Fixes: f1f1d5ebd10f ("posix-timers: Introduce a syscall for clock tuning.") Signed-off-by: Chen Jun --- kernel/time/posix-timers.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c index bf540f5a..dd5697d 100644 --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -1191,8 +1191,8 @@ SYSCALL_DEFINE2(clock_adjtime32, clockid_t, which_clock, err = do_clock_adjtime(which_clock, ); - if (err >= 0) - err = put_old_timex32(utp, ); + if (err >= 0 && put_old_timex32(utp, )) + return -EFAULT; return err; } -- 2.9.4
[PATCH 2/2] arm64: stacktrace: Add skip when task == current
On ARM64, cat /sys/kernel/debug/page_owner, all pages return the same stack: stack_trace_save+0x4c/0x78 register_early_stack+0x34/0x70 init_page_owner+0x34/0x230 page_ext_init+0x1bc/0x1dc The reason is that: check_recursive_alloc always return 1 because that entries[0] is always equal to ip (__set_page_owner+0x3c/0x60). The root cause is that: commit 5fc57df2f6fd ("arm64: stacktrace: Convert to ARCH_STACKWALK") make the save_trace save 2 more entries. Add skip in arch_stack_walk when task == current. Fixes: 5fc57df2f6fd ("arm64: stacktrace: Convert to ARCH_STACKWALK") Signed-off-by: Chen Jun --- arch/arm64/kernel/stacktrace.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c index ad20981..c26b0ac 100644 --- a/arch/arm64/kernel/stacktrace.c +++ b/arch/arm64/kernel/stacktrace.c @@ -201,11 +201,12 @@ void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie, if (regs) start_backtrace(, regs->regs[29], regs->pc); - else if (task == current) + else if (task == current) { + ((struct stacktrace_cookie *)cookie)->skip += 2; start_backtrace(, (unsigned long)__builtin_frame_address(0), (unsigned long)arch_stack_walk); - else + } else start_backtrace(, thread_saved_fp(task), thread_saved_pc(task)); -- 2.9.4
[PATCH 0/2] Fix page_owner broken on arm64
On arm64, cat /sys/kernel/debug/page_owner All pages return the same stack stack_trace_save+0x4c/0x78 register_early_stack+0x34/0x70 init_page_owner+0x34/0x230 page_ext_init+0x1bc/0x1dc The reason is arch_stack_walk save 2 more entries than before. To fix it, add skip in arch_stack_walk *** BLURB HERE *** 1. Prepare for 2, move stacktrace_cookie to .h 2. Fix the problem Chen Jun (2): stacktrace: Move struct stacktrace_cookie to stacktrace.h arm64: stacktrace: Add skip when task == current arch/arm64/kernel/stacktrace.c | 5 +++-- include/linux/stacktrace.h | 7 +++ kernel/stacktrace.c| 7 --- 3 files changed, 10 insertions(+), 9 deletions(-) -- 2.9.4
[PATCH 1/2] stacktrace: Move struct stacktrace_cookie to stacktrace.h
ARM64 need to modify the stacktrace_cookie->skip. Signed-off-by: Chen Jun --- include/linux/stacktrace.h | 7 +++ kernel/stacktrace.c| 7 --- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/linux/stacktrace.h b/include/linux/stacktrace.h index 50e2df3..238b276 100644 --- a/include/linux/stacktrace.h +++ b/include/linux/stacktrace.h @@ -25,6 +25,13 @@ unsigned int stack_trace_save_user(unsigned long *store, unsigned int size); /* Internal interfaces. Do not use in generic code */ #ifdef CONFIG_ARCH_STACKWALK +struct stacktrace_cookie { + unsigned long *store; + unsigned intsize; + unsigned intskip; + unsigned intlen; +}; + /** * stack_trace_consume_fn - Callback for arch_stack_walk() * @cookie:Caller supplied pointer handed back by arch_stack_walk() diff --git a/kernel/stacktrace.c b/kernel/stacktrace.c index 9f8117c..b072e8f 100644 --- a/kernel/stacktrace.c +++ b/kernel/stacktrace.c @@ -71,13 +71,6 @@ EXPORT_SYMBOL_GPL(stack_trace_snprint); #ifdef CONFIG_ARCH_STACKWALK -struct stacktrace_cookie { - unsigned long *store; - unsigned intsize; - unsigned intskip; - unsigned intlen; -}; - static bool stack_trace_consume_entry(void *cookie, unsigned long addr) { struct stacktrace_cookie *c = cookie; -- 2.9.4
[PATCH] rockchip: Make cdn_dp_resume depend on CONFIG_PM_SLEEP
If build Image without CONFIG_PM_SLEEP, there would be a compile warning: warning: ‘cdn_dp_resume’ defined but not used [-Wunused-function] Because SET_SYSTEM_SLEEP_PM_OPS will do nothing without CONFIG_PM_SLEEP. Make cdn_dp_resume depend on CONFIG_PM_SLEEP Signed-off-by: Chen Jun --- drivers/gpu/drm/rockchip/cdn-dp-core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c index a4a45daf93f2..063a60d213ba 100644 --- a/drivers/gpu/drm/rockchip/cdn-dp-core.c +++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c @@ -1121,6 +1121,7 @@ static int cdn_dp_suspend(struct device *dev) return ret; } +#ifdef CONFIG_PM_SLEEP static int cdn_dp_resume(struct device *dev) { struct cdn_dp_device *dp = dev_get_drvdata(dev); @@ -1133,6 +1134,7 @@ static int cdn_dp_resume(struct device *dev) return 0; } +#endif static int cdn_dp_probe(struct platform_device *pdev) { -- 2.25.0
[PATCH] recordmcount: use w8 to read relp->r_info in arm64_is_fake_mcount
On little endian system, Use aarch64_be(gcc v7.3) downloaded from linaro.org to build image with CONFIG_CPU_BIG_ENDIAN = y, CONFIG_FTRACE = y, CONFIG_DYNAMIC_FTRACE = y. gcc will create symbols of _mcount but recordmcount can not create mcount_loc for *.o. aarch64_be-linux-gnu-objdump -r fs/namei.o | grep mcount 00d0 R_AARCH64_CALL26 _mcount ... 7190 R_AARCH64_CALL26 _mcount The reason is than funciton arm64_is_fake_mcount can not work correctly. A symbol of _mcount in *.o compiled with big endian compiler likes: 00 00 00 2d 00 00 01 1b w(rp->r_info) will return 0x2d instead of 0x011b. Because w() takes uint32_t as parameter, which truncates rp->r_info. Use w8() instead w() to read relp->r_info Fixes: ea0eada45632 ("recordmcount: only record relocation of type R_AARCH64_CALL26 on arm64.") Signed-off-by: Chen Jun --- scripts/recordmcount.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/recordmcount.c b/scripts/recordmcount.c index b9c2ee7ab43f..cce12e1971d8 100644 --- a/scripts/recordmcount.c +++ b/scripts/recordmcount.c @@ -438,7 +438,7 @@ static int arm_is_fake_mcount(Elf32_Rel const *rp) static int arm64_is_fake_mcount(Elf64_Rel const *rp) { - return ELF64_R_TYPE(w(rp->r_info)) != R_AARCH64_CALL26; + return ELF64_R_TYPE(w8(rp->r_info)) != R_AARCH64_CALL26; } /* 64-bit EM_MIPS has weird ELF64_Rela.r_info. -- 2.25.0
[PATCH] arm64: kernel: Make IPI_WAKEUP under control of CONFIG_ARM64_ACPI_PARKING_PROTOCOL
since commit 5e89c55e4ed81d7abb1ce8828db35fa389dc0e90 ("arm64: kernel: implement ACPI parking protocol") On arm64, IPI 6 will be wasted without setting CONFIG_ARM64_ACPI_PARKING_PROTOCOL. Signed-off-by: Chen Jun --- arch/arm64/kernel/smp.c | 4 1 file changed, 4 insertions(+) diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index ad00f99ee9b0..8b494ad1c61e 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -73,7 +73,9 @@ enum ipi_msg_type { IPI_CPU_CRASH_STOP, IPI_TIMER, IPI_IRQ_WORK, +#ifdef CONFIG_ARM64_ACPI_PARKING_PROTOCOL IPI_WAKEUP, +#endif NR_IPI }; @@ -795,7 +797,9 @@ static const char *ipi_types[NR_IPI] __tracepoint_string = { [IPI_CPU_CRASH_STOP]= "CPU stop (for crash dump) interrupts", [IPI_TIMER] = "Timer broadcast interrupts", [IPI_IRQ_WORK] = "IRQ work interrupts", +#ifdef CONFIG_ARM64_ACPI_PARKING_PROTOCOL [IPI_WAKEUP]= "CPU wake-up interrupts", +#endif }; static void smp_cross_call(const struct cpumask *target, unsigned int ipinr); -- 2.25.0
[RFC PATCH v2] selinux: Fix kmemleak after disabling selinux runtime
From: Chen Jun Kmemleak will report a problem after using "echo 1 > /sys/fs/selinux/disable" to disable selinux on runtime. kmemleak report: unreferenced object 0x901281c208a0 (size 96): comm "swapper/0", pid 1, jiffies 4294668265 (age 692.799s) hex dump (first 32 bytes): 00 40 c8 81 12 90 ff ff 03 00 00 00 05 00 00 00 .@.. 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 backtrace: [<14622ef8>] selinux_sb_alloc_security+0x1b/0xa0 [<044914e1>] security_sb_alloc+0x1d/0x30 [<9f9d5ffd>] alloc_super+0xa7/0x310 [<3c5f0b5b>] sget_fc+0xca/0x230 [<367a9996>] vfs_get_super+0x37/0x110 [<1c47e818>] vfs_get_tree+0x20/0xc0 [<d239b404>] fc_mount+0x9/0x30 [<708a102f>] vfs_kern_mount.part.36+0x6a/0x80 [<5db542fe>] kern_mount+0x1b/0x30 [<51919f9f>] init_sel_fs+0x8b/0x119 [<0f328fe0>] do_one_initcall+0x3f/0x1d0 [<8a6ceb81>] kernel_init_freeable+0x1b4/0x1f2 [<3a425dcd>] kernel_init+0x5/0x110 [<4e8d6c9d>] ret_from_fork+0x22/0x30 "echo 1 > /sys/fs/selinux/disable" will delete the hooks. Any memory alloced by calling HOOKFUNCTION (like call_int_hook(sb_alloc_security, 0, sb)) has no chance to be freed after deleting hooks. Add a flag to mark a hook not be delete when deleting hooks. Signed-off-by: Chen Jun --- include/linux/lsm_hooks.h | 6 +- security/selinux/hooks.c | 20 ++-- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index c503f7ab8afb..85de731b0c74 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -1554,6 +1554,7 @@ struct security_hook_list { struct hlist_head *head; union security_list_options hook; char*lsm; + boolno_del; } __randomize_layout; /* @@ -1582,6 +1583,8 @@ struct lsm_blob_sizes { */ #define LSM_HOOK_INIT(HEAD, HOOK) \ { .head = _hook_heads.HEAD, .hook = { .HEAD = HOOK } } +#define LSM_HOOK_INIT_NO_DEL(HEAD, HOOK) \ + { .head = _hook_heads.HEAD, .hook = { .HEAD = HOOK }, .no_del = 1 } extern struct security_hook_heads security_hook_heads; extern char *lsm_names; @@ -1638,7 +1641,8 @@ static inline void security_delete_hooks(struct security_hook_list *hooks, int i; for (i = 0; i < count; i++) - hlist_del_rcu([i].list); + if (!hooks[i].no_del) + hlist_del_rcu([i].list); } #endif /* CONFIG_SECURITY_SELINUX_DISABLE */ diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 6b1826fc3658..daff084fd1c7 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -6974,8 +6974,8 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(bprm_committing_creds, selinux_bprm_committing_creds), LSM_HOOK_INIT(bprm_committed_creds, selinux_bprm_committed_creds), - LSM_HOOK_INIT(sb_free_security, selinux_sb_free_security), - LSM_HOOK_INIT(sb_free_mnt_opts, selinux_free_mnt_opts), + LSM_HOOK_INIT_NO_DEL(sb_free_security, selinux_sb_free_security), + LSM_HOOK_INIT_NO_DEL(sb_free_mnt_opts, selinux_free_mnt_opts), LSM_HOOK_INIT(sb_remount, selinux_sb_remount), LSM_HOOK_INIT(sb_kern_mount, selinux_sb_kern_mount), LSM_HOOK_INIT(sb_show_options, selinux_sb_show_options), @@ -7081,7 +7081,7 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(ismaclabel, selinux_ismaclabel), LSM_HOOK_INIT(secctx_to_secid, selinux_secctx_to_secid), - LSM_HOOK_INIT(release_secctx, selinux_release_secctx), + LSM_HOOK_INIT_NO_DEL(release_secctx, selinux_release_secctx), LSM_HOOK_INIT(inode_invalidate_secctx, selinux_inode_invalidate_secctx), LSM_HOOK_INIT(inode_notifysecctx, selinux_inode_notifysecctx), LSM_HOOK_INIT(inode_setsecctx, selinux_inode_setsecctx), @@ -7107,7 +7107,7 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(socket_getpeersec_stream, selinux_socket_getpeersec_stream), LSM_HOOK_INIT(socket_getpeersec_dgram, selinux_socket_getpeersec_dgram), - LSM_HOOK_INIT(sk_free_security, selinux_sk_free_security), + LSM_HOOK_INIT_NO_DEL(sk_free_security, selinux_sk_free_security), LSM_HOOK_INIT(sk_clone_security, selinux_sk_clone_security), LSM_HOOK_INIT(sk_getsecid, selinux_sk_getsecid), LSM_HOOK_INIT(sock_graft, selinux_sock_graft), @@ -7121,7 +7121,7 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(se
[PATCH] iommu: Modify the description of iommu_sva_unbind_device
From: Chen Jun iommu_sva_unbind_device has no return value. Remove the description of the return value of the function. Signed-off-by: Chen Jun --- drivers/iommu/iommu.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 8c470f4..bb51d53 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -2995,8 +2995,6 @@ EXPORT_SYMBOL_GPL(iommu_sva_bind_device); * Put reference to a bond between device and address space. The device should * not be issuing any more transaction for this PASID. All outstanding page * requests for this PASID must have been flushed to the IOMMU. - * - * Returns 0 on success, or an error value */ void iommu_sva_unbind_device(struct iommu_sva *handle) { -- 2.7.4
[PATCH] Kconfig: Move CONFIG_DEBUG_KMEMLEAK_TEST to samples/Kconfig
From: Chen Jun commit 1abbef4f51724fb11f09adf0e75275f7cb422a8a ("mm,kmemleak-test.c: move kmemleak-test.c to samples dir") make CONFIG_DEBUG_KMEMLEAK_TEST depend on CONFIG_SAMPLES implicitly. And the dependency cannot be guaranteed by Kconfig. move the definition of CONFIG_DEBUG_KMEMLEAK_TEST from lib/Kconfig.debug to samples/Kconfig. Signed-off-by: Chen Jun --- lib/Kconfig.debug | 8 samples/Kconfig | 8 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 66d44d3..debacdc 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -678,14 +678,6 @@ config DEBUG_KMEMLEAK_MEM_POOL_SIZE fully initialised, this memory pool acts as an emergency one if slab allocations fail. -config DEBUG_KMEMLEAK_TEST - tristate "Simple test for the kernel memory leak detector" - depends on DEBUG_KMEMLEAK && m - help - This option enables a module that explicitly leaks memory. - - If unsure, say N. - config DEBUG_KMEMLEAK_DEFAULT_OFF bool "Default kmemleak to off" depends on DEBUG_KMEMLEAK diff --git a/samples/Kconfig b/samples/Kconfig index 0ed6e4d..15978dd 100644 --- a/samples/Kconfig +++ b/samples/Kconfig @@ -216,4 +216,12 @@ config SAMPLE_WATCH_QUEUE Build example userspace program to use the new mount_notify(), sb_notify() syscalls and the KEYCTL_WATCH_KEY keyctl() function. +config DEBUG_KMEMLEAK_TEST + tristate "Simple test for the kernel memory leak detector" + depends on DEBUG_KMEMLEAK && m + help + This option enables a module that explicitly leaks memory. + + If unsure, say N. + endif # SAMPLES -- 2.7.4
[PATCH -next 4/5] mm/kmemleak-test: use %px instead of %p in print
From: Wei Yongjun Real addresses are used for diagnose issues. Convert %p with %px to print kernel addresses. Signed-off-by: Wei Yongjun Signed-off-by: Chen Jun --- mm/kmemleak-test.c | 34 +- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/mm/kmemleak-test.c b/mm/kmemleak-test.c index e19279ff6aa3..75fe1b8c3226 100644 --- a/mm/kmemleak-test.c +++ b/mm/kmemleak-test.c @@ -40,25 +40,25 @@ static int __init kmemleak_test_init(void) pr_info("Kmemleak testing\n"); /* make some orphan objects */ - pr_info("kmalloc(32) = %p\n", kmalloc(32, GFP_KERNEL)); - pr_info("kmalloc(32) = %p\n", kmalloc(32, GFP_KERNEL)); - pr_info("kmalloc(1024) = %p\n", kmalloc(1024, GFP_KERNEL)); - pr_info("kmalloc(1024) = %p\n", kmalloc(1024, GFP_KERNEL)); - pr_info("kmalloc(2048) = %p\n", kmalloc(2048, GFP_KERNEL)); - pr_info("kmalloc(2048) = %p\n", kmalloc(2048, GFP_KERNEL)); - pr_info("kmalloc(4096) = %p\n", kmalloc(4096, GFP_KERNEL)); - pr_info("kmalloc(4096) = %p\n", kmalloc(4096, GFP_KERNEL)); + pr_info("kmalloc(32) = %px\n", kmalloc(32, GFP_KERNEL)); + pr_info("kmalloc(32) = %px\n", kmalloc(32, GFP_KERNEL)); + pr_info("kmalloc(1024) = %px\n", kmalloc(1024, GFP_KERNEL)); + pr_info("kmalloc(1024) = %px\n", kmalloc(1024, GFP_KERNEL)); + pr_info("kmalloc(2048) = %px\n", kmalloc(2048, GFP_KERNEL)); + pr_info("kmalloc(2048) = %px\n", kmalloc(2048, GFP_KERNEL)); + pr_info("kmalloc(4096) = %px\n", kmalloc(4096, GFP_KERNEL)); + pr_info("kmalloc(4096) = %px\n", kmalloc(4096, GFP_KERNEL)); #ifndef CONFIG_MODULES - pr_info("kmem_cache_alloc(files_cachep) = %p\n", + pr_info("kmem_cache_alloc(files_cachep) = %px\n", kmem_cache_alloc(files_cachep, GFP_KERNEL)); - pr_info("kmem_cache_alloc(files_cachep) = %p\n", + pr_info("kmem_cache_alloc(files_cachep) = %px\n", kmem_cache_alloc(files_cachep, GFP_KERNEL)); #endif - pr_info("vmalloc(64) = %p\n", vmalloc(64)); - pr_info("vmalloc(64) = %p\n", vmalloc(64)); - pr_info("vmalloc(64) = %p\n", vmalloc(64)); - pr_info("vmalloc(64) = %p\n", vmalloc(64)); - pr_info("vmalloc(64) = %p\n", vmalloc(64)); + pr_info("vmalloc(64) = %px\n", vmalloc(64)); + pr_info("vmalloc(64) = %px\n", vmalloc(64)); + pr_info("vmalloc(64) = %px\n", vmalloc(64)); + pr_info("vmalloc(64) = %px\n", vmalloc(64)); + pr_info("vmalloc(64) = %px\n", vmalloc(64)); /* * Add elements to a list. They should only appear as orphan @@ -66,7 +66,7 @@ static int __init kmemleak_test_init(void) */ for (i = 0; i < 10; i++) { elem = kzalloc(sizeof(*elem), GFP_KERNEL); - pr_info("kzalloc(sizeof(*elem)) = %p\n", elem); + pr_info("kzalloc(sizeof(*elem)) = %px\n", elem); if (!elem) return -ENOMEM; INIT_LIST_HEAD(>list); @@ -75,7 +75,7 @@ static int __init kmemleak_test_init(void) for_each_possible_cpu(i) { per_cpu(kmemleak_test_pointer, i) = kmalloc(129, GFP_KERNEL); - pr_info("kmalloc(129) = %p\n", + pr_info("kmalloc(129) = %px\n", per_cpu(kmemleak_test_pointer, i)); } -- 2.25.0
[PATCH -next 5/5] mm/kmemleak-test: Add a test case for alloc_percpu
After insmod kmemleak-test.ko, a leaking for alloc_percpu will be reported as below: kmemleak: alloc_percpu(sizeof(*elem)) = 7dfdd26a2c40 : : unreferenced object 0x7dfdd26a2c40 (size 8): comm "insmod", pid 183, jiffies 4294905864 (age 40.520s) hex dump (first 8 bytes): 00 00 00 00 00 00 00 00 backtrace: [<(ptrval)>] pcpu_alloc+0x3ec/0x8c8 [<(ptrval)>] __alloc_percpu+0x18/0x28 [<(ptrval)>] 0x88df525c [<(ptrval)>] do_one_initcall+0x60/0x1d8 [<(ptrval)>] do_init_module+0x58/0x1d0 [<(ptrval)>] load_module+0x1d8c/0x23d0 [<(ptrval)>] __do_sys_finit_module+0xdc/0xf8 [<(ptrval)>] __arm64_sys_finit_module+0x20/0x30 [<(ptrval)>] el0_svc_common.constprop.3+0x68/0x170 [<(ptrval)>] do_el0_svc+0x24/0x90 [<(ptrval)>] el0_sync_handler+0x13c/0x1a8 [<(ptrval____)>] el0_sync+0x158/0x180 Signed-off-by: Wei Yongjun Signed-off-by: Chen Jun --- mm/kmemleak-test.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mm/kmemleak-test.c b/mm/kmemleak-test.c index 75fe1b8c3226..8f3e4a60166b 100644 --- a/mm/kmemleak-test.c +++ b/mm/kmemleak-test.c @@ -79,6 +79,9 @@ static int __init kmemleak_test_init(void) per_cpu(kmemleak_test_pointer, i)); } + pr_info("alloc_percpu(sizeof(*elem)) = %px\n", + alloc_percpu(sizeof(*elem))); + return 0; } module_init(kmemleak_test_init); -- 2.25.0
[PATCH -next 0/5] mm/kmemleak:support for percpu memory leak detect
Currently the reporting of the percpu chunks leaking problem are not supported. This patch set introduce this feature. PATCH 1-2 do some cleanup to current kmemleak. PATCH 3 make percpu memleak works. PATCH 4-5 add test case for percpu memleak detector. Following links are some real cases detected by it: [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=71e843295c680898959b22dc877ae3839cc22470 [2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=667e57da358f61b6966e12e925a69e42d912e8bb *** BLURB HERE *** Chen Jun (1): mm/kmemleak-test: Add a test case for alloc_percpu Wei Yongjun (4): mm/kmemleak: make create_object return void mm/kmemleak: skip update_checksum for OBJECT_NO_SCAN objects mm/kmemleak: Add support for percpu memory leak detect mm/kmemleak-test: use %px instead of %p in print mm/kmemleak-test.c | 37 -- mm/kmemleak.c | 79 +- 2 files changed, 84 insertions(+), 32 deletions(-) -- 2.25.0
[PATCH -next 2/5] mm/kmemleak: skip update_checksum for OBJECT_NO_SCAN objects
From: Wei Yongjun Objects marked with OBJECT_NO_SCAN are never scanned. So there is no need to update checksum for them. Signed-off-by: Wei Yongjun Signed-off-by: Chen Jun --- mm/kmemleak.c | 4 1 file changed, 4 insertions(+) diff --git a/mm/kmemleak.c b/mm/kmemleak.c index b3f603fd9fc3..c09c6b59eda6 100644 --- a/mm/kmemleak.c +++ b/mm/kmemleak.c @@ -1166,6 +1166,10 @@ static bool update_checksum(struct kmemleak_object *object) { u32 old_csum = object->checksum; + /* always return false for not scan object */ + if (object->flags & OBJECT_NO_SCAN) + return false; + kasan_disable_current(); kcsan_disable_current(); object->checksum = crc32(0, (void *)object->pointer, object->size); -- 2.25.0
[PATCH -next 3/5] mm/kmemleak: Add support for percpu memory leak detect
From: Wei Yongjun Currently the reporting of the percpu chunks leaking problem are not supported. This patch introduces this function. Since __percpu pointer is not pointing directly to the actual chunks, this patch creates an object for __percpu pointer, but marks it as no scan block, only check whether this pointer is referenced by other blocks. Introduce two global variables, min_percpu_addr and max_percpu_addr, to store the range of valid percpu pointer values, in order to speed up pointer lookup when scanning blocks. Signed-off-by: Wei Yongjun Signed-off-by: Chen Jun --- mm/kmemleak.c | 71 ++- 1 file changed, 59 insertions(+), 12 deletions(-) diff --git a/mm/kmemleak.c b/mm/kmemleak.c index c09c6b59eda6..feedb72f06f2 100644 --- a/mm/kmemleak.c +++ b/mm/kmemleak.c @@ -170,6 +170,8 @@ struct kmemleak_object { #define OBJECT_NO_SCAN (1 << 2) /* flag set to fully scan the object when scan_area allocation failed */ #define OBJECT_FULL_SCAN (1 << 3) +/* flag set to percpu ptr object */ +#define OBJECT_PERCPU (1 << 4) #define HEX_PREFIX "" /* number of bytes to print per line; must be 16 or 32 */ @@ -212,6 +214,9 @@ static int kmemleak_error; /* minimum and maximum address that may be valid pointers */ static unsigned long min_addr = ULONG_MAX; static unsigned long max_addr; +/* minimum and maximum address that may be valid percpu pointers */ +static unsigned long min_percpu_addr = ULONG_MAX; +static unsigned long max_percpu_addr; static struct task_struct *scan_thread; /* used to avoid reporting of recently allocated objects */ @@ -283,6 +288,9 @@ static void hex_dump_object(struct seq_file *seq, const u8 *ptr = (const u8 *)object->pointer; size_t len; + if (object->flags & OBJECT_PERCPU) + ptr = this_cpu_ptr((void __percpu *)object->pointer); + /* limit the number of lines to HEX_MAX_LINES */ len = min_t(size_t, object->size, HEX_MAX_LINES * HEX_ROW_SIZE); @@ -563,17 +571,32 @@ static int __save_stack_trace(unsigned long *trace) return stack_trace_save(trace, MAX_TRACE, 2); } +static void __update_address_range(struct kmemleak_object *object) +{ + unsigned long ptr = object->pointer; + size_t size = object->size; + unsigned long untagged_ptr; + + if (object->flags & OBJECT_PERCPU) { + min_percpu_addr = min(min_percpu_addr, ptr); + max_percpu_addr = max(max_percpu_addr, ptr + size); + } else { + untagged_ptr = (unsigned long)kasan_reset_tag((void *)ptr); + min_addr = min(min_addr, untagged_ptr); + max_addr = max(max_addr, untagged_ptr + size); + } +} + /* * Create the metadata (struct kmemleak_object) corresponding to an allocated * memory block and add it to the object_list and object_tree_root. */ -static void create_object(unsigned long ptr, size_t size, int min_count, - gfp_t gfp) +static void __create_object(unsigned long ptr, size_t size, int min_count, + unsigned int obj_flags, gfp_t gfp) { unsigned long flags; struct kmemleak_object *object, *parent; struct rb_node **link, *rb_parent; - unsigned long untagged_ptr; object = mem_pool_alloc(gfp); if (!object) { @@ -587,7 +610,7 @@ static void create_object(unsigned long ptr, size_t size, int min_count, INIT_HLIST_HEAD(>area_list); raw_spin_lock_init(>lock); atomic_set(>use_count, 1); - object->flags = OBJECT_ALLOCATED; + object->flags = OBJECT_ALLOCATED | obj_flags; object->pointer = ptr; object->size = size; object->excess_ref = 0; @@ -619,9 +642,7 @@ static void create_object(unsigned long ptr, size_t size, int min_count, raw_spin_lock_irqsave(_lock, flags); - untagged_ptr = (unsigned long)kasan_reset_tag((void *)ptr); - min_addr = min(min_addr, untagged_ptr); - max_addr = max(max_addr, untagged_ptr + size); + __update_address_range(object); link = _tree_root.rb_node; rb_parent = NULL; while (*link) { @@ -651,6 +672,19 @@ static void create_object(unsigned long ptr, size_t size, int min_count, raw_spin_unlock_irqrestore(_lock, flags); } +static void create_object(unsigned long ptr, size_t size, int min_count, + gfp_t gfp) +{ + __create_object(ptr, size, min_count, 0, gfp); +} + +static void create_object_percpu(unsigned long ptr, size_t size, int min_count, +gfp_t gfp) +{ + __create_object(ptr, size, min_count, OBJECT_PERCPU | OBJECT_NO_SCAN, + gfp); +} + /* * Mark the object as not allocated and schedule RCU freeing via put_object(). */ @@ -912,10 +
[PATCH -next 1/5] mm/kmemleak: make create_object return void
From: Wei Yongjun No user cares about the return value of create_object, so make it return void. Signed-off-by: Wei Yongjun Signed-off-by: Chen Jun --- mm/kmemleak.c | 8 +++- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/mm/kmemleak.c b/mm/kmemleak.c index c0014d3b91c1..b3f603fd9fc3 100644 --- a/mm/kmemleak.c +++ b/mm/kmemleak.c @@ -567,8 +567,8 @@ static int __save_stack_trace(unsigned long *trace) * Create the metadata (struct kmemleak_object) corresponding to an allocated * memory block and add it to the object_list and object_tree_root. */ -static struct kmemleak_object *create_object(unsigned long ptr, size_t size, -int min_count, gfp_t gfp) +static void create_object(unsigned long ptr, size_t size, int min_count, + gfp_t gfp) { unsigned long flags; struct kmemleak_object *object, *parent; @@ -579,7 +579,7 @@ static struct kmemleak_object *create_object(unsigned long ptr, size_t size, if (!object) { pr_warn("Cannot allocate a kmemleak_object structure\n"); kmemleak_disable(); - return NULL; + return; } INIT_LIST_HEAD(>object_list); @@ -640,7 +640,6 @@ static struct kmemleak_object *create_object(unsigned long ptr, size_t size, */ dump_object_info(parent); kmem_cache_free(object_cache, object); - object = NULL; goto out; } } @@ -650,7 +649,6 @@ static struct kmemleak_object *create_object(unsigned long ptr, size_t size, list_add_tail_rcu(>object_list, _list); out: raw_spin_unlock_irqrestore(_lock, flags); - return object; } /* -- 2.25.0
RE: [PATCH] serial: ifx6x60: ifx_spi_write don't need to do mrdy_assert when fifo is not empty.
Hi, I make this patch on your tty-next tree, Do I need to make it on the branch 3.7-rc6 against? -Original Message- From: Greg KH [mailto:gre...@linuxfoundation.org] Sent: Friday, November 16, 2012 8:39 PM To: Chen, Jun D Cc: Alan Cox; Bi, Chao; serial; Gorby, Russ; linux-kernel@vger.kernel.org; Wu, Fengguang Subject: Re: [PATCH] serial: ifx6x60: ifx_spi_write don't need to do mrdy_assert when fifo is not empty. On Fri, Nov 16, 2012 at 06:08:37AM -0500, Jun Chen wrote: > > This patch check whether the fifo lenth is empty before writing new > data to fifo.If condition is true,ifx_spi_write need to trigger one > mrdy_assert. If condition is false,the mrdy_assert will be trigger by the > next ifx_spi_io. > > Cc: Bi Chao > Signed-off-by: Chen Jun > --- > drivers/tty/serial/ifx6x60.c | 14 +++--- > 1 files changed, 11 insertions(+), 3 deletions(-) What tree did you make this against? It doesn't apply to my tty-next tree at all :( greg k-h -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
RE: [PATCH] serial: ifx6x60: ifx_spi_write don't need to do mrdy_assert when fifo is not empty.
Hi, I make this patch on your tty-next tree, Do I need to make it on the branch 3.7-rc6 against? -Original Message- From: Greg KH [mailto:gre...@linuxfoundation.org] Sent: Friday, November 16, 2012 8:39 PM To: Chen, Jun D Cc: Alan Cox; Bi, Chao; serial; Gorby, Russ; linux-kernel@vger.kernel.org; Wu, Fengguang Subject: Re: [PATCH] serial: ifx6x60: ifx_spi_write don't need to do mrdy_assert when fifo is not empty. On Fri, Nov 16, 2012 at 06:08:37AM -0500, Jun Chen wrote: This patch check whether the fifo lenth is empty before writing new data to fifo.If condition is true,ifx_spi_write need to trigger one mrdy_assert. If condition is false,the mrdy_assert will be trigger by the next ifx_spi_io. Cc: Bi Chao chao...@intel.com Signed-off-by: Chen Jun jun.d.c...@intel.com --- drivers/tty/serial/ifx6x60.c | 14 +++--- 1 files changed, 11 insertions(+), 3 deletions(-) What tree did you make this against? It doesn't apply to my tty-next tree at all :( greg k-h -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/