Commit 76a4efa8 authored by Peter Zijlstra's avatar Peter Zijlstra

perf/arch: Remove perf_sample_data::regs_user_copy

struct perf_sample_data lives on-stack, we should be careful about it's
size. Furthermore, the pt_regs copy in there is only because x86_64 is a
trainwreck, solve it differently.
Reported-by: default avatarThomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Tested-by: default avatarSteven Rostedt <rostedt@goodmis.org>
Link: https://lkml.kernel.org/r/20201030151955.258178461@infradead.org
parent 09da9c81
...@@ -32,8 +32,7 @@ u64 perf_reg_abi(struct task_struct *task) ...@@ -32,8 +32,7 @@ u64 perf_reg_abi(struct task_struct *task)
} }
void perf_get_regs_user(struct perf_regs *regs_user, void perf_get_regs_user(struct perf_regs *regs_user,
struct pt_regs *regs, struct pt_regs *regs)
struct pt_regs *regs_user_copy)
{ {
regs_user->regs = task_pt_regs(current); regs_user->regs = task_pt_regs(current);
regs_user->abi = perf_reg_abi(current); regs_user->abi = perf_reg_abi(current);
......
...@@ -73,8 +73,7 @@ u64 perf_reg_abi(struct task_struct *task) ...@@ -73,8 +73,7 @@ u64 perf_reg_abi(struct task_struct *task)
} }
void perf_get_regs_user(struct perf_regs *regs_user, void perf_get_regs_user(struct perf_regs *regs_user,
struct pt_regs *regs, struct pt_regs *regs)
struct pt_regs *regs_user_copy)
{ {
regs_user->regs = task_pt_regs(current); regs_user->regs = task_pt_regs(current);
regs_user->abi = perf_reg_abi(current); regs_user->abi = perf_reg_abi(current);
......
...@@ -32,8 +32,7 @@ u64 perf_reg_abi(struct task_struct *task) ...@@ -32,8 +32,7 @@ u64 perf_reg_abi(struct task_struct *task)
} }
void perf_get_regs_user(struct perf_regs *regs_user, void perf_get_regs_user(struct perf_regs *regs_user,
struct pt_regs *regs, struct pt_regs *regs)
struct pt_regs *regs_user_copy)
{ {
regs_user->regs = task_pt_regs(current); regs_user->regs = task_pt_regs(current);
regs_user->abi = perf_reg_abi(current); regs_user->abi = perf_reg_abi(current);
......
...@@ -144,8 +144,7 @@ u64 perf_reg_abi(struct task_struct *task) ...@@ -144,8 +144,7 @@ u64 perf_reg_abi(struct task_struct *task)
} }
void perf_get_regs_user(struct perf_regs *regs_user, void perf_get_regs_user(struct perf_regs *regs_user,
struct pt_regs *regs, struct pt_regs *regs)
struct pt_regs *regs_user_copy)
{ {
regs_user->regs = task_pt_regs(current); regs_user->regs = task_pt_regs(current);
regs_user->abi = (regs_user->regs) ? perf_reg_abi(current) : regs_user->abi = (regs_user->regs) ? perf_reg_abi(current) :
......
...@@ -36,8 +36,7 @@ u64 perf_reg_abi(struct task_struct *task) ...@@ -36,8 +36,7 @@ u64 perf_reg_abi(struct task_struct *task)
} }
void perf_get_regs_user(struct perf_regs *regs_user, void perf_get_regs_user(struct perf_regs *regs_user,
struct pt_regs *regs, struct pt_regs *regs)
struct pt_regs *regs_user_copy)
{ {
regs_user->regs = task_pt_regs(current); regs_user->regs = task_pt_regs(current);
regs_user->abi = perf_reg_abi(current); regs_user->abi = perf_reg_abi(current);
......
...@@ -53,8 +53,7 @@ u64 perf_reg_abi(struct task_struct *task) ...@@ -53,8 +53,7 @@ u64 perf_reg_abi(struct task_struct *task)
} }
void perf_get_regs_user(struct perf_regs *regs_user, void perf_get_regs_user(struct perf_regs *regs_user,
struct pt_regs *regs, struct pt_regs *regs)
struct pt_regs *regs_user_copy)
{ {
/* /*
* Use the regs from the first interruption and let * Use the regs from the first interruption and let
......
...@@ -101,8 +101,7 @@ u64 perf_reg_abi(struct task_struct *task) ...@@ -101,8 +101,7 @@ u64 perf_reg_abi(struct task_struct *task)
} }
void perf_get_regs_user(struct perf_regs *regs_user, void perf_get_regs_user(struct perf_regs *regs_user,
struct pt_regs *regs, struct pt_regs *regs)
struct pt_regs *regs_user_copy)
{ {
regs_user->regs = task_pt_regs(current); regs_user->regs = task_pt_regs(current);
regs_user->abi = perf_reg_abi(current); regs_user->abi = perf_reg_abi(current);
...@@ -129,12 +128,20 @@ u64 perf_reg_abi(struct task_struct *task) ...@@ -129,12 +128,20 @@ u64 perf_reg_abi(struct task_struct *task)
return PERF_SAMPLE_REGS_ABI_64; return PERF_SAMPLE_REGS_ABI_64;
} }
static DEFINE_PER_CPU(struct pt_regs, nmi_user_regs);
void perf_get_regs_user(struct perf_regs *regs_user, void perf_get_regs_user(struct perf_regs *regs_user,
struct pt_regs *regs, struct pt_regs *regs)
struct pt_regs *regs_user_copy)
{ {
struct pt_regs *regs_user_copy = this_cpu_ptr(&nmi_user_regs);
struct pt_regs *user_regs = task_pt_regs(current); struct pt_regs *user_regs = task_pt_regs(current);
if (!in_nmi()) {
regs_user->regs = user_regs;
regs_user->abi = perf_reg_abi(current);
return;
}
/* /*
* If we're in an NMI that interrupted task_pt_regs setup, then * If we're in an NMI that interrupted task_pt_regs setup, then
* we can't sample user regs at all. This check isn't really * we can't sample user regs at all. This check isn't really
......
...@@ -1022,13 +1022,7 @@ struct perf_sample_data { ...@@ -1022,13 +1022,7 @@ struct perf_sample_data {
struct perf_callchain_entry *callchain; struct perf_callchain_entry *callchain;
u64 aux_size; u64 aux_size;
/*
* regs_user may point to task_pt_regs or to regs_user_copy, depending
* on arch details.
*/
struct perf_regs regs_user; struct perf_regs regs_user;
struct pt_regs regs_user_copy;
struct perf_regs regs_intr; struct perf_regs regs_intr;
u64 stack_user_size; u64 stack_user_size;
......
...@@ -20,8 +20,7 @@ u64 perf_reg_value(struct pt_regs *regs, int idx); ...@@ -20,8 +20,7 @@ u64 perf_reg_value(struct pt_regs *regs, int idx);
int perf_reg_validate(u64 mask); int perf_reg_validate(u64 mask);
u64 perf_reg_abi(struct task_struct *task); u64 perf_reg_abi(struct task_struct *task);
void perf_get_regs_user(struct perf_regs *regs_user, void perf_get_regs_user(struct perf_regs *regs_user,
struct pt_regs *regs, struct pt_regs *regs);
struct pt_regs *regs_user_copy);
#else #else
#define PERF_REG_EXTENDED_MASK 0 #define PERF_REG_EXTENDED_MASK 0
...@@ -42,8 +41,7 @@ static inline u64 perf_reg_abi(struct task_struct *task) ...@@ -42,8 +41,7 @@ static inline u64 perf_reg_abi(struct task_struct *task)
} }
static inline void perf_get_regs_user(struct perf_regs *regs_user, static inline void perf_get_regs_user(struct perf_regs *regs_user,
struct pt_regs *regs, struct pt_regs *regs)
struct pt_regs *regs_user_copy)
{ {
regs_user->regs = task_pt_regs(current); regs_user->regs = task_pt_regs(current);
regs_user->abi = perf_reg_abi(current); regs_user->abi = perf_reg_abi(current);
......
...@@ -6374,14 +6374,13 @@ perf_output_sample_regs(struct perf_output_handle *handle, ...@@ -6374,14 +6374,13 @@ perf_output_sample_regs(struct perf_output_handle *handle,
} }
static void perf_sample_regs_user(struct perf_regs *regs_user, static void perf_sample_regs_user(struct perf_regs *regs_user,
struct pt_regs *regs, struct pt_regs *regs)
struct pt_regs *regs_user_copy)
{ {
if (user_mode(regs)) { if (user_mode(regs)) {
regs_user->abi = perf_reg_abi(current); regs_user->abi = perf_reg_abi(current);
regs_user->regs = regs; regs_user->regs = regs;
} else if (!(current->flags & PF_KTHREAD)) { } else if (!(current->flags & PF_KTHREAD)) {
perf_get_regs_user(regs_user, regs, regs_user_copy); perf_get_regs_user(regs_user, regs);
} else { } else {
regs_user->abi = PERF_SAMPLE_REGS_ABI_NONE; regs_user->abi = PERF_SAMPLE_REGS_ABI_NONE;
regs_user->regs = NULL; regs_user->regs = NULL;
...@@ -7083,8 +7082,7 @@ void perf_prepare_sample(struct perf_event_header *header, ...@@ -7083,8 +7082,7 @@ void perf_prepare_sample(struct perf_event_header *header,
} }
if (sample_type & (PERF_SAMPLE_REGS_USER | PERF_SAMPLE_STACK_USER)) if (sample_type & (PERF_SAMPLE_REGS_USER | PERF_SAMPLE_STACK_USER))
perf_sample_regs_user(&data->regs_user, regs, perf_sample_regs_user(&data->regs_user, regs);
&data->regs_user_copy);
if (sample_type & PERF_SAMPLE_REGS_USER) { if (sample_type & PERF_SAMPLE_REGS_USER) {
/* regs dump ABI info */ /* regs dump ABI info */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment