From: "Steven Rostedt (Google)" <rostedt(a)goodmis.org>
The following can crash the kernel:
# cd /sys/kernel/tracing
# echo 'p:sched schedule' > kprobe_events
# exec 5>>events/kprobes/sched/enable
# > kprobe_events
# exec 5>&-
The above commands:
1. Change directory to the tracefs directory
2. Create a kprobe event (doesn't matter what one)
3. Open bash file descriptor 5 on the enable file of the kprobe event
4. Delete the kprobe event (removes the files too)
5. Close the bash file descriptor 5
The above causes a crash!
BUG: kernel NULL pointer dereference, address: 0000000000000028
#PF: supervisor read access in kernel mode
#PF: error_code(0x0000) - not-present page
PGD 0 P4D 0
Oops: 0000 [#1] PREEMPT SMP PTI
CPU: 6 PID: 877 Comm: bash Not tainted 6.5.0-rc4-test-00008-g2c6b6b1029d4-dirty #186
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-debian-1.16.2-1 04/01/2014
RIP: 0010:tracing_release_file_tr+0xc/0x50
What happens here is that the kprobe event creates a trace_event_file
"file" descriptor that represents the file in tracefs to the event. It
maintains state of the event (is it enabled for the given instance?).
Opening the "enable" file gets a reference to the event "file" descriptor
via the open file descriptor. When the kprobe event is deleted, the file is
also deleted from the tracefs system which also frees the event "file"
descriptor.
But as the tracefs file is still opened by user space, it will not be
totally removed until the final dput() is called on it. But this is not
true with the event "file" descriptor that is already freed. If the user
does a write to or simply closes the file descriptor it will reference the
event "file" descriptor that was just freed, causing a use-after-free bug.
To solve this, add a ref count to the event "file" descriptor as well as a
new flag called "FREED". The "file" will not be freed until the last
reference is released. But the FREE flag will be set when the event is
removed to prevent any more modifications to that event from happening,
even if there's still a reference to the event "file" descriptor.
Link: https://lore.kernel.org/linux-trace-kernel/20231031000031.1e705592@gandalf.…
Link: https://lore.kernel.org/linux-trace-kernel/20231031122453.7a48b923@gandalf.…
Cc: stable(a)vger.kernel.org
Cc: Masami Hiramatsu <mhiramat(a)kernel.org>
Cc: Mark Rutland <mark.rutland(a)arm.com>
Fixes: f5ca233e2e66d ("tracing: Increase trace array ref count on enable and filter files")
Reported-by: Beau Belgrave <beaub(a)linux.microsoft.com>
Tested-by: Beau Belgrave <beaub(a)linux.microsoft.com>
Signed-off-by: Steven Rostedt (Google) <rostedt(a)goodmis.org>
---
include/linux/trace_events.h | 4 ++++
kernel/trace/trace.c | 15 +++++++++++++++
kernel/trace/trace.h | 3 +++
kernel/trace/trace_events.c | 31 ++++++++++++++++++++++++++----
kernel/trace/trace_events_filter.c | 3 +++
5 files changed, 52 insertions(+), 4 deletions(-)
diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h
index 12207dc6722d..696f8dc4aa53 100644
--- a/include/linux/trace_events.h
+++ b/include/linux/trace_events.h
@@ -492,6 +492,7 @@ enum {
EVENT_FILE_FL_TRIGGER_COND_BIT,
EVENT_FILE_FL_PID_FILTER_BIT,
EVENT_FILE_FL_WAS_ENABLED_BIT,
+ EVENT_FILE_FL_FREED_BIT,
};
extern struct trace_event_file *trace_get_event_file(const char *instance,
@@ -630,6 +631,7 @@ extern int __kprobe_event_add_fields(struct dynevent_cmd *cmd, ...);
* TRIGGER_COND - When set, one or more triggers has an associated filter
* PID_FILTER - When set, the event is filtered based on pid
* WAS_ENABLED - Set when enabled to know to clear trace on module removal
+ * FREED - File descriptor is freed, all fields should be considered invalid
*/
enum {
EVENT_FILE_FL_ENABLED = (1 << EVENT_FILE_FL_ENABLED_BIT),
@@ -643,6 +645,7 @@ enum {
EVENT_FILE_FL_TRIGGER_COND = (1 << EVENT_FILE_FL_TRIGGER_COND_BIT),
EVENT_FILE_FL_PID_FILTER = (1 << EVENT_FILE_FL_PID_FILTER_BIT),
EVENT_FILE_FL_WAS_ENABLED = (1 << EVENT_FILE_FL_WAS_ENABLED_BIT),
+ EVENT_FILE_FL_FREED = (1 << EVENT_FILE_FL_FREED_BIT),
};
struct trace_event_file {
@@ -671,6 +674,7 @@ struct trace_event_file {
* caching and such. Which is mostly OK ;-)
*/
unsigned long flags;
+ atomic_t ref; /* ref count for opened files */
atomic_t sm_ref; /* soft-mode reference counter */
atomic_t tm_ref; /* trigger-mode reference counter */
};
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 2539cfc20a97..9aebf904ff97 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -4978,6 +4978,20 @@ int tracing_open_file_tr(struct inode *inode, struct file *filp)
if (ret)
return ret;
+ mutex_lock(&event_mutex);
+
+ /* Fail if the file is marked for removal */
+ if (file->flags & EVENT_FILE_FL_FREED) {
+ trace_array_put(file->tr);
+ ret = -ENODEV;
+ } else {
+ event_file_get(file);
+ }
+
+ mutex_unlock(&event_mutex);
+ if (ret)
+ return ret;
+
filp->private_data = inode->i_private;
return 0;
@@ -4988,6 +5002,7 @@ int tracing_release_file_tr(struct inode *inode, struct file *filp)
struct trace_event_file *file = inode->i_private;
trace_array_put(file->tr);
+ event_file_put(file);
return 0;
}
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index 0e1405abf4f7..b7f4ea25a194 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -1669,6 +1669,9 @@ extern void event_trigger_unregister(struct event_command *cmd_ops,
char *glob,
struct event_trigger_data *trigger_data);
+extern void event_file_get(struct trace_event_file *file);
+extern void event_file_put(struct trace_event_file *file);
+
/**
* struct event_trigger_ops - callbacks for trace event triggers
*
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index f9e3e24d8796..f29e815ca5b2 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -990,13 +990,35 @@ static void remove_subsystem(struct trace_subsystem_dir *dir)
}
}
+void event_file_get(struct trace_event_file *file)
+{
+ atomic_inc(&file->ref);
+}
+
+void event_file_put(struct trace_event_file *file)
+{
+ if (WARN_ON_ONCE(!atomic_read(&file->ref))) {
+ if (file->flags & EVENT_FILE_FL_FREED)
+ kmem_cache_free(file_cachep, file);
+ return;
+ }
+
+ if (atomic_dec_and_test(&file->ref)) {
+ /* Count should only go to zero when it is freed */
+ if (WARN_ON_ONCE(!(file->flags & EVENT_FILE_FL_FREED)))
+ return;
+ kmem_cache_free(file_cachep, file);
+ }
+}
+
static void remove_event_file_dir(struct trace_event_file *file)
{
eventfs_remove_dir(file->ei);
list_del(&file->list);
remove_subsystem(file->system);
free_event_filter(file->filter);
- kmem_cache_free(file_cachep, file);
+ file->flags |= EVENT_FILE_FL_FREED;
+ event_file_put(file);
}
/*
@@ -1369,7 +1391,7 @@ event_enable_read(struct file *filp, char __user *ubuf, size_t cnt,
flags = file->flags;
mutex_unlock(&event_mutex);
- if (!file)
+ if (!file || flags & EVENT_FILE_FL_FREED)
return -ENODEV;
if (flags & EVENT_FILE_FL_ENABLED &&
@@ -1403,7 +1425,7 @@ event_enable_write(struct file *filp, const char __user *ubuf, size_t cnt,
ret = -ENODEV;
mutex_lock(&event_mutex);
file = event_file_data(filp);
- if (likely(file)) {
+ if (likely(file && !(file->flags & EVENT_FILE_FL_FREED))) {
ret = tracing_update_buffers(file->tr);
if (ret < 0) {
mutex_unlock(&event_mutex);
@@ -1683,7 +1705,7 @@ event_filter_read(struct file *filp, char __user *ubuf, size_t cnt,
mutex_lock(&event_mutex);
file = event_file_data(filp);
- if (file)
+ if (file && !(file->flags & EVENT_FILE_FL_FREED))
print_event_filter(file, s);
mutex_unlock(&event_mutex);
@@ -2902,6 +2924,7 @@ trace_create_new_event(struct trace_event_call *call,
atomic_set(&file->tm_ref, 0);
INIT_LIST_HEAD(&file->triggers);
list_add(&file->list, &tr->events);
+ event_file_get(file);
return file;
}
diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c
index 33264e510d16..0c611b281a5b 100644
--- a/kernel/trace/trace_events_filter.c
+++ b/kernel/trace/trace_events_filter.c
@@ -2349,6 +2349,9 @@ int apply_event_filter(struct trace_event_file *file, char *filter_string)
struct event_filter *filter = NULL;
int err;
+ if (file->flags & EVENT_FILE_FL_FREED)
+ return -ENODEV;
+
if (!strcmp(strstrip(filter_string), "0")) {
filter_disable(file);
filter = event_filter(file);
--
2.42.0
The quilt patch titled
Subject: scripts/gdb/vmalloc: disable on no-MMU
has been removed from the -mm tree. Its filename was
scripts-gdb-vmalloc-disable-on-no-mmu.patch
This patch was dropped because it was merged into the mm-nonmm-stable branch
of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
------------------------------------------------------
From: Ben Wolsieffer <ben.wolsieffer(a)hefring.com>
Subject: scripts/gdb/vmalloc: disable on no-MMU
Date: Tue, 31 Oct 2023 16:22:36 -0400
vmap_area does not exist on no-MMU, therefore the GDB scripts fail to
load:
Traceback (most recent call last):
File "<...>/vmlinux-gdb.py", line 51, in <module>
import linux.vmalloc
File "<...>/scripts/gdb/linux/vmalloc.py", line 14, in <module>
vmap_area_ptr_type = vmap_area_type.get_type().pointer()
^^^^^^^^^^^^^^^^^^^^^^^^^
File "<...>/scripts/gdb/linux/utils.py", line 28, in get_type
self._type = gdb.lookup_type(self._name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
gdb.error: No struct type named vmap_area.
To fix this, disable the command and add an informative error message if
CONFIG_MMU is not defined, following the example of lx-slabinfo.
Link: https://lkml.kernel.org/r/20231031202235.2655333-2-ben.wolsieffer@hefring.c…
Fixes: 852622bf3616 ("scripts/gdb/vmalloc: add vmallocinfo support")
Signed-off-by: Ben Wolsieffer <ben.wolsieffer(a)hefring.com>
Cc: Jan Kiszka <jan.kiszka(a)siemens.com>
Cc: Kieran Bingham <kbingham(a)kernel.org>
Cc: Kuan-Ying Lee <Kuan-Ying.Lee(a)mediatek.com>
Cc: <stable(a)vger.kernel.org>
Signed-off-by: Andrew Morton <akpm(a)linux-foundation.org>
---
scripts/gdb/linux/constants.py.in | 1 +
scripts/gdb/linux/vmalloc.py | 8 ++++++--
2 files changed, 7 insertions(+), 2 deletions(-)
--- a/scripts/gdb/linux/constants.py.in~scripts-gdb-vmalloc-disable-on-no-mmu
+++ a/scripts/gdb/linux/constants.py.in
@@ -158,3 +158,4 @@ LX_CONFIG(CONFIG_STACKDEPOT)
LX_CONFIG(CONFIG_PAGE_OWNER)
LX_CONFIG(CONFIG_SLUB_DEBUG)
LX_CONFIG(CONFIG_SLAB_FREELIST_HARDENED)
+LX_CONFIG(CONFIG_MMU)
--- a/scripts/gdb/linux/vmalloc.py~scripts-gdb-vmalloc-disable-on-no-mmu
+++ a/scripts/gdb/linux/vmalloc.py
@@ -10,8 +10,9 @@ import gdb
import re
from linux import lists, utils, stackdepot, constants, mm
-vmap_area_type = utils.CachedType('struct vmap_area')
-vmap_area_ptr_type = vmap_area_type.get_type().pointer()
+if constants.LX_CONFIG_MMU:
+ vmap_area_type = utils.CachedType('struct vmap_area')
+ vmap_area_ptr_type = vmap_area_type.get_type().pointer()
def is_vmalloc_addr(x):
pg_ops = mm.page_ops().ops
@@ -25,6 +26,9 @@ class LxVmallocInfo(gdb.Command):
super(LxVmallocInfo, self).__init__("lx-vmallocinfo", gdb.COMMAND_DATA)
def invoke(self, arg, from_tty):
+ if not constants.LX_CONFIG_MMU:
+ raise gdb.GdbError("Requires MMU support")
+
vmap_area_list = gdb.parse_and_eval('vmap_area_list')
for vmap_area in lists.list_for_each_entry(vmap_area_list, vmap_area_ptr_type, "list"):
if not vmap_area['vm']:
_
Patches currently in -mm which might be from ben.wolsieffer(a)hefring.com are
The quilt patch titled
Subject: mm/damon/sysfs: update monitoring target regions for online input commit
has been removed from the -mm tree. Its filename was
mm-damon-sysfs-update-monitoring-target-regions-for-online-input-commit.patch
This patch was dropped because it was merged into the mm-stable branch
of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
------------------------------------------------------
From: SeongJae Park <sj(a)kernel.org>
Subject: mm/damon/sysfs: update monitoring target regions for online input commit
Date: Tue, 31 Oct 2023 17:01:31 +0000
When user input is committed online, DAMON sysfs interface is ignoring the
user input for the monitoring target regions. Such request is valid and
useful for fixed monitoring target regions-based monitoring ops like
'paddr' or 'fvaddr'.
Update the region boundaries as user specified, too. Note that the
monitoring results of the regions that overlap between the latest
monitoring target regions and the new target regions are preserved.
Treat empty monitoring target regions user request as a request to just
make no change to the monitoring target regions. Otherwise, users should
set the monitoring target regions same to current one for every online
input commit, and it could be challenging for dynamic monitoring target
regions update DAMON ops like 'vaddr'. If the user really need to remove
all monitoring target regions, they can simply remove the target and then
create the target again with empty target regions.
Link: https://lkml.kernel.org/r/20231031170131.46972-1-sj@kernel.org
Fixes: da87878010e5 ("mm/damon/sysfs: support online inputs update")
Signed-off-by: SeongJae Park <sj(a)kernel.org>
Cc: <stable(a)vger.kernel.org> [5.19+]
Signed-off-by: Andrew Morton <akpm(a)linux-foundation.org>
---
mm/damon/sysfs.c | 47 ++++++++++++++++++++++++++++-----------------
1 file changed, 30 insertions(+), 17 deletions(-)
--- a/mm/damon/sysfs.c~mm-damon-sysfs-update-monitoring-target-regions-for-online-input-commit
+++ a/mm/damon/sysfs.c
@@ -1150,34 +1150,47 @@ destroy_targets_out:
return err;
}
-static int damon_sysfs_update_target(struct damon_target *target,
- struct damon_ctx *ctx,
- struct damon_sysfs_target *sys_target)
+static int damon_sysfs_update_target_pid(struct damon_target *target, int pid)
{
- struct pid *pid;
- struct damon_region *r, *next;
-
- if (!damon_target_has_pid(ctx))
- return 0;
+ struct pid *pid_new;
- pid = find_get_pid(sys_target->pid);
- if (!pid)
+ pid_new = find_get_pid(pid);
+ if (!pid_new)
return -EINVAL;
- /* no change to the target */
- if (pid == target->pid) {
- put_pid(pid);
+ if (pid_new == target->pid) {
+ put_pid(pid_new);
return 0;
}
- /* remove old monitoring results and update the target's pid */
- damon_for_each_region_safe(r, next, target)
- damon_destroy_region(r, target);
put_pid(target->pid);
- target->pid = pid;
+ target->pid = pid_new;
return 0;
}
+static int damon_sysfs_update_target(struct damon_target *target,
+ struct damon_ctx *ctx,
+ struct damon_sysfs_target *sys_target)
+{
+ int err;
+
+ if (damon_target_has_pid(ctx)) {
+ err = damon_sysfs_update_target_pid(target, sys_target->pid);
+ if (err)
+ return err;
+ }
+
+ /*
+ * Do monitoring target region boundary update only if one or more
+ * regions are set by the user. This is for keeping current monitoring
+ * target results and range easier, especially for dynamic monitoring
+ * target regions update ops like 'vaddr'.
+ */
+ if (sys_target->regions->nr)
+ err = damon_sysfs_set_regions(target, sys_target->regions);
+ return err;
+}
+
static int damon_sysfs_set_targets(struct damon_ctx *ctx,
struct damon_sysfs_targets *sysfs_targets)
{
_
Patches currently in -mm which might be from sj(a)kernel.org are
The quilt patch titled
Subject: mm/damon/sysfs: remove requested targets when online-commit inputs
has been removed from the -mm tree. Its filename was
mm-damon-sysfs-remove-requested-targets-when-online-commit-inputs.patch
This patch was dropped because it was merged into the mm-stable branch
of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
------------------------------------------------------
From: SeongJae Park <sj(a)kernel.org>
Subject: mm/damon/sysfs: remove requested targets when online-commit inputs
Date: Sun, 22 Oct 2023 21:07:33 +0000
damon_sysfs_set_targets(), which updates the targets of the context for
online commitment, do not remove targets that removed from the
corresponding sysfs files. As a result, more than intended targets of the
context can exist and hence consume memory and monitoring CPU resource
more than expected.
Fix it by removing all targets of the context and fill up again using the
user input. This could cause unnecessary memory dealloc and realloc
operations, but this is not a hot code path. Also, note that damon_target
is stateless, and hence no data is lost.
[sj(a)kernel.org: fix unnecessary monitoring results removal]
Link: https://lkml.kernel.org/r/20231028213353.45397-1-sj@kernel.org
Link: https://lkml.kernel.org/r/20231022210735.46409-2-sj@kernel.org
Fixes: da87878010e5 ("mm/damon/sysfs: support online inputs update")
Signed-off-by: SeongJae Park <sj(a)kernel.org>
Cc: Brendan Higgins <brendanhiggins(a)google.com>
Cc: <stable(a)vger.kernel.org> [5.19.x]
Signed-off-by: Andrew Morton <akpm(a)linux-foundation.org>
---
mm/damon/sysfs.c | 68 +++++++++++++++++++++++----------------------
1 file changed, 35 insertions(+), 33 deletions(-)
--- a/mm/damon/sysfs.c~mm-damon-sysfs-remove-requested-targets-when-online-commit-inputs
+++ a/mm/damon/sysfs.c
@@ -1150,58 +1150,60 @@ destroy_targets_out:
return err;
}
-/*
- * Search a target in a context that corresponds to the sysfs target input.
- *
- * Return: pointer to the target if found, NULL if not found, or negative
- * error code if the search failed.
- */
-static struct damon_target *damon_sysfs_existing_target(
- struct damon_sysfs_target *sys_target, struct damon_ctx *ctx)
+static int damon_sysfs_update_target(struct damon_target *target,
+ struct damon_ctx *ctx,
+ struct damon_sysfs_target *sys_target)
{
struct pid *pid;
- struct damon_target *t;
+ struct damon_region *r, *next;
- if (!damon_target_has_pid(ctx)) {
- /* Up to only one target for paddr could exist */
- damon_for_each_target(t, ctx)
- return t;
- return NULL;
- }
+ if (!damon_target_has_pid(ctx))
+ return 0;
- /* ops.id should be DAMON_OPS_VADDR or DAMON_OPS_FVADDR */
pid = find_get_pid(sys_target->pid);
if (!pid)
- return ERR_PTR(-EINVAL);
- damon_for_each_target(t, ctx) {
- if (t->pid == pid) {
- put_pid(pid);
- return t;
- }
+ return -EINVAL;
+
+ /* no change to the target */
+ if (pid == target->pid) {
+ put_pid(pid);
+ return 0;
}
- put_pid(pid);
- return NULL;
+
+ /* remove old monitoring results and update the target's pid */
+ damon_for_each_region_safe(r, next, target)
+ damon_destroy_region(r, target);
+ put_pid(target->pid);
+ target->pid = pid;
+ return 0;
}
static int damon_sysfs_set_targets(struct damon_ctx *ctx,
struct damon_sysfs_targets *sysfs_targets)
{
- int i, err;
+ struct damon_target *t, *next;
+ int i = 0, err;
/* Multiple physical address space monitoring targets makes no sense */
if (ctx->ops.id == DAMON_OPS_PADDR && sysfs_targets->nr > 1)
return -EINVAL;
- for (i = 0; i < sysfs_targets->nr; i++) {
+ damon_for_each_target_safe(t, next, ctx) {
+ if (i < sysfs_targets->nr) {
+ damon_sysfs_update_target(t, ctx,
+ sysfs_targets->targets_arr[i]);
+ } else {
+ if (damon_target_has_pid(ctx))
+ put_pid(t->pid);
+ damon_destroy_target(t);
+ }
+ i++;
+ }
+
+ for (; i < sysfs_targets->nr; i++) {
struct damon_sysfs_target *st = sysfs_targets->targets_arr[i];
- struct damon_target *t = damon_sysfs_existing_target(st, ctx);
- if (IS_ERR(t))
- return PTR_ERR(t);
- if (!t)
- err = damon_sysfs_add_target(st, ctx);
- else
- err = damon_sysfs_set_regions(t, st->regions);
+ err = damon_sysfs_add_target(st, ctx);
if (err)
return err;
}
_
Patches currently in -mm which might be from sj(a)kernel.org are
This is the start of the stable review cycle for the 6.1.61 release.
There are 86 patches in this series, all will be posted as a response
to this one. If anyone has any issues with these being applied, please
let me know.
Responses should be made by Thu, 02 Nov 2023 16:59:03 +0000.
Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.1.61-rc1…
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.1.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Linux 6.1.61-rc1
John Sperbeck <jsperbeck(a)google.com>
objtool/x86: add missing embedded_insn check
Baokun Li <libaokun1(a)huawei.com>
ext4: avoid overlapping preallocations due to overflow
Baokun Li <libaokun1(a)huawei.com>
ext4: fix BUG in ext4_mb_new_inode_pa() due to overflow
Baokun Li <libaokun1(a)huawei.com>
ext4: add two helper functions extent_logical_end() and pa_logical_end()
David Lazar <dlazar(a)gmail.com>
platform/x86: Add s2idle quirk for more Lenovo laptops
Alessandro Carminati <alessandro.carminati(a)gmail.com>
clk: Sanitize possible_parent_show to Handle Return Value of of_clk_get_parent_name
Al Viro <viro(a)zeniv.linux.org.uk>
sparc32: fix a braino in fault handling in csum_and_copy_..._user()
Peter Zijlstra <peterz(a)infradead.org>
perf/core: Fix potential NULL deref
Tony Luck <tony.luck(a)intel.com>
x86/cpu: Add model number for Intel Arrow Lake mobile processor
Thomas Gleixner <tglx(a)linutronix.de>
x86/i8259: Skip probing when ACPI/MADT advertises PCAT compatibility
Peng Fan <peng.fan(a)nxp.com>
nvmem: imx: correct nregs for i.MX6UL
Peng Fan <peng.fan(a)nxp.com>
nvmem: imx: correct nregs for i.MX6SLL
Peng Fan <peng.fan(a)nxp.com>
nvmem: imx: correct nregs for i.MX6ULL
Ekansh Gupta <quic_ekangupt(a)quicinc.com>
misc: fastrpc: Unmap only if buffer is unmapped from DSP
Ekansh Gupta <quic_ekangupt(a)quicinc.com>
misc: fastrpc: Clean buffers on remote invocation failures
Ekansh Gupta <quic_ekangupt(a)quicinc.com>
misc: fastrpc: Free DMA handles for RPC calls with no arguments
Ekansh Gupta <quic_ekangupt(a)quicinc.com>
misc: fastrpc: Reset metadata buffer to avoid incorrect free
Yujie Liu <yujie.liu(a)intel.com>
tracing/kprobes: Fix the description of variable length arguments
Jian Zhang <zhangjian.3032(a)bytedance.com>
i2c: aspeed: Fix i2c bus hang in slave read
Alain Volmat <alain.volmat(a)foss.st.com>
i2c: stm32f7: Fix PEC handling in case of SMBUS transfers
Herve Codina <herve.codina(a)bootlin.com>
i2c: muxes: i2c-demux-pinctrl: Use of_get_i2c_adapter_by_node()
Herve Codina <herve.codina(a)bootlin.com>
i2c: muxes: i2c-mux-gpmux: Use of_get_i2c_adapter_by_node()
Herve Codina <herve.codina(a)bootlin.com>
i2c: muxes: i2c-mux-pinctrl: Use of_get_i2c_adapter_by_node()
Robert Hancock <robert.hancock(a)calian.com>
iio: adc: xilinx-xadc: Correct temperature offset/scale for UltraScale
Robert Hancock <robert.hancock(a)calian.com>
iio: adc: xilinx-xadc: Don't clobber preset voltage/temperature thresholds
Marek Szyprowski <m.szyprowski(a)samsung.com>
iio: exynos-adc: request second interupt only when touchscreen mode is used
Linus Walleij <linus.walleij(a)linaro.org>
iio: afe: rescale: Accept only offset channels
Jens Axboe <axboe(a)kernel.dk>
io_uring/fdinfo: lock SQ thread while retrieving thread cpu/pid
Haibo Li <haibo.li(a)mediatek.com>
kasan: print the original fault addr when access invalid shadow
Khazhismel Kumykov <khazhy(a)chromium.org>
blk-throttle: check for overflow in calculate_bytes_allowed
Damien Le Moal <dlemoal(a)kernel.org>
scsi: sd: Introduce manage_shutdown device flag
Michal Schmidt <mschmidt(a)redhat.com>
iavf: in iavf_down, disable queues when removing the driver
Sui Jingfeng <suijingfeng(a)loongson.cn>
drm/logicvc: Kconfig: select REGMAP and REGMAP_MMIO
Ivan Vecera <ivecera(a)redhat.com>
i40e: Fix wrong check for I40E_TXR_FLAGS_WB_ON_ITR
Pablo Neira Ayuso <pablo(a)netfilter.org>
gtp: fix fragmentation needed check with gso
Pablo Neira Ayuso <pablo(a)netfilter.org>
gtp: uapi: fix GTPA_MAX
Fred Chen <fred.chenchen03(a)gmail.com>
tcp: fix wrong RTO timeout when received SACK reneging
Douglas Anderson <dianders(a)chromium.org>
r8152: Release firmware if we have an error in probe
Douglas Anderson <dianders(a)chromium.org>
r8152: Cancel hw_phy_work if we have an error in probe
Douglas Anderson <dianders(a)chromium.org>
r8152: Run the unload routine if we have errors during probe
Douglas Anderson <dianders(a)chromium.org>
r8152: Increase USB control msg timeout to 5000ms as per spec
Shigeru Yoshida <syoshida(a)redhat.com>
net: usb: smsc95xx: Fix uninit-value access in smsc95xx_read_reg
Christophe JAILLET <christophe.jaillet(a)wanadoo.fr>
net: ieee802154: adf7242: Fix some potential buffer overflow in adf7242_stats_show()
Dell Jin <dell.jin.code(a)outlook.com>
net: ethernet: adi: adin1110: Fix uninitialized variable
Sasha Neftin <sasha.neftin(a)intel.com>
igc: Fix ambiguity in the ethtool advertising
Eric Dumazet <edumazet(a)google.com>
neighbour: fix various data-races
Mateusz Palczewski <mateusz.palczewski(a)intel.com>
igb: Fix potential memory leak in igb_add_ethtool_nfc_entry
Kunwu Chan <chentao(a)kylinos.cn>
treewide: Spelling fix in comment
Ivan Vecera <ivecera(a)redhat.com>
i40e: Fix I40E_FLAG_VF_VLAN_PRUNING value
Michal Schmidt <mschmidt(a)redhat.com>
iavf: initialize waitqueues before starting watchdog_task
Mirsad Goran Todorovac <mirsad.todorovac(a)alu.unizg.hr>
r8169: fix the KCSAN reported data race in rtl_rx while reading desc->opts1
Mirsad Goran Todorovac <mirsad.todorovac(a)alu.unizg.hr>
r8169: fix the KCSAN reported data-race in rtl_tx while reading TxDescArray[entry].opts1
Mirsad Goran Todorovac <mirsad.todorovac(a)alu.unizg.hr>
r8169: fix the KCSAN reported data-race in rtl_tx() while reading tp->cur_tx
Tony Lindgren <tony(a)atomide.com>
clk: ti: Fix missing omap5 mcbsp functional clock and aliases
Tony Lindgren <tony(a)atomide.com>
clk: ti: Fix missing omap4 mcbsp functional clock and aliases
Hao Ge <gehao(a)kylinos.cn>
firmware/imx-dsp: Fix use_after_free in imx_dsp_setup_channels()
Randy Dunlap <rdunlap(a)infradead.org>
ARM: OMAP: timer32K: fix all kernel-doc warnings
Lukasz Majczak <lma(a)semihalf.com>
drm/dp_mst: Fix NULL deref in get_mst_branch_device_by_guid_helper()
Mario Limonciello <mario.limonciello(a)amd.com>
drm/amd: Disable ASPM for VI w/ all Intel systems
Umesh Nerlige Ramappa <umesh.nerlige.ramappa(a)intel.com>
drm/i915/pmu: Check if pmu is closed before stopping event
Al Viro <viro(a)zeniv.linux.org.uk>
nfsd: lock_rename() needs both directories to live on the same fs
Liam R. Howlett <Liam.Howlett(a)oracle.com>
maple_tree: add GFP_KERNEL to allocations in mas_expected_entries()
Rik van Riel <riel(a)surriel.com>
hugetlbfs: extend hugetlb_vma_lock to private VMAs
Gregory Price <gourry.memverge(a)gmail.com>
mm/migrate: fix do_pages_move for compat pointers
Kemeng Shi <shikemeng(a)huaweicloud.com>
mm/page_alloc: correct start page when guard page debug is enabled
Rik van Riel <riel(a)surriel.com>
hugetlbfs: clear resv_map pointer if mmap fails
Sebastian Ott <sebott(a)redhat.com>
mm: fix vm_brk_flags() to not bail out while holding lock
Christopher Obbard <chris.obbard(a)collabora.com>
arm64: dts: rockchip: Fix i2s0 pin conflict on ROCK Pi 4 boards
Christopher Obbard <chris.obbard(a)collabora.com>
arm64: dts: rockchip: Add i2s0-2ch-bus-bclk-off pins to RK3399
Eric Auger <eric.auger(a)redhat.com>
vhost: Allow null msg.size on VHOST_IOTLB_INVALIDATE
Alexandru Matei <alexandru.matei(a)uipath.com>
vsock/virtio: initialize the_virtio_vsock before using VQs
Xuan Zhuo <xuanzhuo(a)linux.alibaba.com>
virtio_pci: fix the common cfg map size
zhenwei pi <pizhenwei(a)bytedance.com>
virtio-crypto: handle config changed by work queue
Maximilian Heyne <mheyne(a)amazon.de>
virtio-mmio: fix memory leak of vm_dev
Gavin Shan <gshan(a)redhat.com>
virtio_balloon: Fix endless deflation and inflation on arm64
Rodríguez Barbarin, José Javier <JoseJavier.Rodriguez(a)duagon.com>
mcb-lpc: Reallocate memory region to avoid memory overlapping
Rodríguez Barbarin, José Javier <JoseJavier.Rodriguez(a)duagon.com>
mcb: Return actual parsed size when reading chameleon table
Krzysztof Kozlowski <krzysztof.kozlowski(a)linaro.org>
pinctrl: qcom: lpass-lpi: fix concurrent register updates
Johan Hovold <johan+linaro(a)kernel.org>
ASoC: codecs: wcd938x: fix runtime PM imbalance on remove
Johan Hovold <johan+linaro(a)kernel.org>
ASoC: codecs: wcd938x: fix regulator leaks on probe errors
Krzysztof Kozlowski <krzysztof.kozlowski(a)linaro.org>
ASoC: codecs: wcd938x: Simplify with dev_err_probe
Uwe Kleine-König <u.kleine-koenig(a)pengutronix.de>
ASoC: codecs: wcd938x: Convert to platform remove callback returning void
Ulf Hansson <ulf.hansson(a)linaro.org>
mmc: core: Fix error propagation for some ioctl commands
Christian Loehle <CLoehle(a)hyperstone.com>
mmc: block: ioctl: do write error check for spi
Ulf Hansson <ulf.hansson(a)linaro.org>
mmc: core: Align to common busy polling behaviour for mmc ioctls
Roman Kagan <rkagan(a)amazon.de>
KVM: x86/pmu: Truncate counter value to allowed width on write
-------------
Diffstat:
Makefile | 4 +-
arch/arm/boot/dts/omap4-l4-abe.dtsi | 6 ++
arch/arm/boot/dts/omap4-l4.dtsi | 2 +
arch/arm/boot/dts/omap5-l4-abe.dtsi | 6 ++
arch/arm/mach-omap1/timer32k.c | 14 ++---
arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi | 1 +
arch/arm64/boot/dts/rockchip/rk3399.dtsi | 10 +++
arch/sparc/lib/checksum_32.S | 2 +-
arch/x86/include/asm/i8259.h | 2 +
arch/x86/include/asm/intel-family.h | 2 +
arch/x86/kernel/acpi/boot.c | 3 +
arch/x86/kernel/i8259.c | 38 ++++++++---
arch/x86/kvm/pmu.h | 6 ++
arch/x86/kvm/svm/pmu.c | 2 +-
arch/x86/kvm/vmx/pmu_intel.c | 4 +-
block/blk-throttle.c | 6 ++
drivers/ata/libata-scsi.c | 5 +-
drivers/clk/clk.c | 21 ++++---
drivers/clk/ti/clk-44xx.c | 5 ++
drivers/clk/ti/clk-54xx.c | 4 ++
drivers/crypto/virtio/virtio_crypto_common.h | 3 +
drivers/crypto/virtio/virtio_crypto_core.c | 14 ++++-
drivers/firewire/sbp2.c | 1 +
drivers/firmware/imx/imx-dsp.c | 2 +-
drivers/gpu/drm/amd/amdgpu/vi.c | 2 +-
drivers/gpu/drm/display/drm_dp_mst_topology.c | 6 +-
drivers/gpu/drm/i915/i915_pmu.c | 9 +++
drivers/gpu/drm/logicvc/Kconfig | 2 +
drivers/i2c/busses/i2c-aspeed.c | 3 +-
drivers/i2c/busses/i2c-stm32f7.c | 9 ++-
drivers/i2c/muxes/i2c-demux-pinctrl.c | 2 +-
drivers/i2c/muxes/i2c-mux-gpmux.c | 2 +-
drivers/i2c/muxes/i2c-mux-pinctrl.c | 2 +-
drivers/iio/adc/exynos_adc.c | 24 ++++---
drivers/iio/adc/xilinx-xadc-core.c | 39 +++++-------
drivers/iio/adc/xilinx-xadc.h | 2 +
drivers/iio/afe/iio-rescale.c | 19 ++++--
drivers/mcb/mcb-lpc.c | 35 +++++++++--
drivers/mcb/mcb-parse.c | 15 +++--
drivers/misc/fastrpc.c | 34 +++++-----
drivers/mmc/core/block.c | 38 ++++++++---
drivers/mmc/core/mmc_ops.c | 1 +
drivers/net/ethernet/adi/adin1110.c | 2 +-
drivers/net/ethernet/intel/i40e/i40e.h | 2 +-
drivers/net/ethernet/intel/i40e/i40e_txrx.c | 2 +-
drivers/net/ethernet/intel/iavf/iavf_main.c | 7 ++-
drivers/net/ethernet/intel/igb/igb_ethtool.c | 6 +-
drivers/net/ethernet/intel/igc/igc_ethtool.c | 35 ++++++++---
drivers/net/ethernet/realtek/r8169_main.c | 6 +-
drivers/net/ethernet/toshiba/ps3_gelic_wireless.c | 2 +-
drivers/net/gtp.c | 5 +-
drivers/net/ieee802154/adf7242.c | 5 +-
drivers/net/usb/r8152.c | 11 +++-
drivers/net/usb/smsc95xx.c | 4 +-
drivers/nvmem/imx-ocotp.c | 6 +-
drivers/pinctrl/qcom/pinctrl-lpass-lpi.c | 17 +++--
drivers/platform/x86/thinkpad_acpi.c | 73 ++++++++++++++++++++++
drivers/scsi/sd.c | 39 +++++++++++-
drivers/vhost/vhost.c | 4 +-
drivers/virtio/virtio_balloon.c | 6 +-
drivers/virtio/virtio_mmio.c | 19 ++++--
drivers/virtio/virtio_pci_modern_dev.c | 2 +-
fs/ext4/mballoc.c | 51 +++++++--------
fs/ext4/mballoc.h | 14 +++++
fs/nfsd/vfs.c | 12 ++--
include/linux/hugetlb.h | 6 ++
include/linux/kasan.h | 6 +-
include/scsi/scsi_device.h | 20 +++++-
include/uapi/linux/gtp.h | 2 +-
io_uring/fdinfo.c | 18 ++++--
kernel/events/core.c | 3 +-
kernel/trace/trace_kprobe.c | 4 +-
lib/maple_tree.c | 2 +-
lib/test_maple_tree.c | 35 +++++++----
mm/hugetlb.c | 48 +++++++++++---
mm/kasan/report.c | 4 +-
mm/migrate.c | 14 ++++-
mm/mmap.c | 6 +-
mm/page_alloc.c | 2 +-
net/core/neighbour.c | 67 ++++++++++----------
net/ipv4/tcp_input.c | 9 +--
net/vmw_vsock/virtio_transport.c | 18 +++++-
sound/soc/codecs/wcd938x.c | 51 ++++++++-------
tools/include/linux/rwsem.h | 40 ++++++++++++
tools/objtool/check.c | 2 +-
85 files changed, 789 insertions(+), 305 deletions(-)
From: "Steven Rostedt (Google)" <rostedt(a)goodmis.org>
There exists a race between holding a reference of an eventfs_inode dentry
and the freeing of the eventfs_inode. If user space has a dentry held long
enough, it may still be able to access the dentry's eventfs_inode after it
has been freed.
To prevent this, have he eventfs_inode freed via the last dput() (or via
RCU if the eventfs_inode does not have a dentry).
This means reintroducing the eventfs_inode del_list field at a temporary
place to put the eventfs_inode. It needs to mark it as freed (via the
list) but also must invalidate the dentry immediately as the return from
eventfs_remove_dir() expects that they are. But the dentry invalidation
must not be called under the eventfs_mutex, so it must be done after the
eventfs_inode is marked as free (put on a deletion list).
Cc: stable(a)vger.kernel.org
Cc: Ajay Kaher <akaher(a)vmware.com>
Fixes: 5bdcd5f5331a2 ("eventfs: Implement removal of meta data from eventfs")
Signed-off-by: Steven Rostedt (Google) <rostedt(a)goodmis.org>
---
Changes since v5: https://lkml.kernel.org/r/20231031223420.988874091@goodmis.org
- Rebased for this patch series
fs/tracefs/event_inode.c | 146 ++++++++++++++++++---------------------
fs/tracefs/internal.h | 2 +
2 files changed, 69 insertions(+), 79 deletions(-)
diff --git a/fs/tracefs/event_inode.c b/fs/tracefs/event_inode.c
index 8ac9abf7a3d5..0a04ae0ca8c8 100644
--- a/fs/tracefs/event_inode.c
+++ b/fs/tracefs/event_inode.c
@@ -85,8 +85,7 @@ static int eventfs_set_attr(struct mnt_idmap *idmap, struct dentry *dentry,
mutex_lock(&eventfs_mutex);
ei = dentry->d_fsdata;
- /* The LSB is set when the eventfs_inode is being freed */
- if (((unsigned long)ei & 1UL) || ei->is_freed) {
+ if (ei->is_freed) {
/* Do not allow changes if the event is about to be removed. */
mutex_unlock(&eventfs_mutex);
return -ENODEV;
@@ -276,35 +275,17 @@ static void free_ei(struct eventfs_inode *ei)
void eventfs_set_ei_status_free(struct tracefs_inode *ti, struct dentry *dentry)
{
struct tracefs_inode *ti_parent;
- struct eventfs_inode *ei_child, *tmp;
struct eventfs_inode *ei;
int i;
/* The top level events directory may be freed by this */
if (unlikely(ti->flags & TRACEFS_EVENT_TOP_INODE)) {
- LIST_HEAD(ef_del_list);
-
mutex_lock(&eventfs_mutex);
-
ei = ti->private;
-
- /* Record all the top level files */
- list_for_each_entry_srcu(ei_child, &ei->children, list,
- lockdep_is_held(&eventfs_mutex)) {
- list_add_tail(&ei_child->del_list, &ef_del_list);
- }
-
/* Nothing should access this, but just in case! */
ti->private = NULL;
-
mutex_unlock(&eventfs_mutex);
- /* Now safely free the top level files and their children */
- list_for_each_entry_safe(ei_child, tmp, &ef_del_list, del_list) {
- list_del(&ei_child->del_list);
- eventfs_remove_dir(ei_child);
- }
-
free_ei(ei);
return;
}
@@ -319,14 +300,6 @@ void eventfs_set_ei_status_free(struct tracefs_inode *ti, struct dentry *dentry)
if (!ei)
goto out;
- /*
- * If ei was freed, then the LSB bit is set for d_fsdata.
- * But this should not happen, as it should still have a
- * ref count that prevents it. Warn in case it does.
- */
- if (WARN_ON_ONCE((unsigned long)ei & 1))
- goto out;
-
/* This could belong to one of the files of the ei */
if (ei->dentry != dentry) {
for (i = 0; i < ei->nr_entries; i++) {
@@ -336,6 +309,8 @@ void eventfs_set_ei_status_free(struct tracefs_inode *ti, struct dentry *dentry)
if (WARN_ON_ONCE(i == ei->nr_entries))
goto out;
ei->d_children[i] = NULL;
+ } else if (ei->is_freed) {
+ free_ei(ei);
} else {
ei->dentry = NULL;
}
@@ -962,13 +937,65 @@ struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry
return ERR_PTR(-ENOMEM);
}
+static LLIST_HEAD(free_list);
+
+static void eventfs_workfn(struct work_struct *work)
+{
+ struct eventfs_inode *ei, *tmp;
+ struct llist_node *llnode;
+
+ llnode = llist_del_all(&free_list);
+ llist_for_each_entry_safe(ei, tmp, llnode, llist) {
+ /* This dput() matches the dget() from unhook_dentry() */
+ for (int i = 0; i < ei->nr_entries; i++) {
+ if (ei->d_children[i])
+ dput(ei->d_children[i]);
+ }
+ /* This should only get here if it had a dentry */
+ if (!WARN_ON_ONCE(!ei->dentry))
+ dput(ei->dentry);
+ }
+}
+
+static DECLARE_WORK(eventfs_work, eventfs_workfn);
+
static void free_rcu_ei(struct rcu_head *head)
{
struct eventfs_inode *ei = container_of(head, struct eventfs_inode, rcu);
+ if (ei->dentry) {
+ /* Do not free the ei until all references of dentry are gone */
+ if (llist_add(&ei->llist, &free_list))
+ queue_work(system_unbound_wq, &eventfs_work);
+ return;
+ }
+
+ /* If the ei doesn't have a dentry, neither should its children */
+ for (int i = 0; i < ei->nr_entries; i++) {
+ WARN_ON_ONCE(ei->d_children[i]);
+ }
+
free_ei(ei);
}
+static void unhook_dentry(struct dentry *dentry)
+{
+ if (!dentry)
+ return;
+
+ /* Keep the dentry from being freed yet (see eventfs_workfn()) */
+ dget(dentry);
+
+ dentry->d_fsdata = NULL;
+ d_invalidate(dentry);
+ mutex_lock(&eventfs_mutex);
+ /* dentry should now have at least a single reference */
+ WARN_ONCE((int)d_count(dentry) < 1,
+ "dentry %px (%s) less than one reference (%d) after invalidate\n",
+ dentry, dentry->d_name.name, d_count(dentry));
+ mutex_unlock(&eventfs_mutex);
+}
+
/**
* eventfs_remove_rec - remove eventfs dir or file from list
* @ei: eventfs_inode to be removed.
@@ -1006,33 +1033,6 @@ static void eventfs_remove_rec(struct eventfs_inode *ei, struct list_head *head,
list_add_tail(&ei->del_list, head);
}
-static void unhook_dentry(struct dentry **dentry, struct dentry **list)
-{
- if (*dentry) {
- unsigned long ptr = (unsigned long)*list;
-
- /* Keep the dentry from being freed yet */
- dget(*dentry);
-
- /*
- * Paranoid: The dget() above should prevent the dentry
- * from being freed and calling eventfs_set_ei_status_free().
- * But just in case, set the link list LSB pointer to 1
- * and have eventfs_set_ei_status_free() check that to
- * make sure that if it does happen, it will not think
- * the d_fsdata is an eventfs_inode.
- *
- * For this to work, no eventfs_inode should be allocated
- * on a odd space, as the ef should always be allocated
- * to be at least word aligned. Check for that too.
- */
- WARN_ON_ONCE(ptr & 1);
-
- (*dentry)->d_fsdata = (void *)(ptr | 1);
- *list = *dentry;
- *dentry = NULL;
- }
-}
/**
* eventfs_remove_dir - remove eventfs dir or file from list
* @ei: eventfs_inode to be removed.
@@ -1043,40 +1043,28 @@ void eventfs_remove_dir(struct eventfs_inode *ei)
{
struct eventfs_inode *tmp;
LIST_HEAD(ei_del_list);
- struct dentry *dentry_list = NULL;
- struct dentry *dentry;
- int i;
if (!ei)
return;
+ /*
+ * Move the deleted eventfs_inodes onto the ei_del_list
+ * which will also set the is_freed value. Note, this has to be
+ * done under the eventfs_mutex, but the deletions of
+ * the dentries must be done outside the eventfs_mutex.
+ * Hence moving them to this temporary list.
+ */
mutex_lock(&eventfs_mutex);
eventfs_remove_rec(ei, &ei_del_list, 0);
+ mutex_unlock(&eventfs_mutex);
list_for_each_entry_safe(ei, tmp, &ei_del_list, del_list) {
- for (i = 0; i < ei->nr_entries; i++)
- unhook_dentry(&ei->d_children[i], &dentry_list);
- unhook_dentry(&ei->dentry, &dentry_list);
+ for (int i = 0; i < ei->nr_entries; i++)
+ unhook_dentry(ei->d_children[i]);
+ unhook_dentry(ei->dentry);
+ list_del(&ei->del_list);
call_srcu(&eventfs_srcu, &ei->rcu, free_rcu_ei);
}
- mutex_unlock(&eventfs_mutex);
-
- while (dentry_list) {
- unsigned long ptr;
-
- dentry = dentry_list;
- ptr = (unsigned long)dentry->d_fsdata & ~1UL;
- dentry_list = (struct dentry *)ptr;
- dentry->d_fsdata = NULL;
- d_invalidate(dentry);
- mutex_lock(&eventfs_mutex);
- /* dentry should now have at least a single reference */
- WARN_ONCE((int)d_count(dentry) < 1,
- "dentry %px (%s) less than one reference (%d) after invalidate\n",
- dentry, dentry->d_name.name, d_count(dentry));
- mutex_unlock(&eventfs_mutex);
- dput(dentry);
- }
}
/**
diff --git a/fs/tracefs/internal.h b/fs/tracefs/internal.h
index 5f60bcd69289..06a1f220b901 100644
--- a/fs/tracefs/internal.h
+++ b/fs/tracefs/internal.h
@@ -54,10 +54,12 @@ struct eventfs_inode {
void *data;
/*
* Union - used for deletion
+ * @llist: for calling dput() if needed after RCU
* @del_list: list of eventfs_inode to delete
* @rcu: eventfs_inode to delete in RCU
*/
union {
+ struct llist_node llist;
struct list_head del_list;
struct rcu_head rcu;
};
--
2.42.0
From: "Steven Rostedt (Google)" <rostedt(a)goodmis.org>
The eventfs_inode->is_freed was a union with the rcu_head with the
assumption that when it was on the srcu list the head would contain a
pointer which would make "is_freed" true. But that was a wrong assumption
as the rcu head is a single link list where the last element is NULL.
Instead, split the nr_entries integer so that "is_freed" is one bit and
the nr_entries is the next 31 bits. As there shouldn't be more than 10
(currently there's at most 5 to 7 depending on the config), this should
not be a problem.
Cc: stable(a)vger.kernel.org
Cc: Ajay Kaher <akaher(a)vmware.com>
Fixes: 63940449555e7 ("eventfs: Implement eventfs lookup, read, open functions")
Reviewed-by: Masami Hiramatsu (Google) <mhiramat(a)kernel.org>
Signed-off-by: Steven Rostedt (Google) <rostedt(a)goodmis.org>
---
Changes since v5: https://lkml.kernel.org/r/20231031223419.935276916@goodmis.org
- Resynced for this patch series
fs/tracefs/event_inode.c | 2 ++
fs/tracefs/internal.h | 6 +++---
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/fs/tracefs/event_inode.c b/fs/tracefs/event_inode.c
index 9f612a8f009d..1ce73acf3df0 100644
--- a/fs/tracefs/event_inode.c
+++ b/fs/tracefs/event_inode.c
@@ -824,6 +824,8 @@ static void eventfs_remove_rec(struct eventfs_inode *ei, struct list_head *head,
eventfs_remove_rec(ei_child, head, level + 1);
}
+ ei->is_freed = 1;
+
list_del_rcu(&ei->list);
list_add_tail(&ei->del_list, head);
}
diff --git a/fs/tracefs/internal.h b/fs/tracefs/internal.h
index 64fde9490f52..c7d88aaa949f 100644
--- a/fs/tracefs/internal.h
+++ b/fs/tracefs/internal.h
@@ -23,6 +23,7 @@ struct tracefs_inode {
* @d_parent: pointer to the parent's dentry
* @d_children: The array of dentries to represent the files when created
* @data: The private data to pass to the callbacks
+ * @is_freed: Flag set if the eventfs is on its way to be freed
* @nr_entries: The number of items in @entries
*/
struct eventfs_inode {
@@ -38,14 +39,13 @@ struct eventfs_inode {
* Union - used for deletion
* @del_list: list of eventfs_inode to delete
* @rcu: eventfs_inode to delete in RCU
- * @is_freed: node is freed if one of the above is set
*/
union {
struct list_head del_list;
struct rcu_head rcu;
- unsigned long is_freed;
};
- int nr_entries;
+ unsigned int is_freed:1;
+ unsigned int nr_entries:31;
};
static inline struct tracefs_inode *get_tracefs(const struct inode *inode)
--
2.42.0
Hi all,
This series fixes some long-term issues in kernel that preventing
some machine from work properly.
Hopefully that will rescue some system in wild :-)
Thanks
Signed-off-by: Jiaxun Yang <jiaxun.yang(a)flygoat.com>
---
Jiaxun Yang (3):
MIPS: Loongson64: Reserve vgabios memory on boot
MIPS: Loongson64: Enable DMA noncoherent support
MIPS: Loongson64: Handle more memory types passed from firmware
arch/mips/Kconfig | 2 +
arch/mips/include/asm/mach-loongson64/boot_param.h | 9 ++++-
arch/mips/loongson64/env.c | 9 ++++-
arch/mips/loongson64/init.c | 47 ++++++++++++++--------
4 files changed, 48 insertions(+), 19 deletions(-)
---
base-commit: 9c2d379d63450ae464eeab45462e0cb573cd97d0
change-id: 20231101-loongson64_fixes-0afb1b503d1e
Best regards,
--
Jiaxun Yang <jiaxun.yang(a)flygoat.com>
Hi Greg,
I see following build warnings / errors on stable-rc 5.4 branch.
arch/arm/mach-omap2/timer.c:51:10: fatal error: plat/counter-32k.h: No
such file or directory
51 | #include <plat/counter-32k.h>
| ^~~~~~~~~~~~~~~~~~~~
compilation terminated.
Link:
https://storage.tuxsuite.com/public/linaro/lkft/builds/2XXAJIrAB4GOy6jEODeH…
- Naresh
Hi Greg,
I see the following build warning / errors everywhere on stable-rc 5.4 branch.
ld.lld: error: undefined symbol: kallsyms_on_each_symbol
>>> referenced by trace_kprobe.c
>>> trace/trace_kprobe.o:(create_local_trace_kprobe) in archive kernel/built-in.a
>>> referenced by trace_kprobe.c
>>> trace/trace_kprobe.o:(__trace_kprobe_create) in archive kernel/built-in.a
make[1]: *** [Makefile:1227: vmlinux] Error 1
Links,
- https://storage.tuxsuite.com/public/linaro/lkft/builds/2XXALLRIZaXJVcqhff4Z…
- Naresh