⚠ This page is served via a proxy. Original site: https://github.com
This service does not collect credentials or authentication data.
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions arch/riscv/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1367,6 +1367,12 @@ config BUILTIN_DTB_NAME
DTS file path (without suffix, relative to arch/riscv/boot/dts)
for the DTS file that will be used to produce the DTB linked into the
kernel.

config JUMP_LABEL_PATCH_LOG_SNAPSHOT
bool "Snapshot jump labels"
depends on JUMP_LABEL
help
Snapshot jump labels for debugging purposes.

endmenu # "Boot options"

Expand Down
9 changes: 9 additions & 0 deletions arch/riscv/kernel/cpufeature.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <linux/memory.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/jump_label_patch_log.h>
#include <asm/acpi.h>
#include <asm/alternative.h>
#include <asm/bugs.h>
Expand Down Expand Up @@ -1221,6 +1222,14 @@ void __init_or_module riscv_cpufeature_patch_func(struct alt_entry *begin,
mutex_lock(&text_mutex);
patch_text_nosync(oldptr, altptr, alt->alt_len);
riscv_alternative_fix_offsets(oldptr, alt->alt_len, oldptr - altptr);
for (int i = 0; i < alt->alt_len; i += sizeof(u32)) {
u32 insn;
memcpy(&insn, oldptr + i, sizeof(insn));
jl_snap_append(&(struct jl_entry){
.addr = (u64)(oldptr + i),
.new_insn = insn,
});
}
mutex_unlock(&text_mutex);
}
}
Expand Down
3 changes: 3 additions & 0 deletions arch/riscv/kernel/jump_label.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* Based on arch/arm64/kernel/jump_label.c
*/
#include <linux/jump_label.h>
#include <linux/jump_label_patch_log.h>
#include <linux/kernel.h>
#include <linux/memory.h>
#include <linux/mutex.h>
Expand Down Expand Up @@ -39,11 +40,13 @@ bool arch_jump_label_transform_queue(struct jump_entry *entry,
if (early_boot_irqs_disabled) {
riscv_patch_in_stop_machine = 1;
patch_insn_write(addr, &insn, sizeof(insn));
jl_snap_append(&(struct jl_entry){.addr = (u64)addr, .new_insn = insn});
riscv_patch_in_stop_machine = 0;
} else {
mutex_lock(&text_mutex);
patch_insn_write(addr, &insn, sizeof(insn));
mutex_unlock(&text_mutex);
jl_snap_append(&(struct jl_entry){.addr = (u64)addr, .new_insn = insn});
}

return true;
Expand Down
21 changes: 21 additions & 0 deletions include/linux/jump_label_patch_log.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _LINUX_JUMP_LABEL_PATCH_LOG_H
#define _LINUX_JUMP_LABEL_PATCH_LOG_H

#include <linux/types.h>
#include <linux/jump_label.h>

struct jl_entry {
u64 addr; // site address
u32 new_insn;
};

#ifdef CONFIG_JUMP_LABEL_PATCH_LOG_SNAPSHOT
void jl_snap_append(const struct jl_entry *e);
void jl_snap_publish_debugfs(void); // call later (late init)
#else
static inline void jl_snap_append(const struct jl_entry *e) { }
static inline void jl_snap_publish_debugfs(void) { }
#endif

#endif
1 change: 1 addition & 0 deletions kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ obj-$(CONFIG_PERF_EVENTS) += events/
obj-$(CONFIG_USER_RETURN_NOTIFIER) += user-return-notifier.o
obj-$(CONFIG_PADATA) += padata.o
obj-$(CONFIG_JUMP_LABEL) += jump_label.o
obj-$(CONFIG_JUMP_LABEL_PATCH_LOG_SNAPSHOT) += jump_label_patch_log.o
obj-$(CONFIG_CONTEXT_TRACKING) += context_tracking.o
obj-$(CONFIG_TORTURE_TEST) += torture.o

Expand Down
1 change: 1 addition & 0 deletions kernel/jump_label.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <linux/err.h>
#include <linux/static_key.h>
#include <linux/jump_label_ratelimit.h>
#include <linux/jump_label_patch_log.h>
#include <linux/bug.h>
#include <linux/cpu.h>
#include <asm/sections.h>
Expand Down
63 changes: 63 additions & 0 deletions kernel/jump_label_patch_log.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#include <linux/jump_label_patch_log.h>
#include <linux/atomic.h>

#define JL_MAX 8192 // tune or make it cmdline-configurable
static struct jl_entry jl_buf[JL_MAX];
static atomic_t jl_widx = ATOMIC_INIT(0);

#ifdef CONFIG_JUMP_LABEL_PATCH_LOG_SNAPSHOT
void jl_snap_append(const struct jl_entry *e)
{
int i = atomic_fetch_add_unless(&jl_widx, 1, JL_MAX);
if (i >= JL_MAX) return; // drop if full
jl_buf[i] = *e;
}
#endif

#ifdef CONFIG_DEBUG_FS
#include <linux/debugfs.h>
#include <linux/seq_file.h>

static int jl_dbg_show(struct seq_file *m, void *v)
{
int i, n = min(atomic_read(&jl_widx), JL_MAX);
for (i = 0; i < n; i++) {
const struct jl_entry *e = &jl_buf[i];
seq_printf(m, "%llx,%08x\n",
(unsigned long long)e->addr,
e->new_insn);
}
return 0;
}
static int jl_dbg_open(struct inode *inode, struct file *file)
{
return single_open(file, jl_dbg_show, NULL);
}
static const struct file_operations jl_dbg_fops = {
.owner = THIS_MODULE,
.open = jl_dbg_open,
.read = seq_read,
.llseek= seq_lseek,
.release= single_release,
};

#ifdef CONFIG_JUMP_LABEL_PATCH_LOG_SNAPSHOT
static struct dentry *jl_dent;
void jl_snap_publish_debugfs(void)
{
if (!jl_dent)
jl_dent = debugfs_create_file("jump_label_snapshot", 0444,
NULL, NULL, &jl_dbg_fops);
}

static int __init jl_snap_publish_debugfs_init(void)
{
jl_snap_publish_debugfs();
return 0;
}
late_initcall(jl_snap_publish_debugfs_init);

#endif // CONFIG_JUMP_LABEL_PATCH_LOG_SNAPSHOT
#else // CONFIG_DEBUG_FS
void jl_snap_publish_debugfs(void) { }
#endif // CONFIG_DEBUG_FS
4 changes: 4 additions & 0 deletions kernel/sched/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(sched_util_est_se_tp);
EXPORT_TRACEPOINT_SYMBOL_GPL(sched_update_nr_running_tp);
EXPORT_TRACEPOINT_SYMBOL_GPL(sched_compute_energy_tp);

EXPORT_SYMBOL(__tracepoint_sched_process_exec);
EXPORT_SYMBOL(__tracepoint_sched_process_fork);
EXPORT_SYMBOL(__tracepoint_sched_switch);

DEFINE_PER_CPU_SHARED_ALIGNED(struct rq, runqueues);

/*
Expand Down