Skip to content

Commit d83212d

Browse files
virtuosoacmel
authored andcommitted
kallsyms, x86: Export addresses of PTI entry trampolines
Currently, the addresses of PTI entry trampolines are not exported to user space. Kernel profiling tools need these addresses to identify the kernel code, so add a symbol and address for each CPU's PTI entry trampoline. Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com> Acked-by: Andi Kleen <ak@linux.intel.com> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: Andy Lutomirski <luto@kernel.org> Cc: Dave Hansen <dave.hansen@linux.intel.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Joerg Roedel <joro@8bytes.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: x86@kernel.org Link: http://lkml.kernel.org/r/1528289651-4113-3-git-send-email-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
1 parent b966794 commit d83212d

File tree

2 files changed

+50
-1
lines changed

2 files changed

+50
-1
lines changed

arch/x86/mm/cpu_entry_area.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include <linux/spinlock.h>
44
#include <linux/percpu.h>
5+
#include <linux/kallsyms.h>
56

67
#include <asm/cpu_entry_area.h>
78
#include <asm/pgtable.h>
@@ -150,6 +151,28 @@ static void __init setup_cpu_entry_area(int cpu)
150151
percpu_setup_debug_store(cpu);
151152
}
152153

154+
#ifdef CONFIG_X86_64
155+
int arch_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
156+
char *name)
157+
{
158+
unsigned int cpu, ncpu = 0;
159+
160+
if (symnum >= num_possible_cpus())
161+
return -EINVAL;
162+
163+
for_each_possible_cpu(cpu) {
164+
if (ncpu++ >= symnum)
165+
break;
166+
}
167+
168+
*value = (unsigned long)&get_cpu_entry_area(cpu)->entry_trampoline;
169+
*type = 't';
170+
strlcpy(name, "__entry_SYSCALL_64_trampoline", KSYM_NAME_LEN);
171+
172+
return 0;
173+
}
174+
#endif
175+
153176
static __init void setup_cpu_entry_area_ptes(void)
154177
{
155178
#ifdef CONFIG_X86_32

kernel/kallsyms.c

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,7 @@ int sprint_backtrace(char *buffer, unsigned long address)
432432
/* To avoid using get_symbol_offset for every symbol, we carry prefix along. */
433433
struct kallsym_iter {
434434
loff_t pos;
435+
loff_t pos_arch_end;
435436
loff_t pos_mod_end;
436437
loff_t pos_ftrace_mod_end;
437438
unsigned long value;
@@ -443,9 +444,29 @@ struct kallsym_iter {
443444
int show_value;
444445
};
445446

447+
int __weak arch_get_kallsym(unsigned int symnum, unsigned long *value,
448+
char *type, char *name)
449+
{
450+
return -EINVAL;
451+
}
452+
453+
static int get_ksymbol_arch(struct kallsym_iter *iter)
454+
{
455+
int ret = arch_get_kallsym(iter->pos - kallsyms_num_syms,
456+
&iter->value, &iter->type,
457+
iter->name);
458+
459+
if (ret < 0) {
460+
iter->pos_arch_end = iter->pos;
461+
return 0;
462+
}
463+
464+
return 1;
465+
}
466+
446467
static int get_ksymbol_mod(struct kallsym_iter *iter)
447468
{
448-
int ret = module_get_kallsym(iter->pos - kallsyms_num_syms,
469+
int ret = module_get_kallsym(iter->pos - iter->pos_arch_end,
449470
&iter->value, &iter->type,
450471
iter->name, iter->module_name,
451472
&iter->exported);
@@ -501,6 +522,7 @@ static void reset_iter(struct kallsym_iter *iter, loff_t new_pos)
501522
iter->nameoff = get_symbol_offset(new_pos);
502523
iter->pos = new_pos;
503524
if (new_pos == 0) {
525+
iter->pos_arch_end = 0;
504526
iter->pos_mod_end = 0;
505527
iter->pos_ftrace_mod_end = 0;
506528
}
@@ -515,6 +537,10 @@ static int update_iter_mod(struct kallsym_iter *iter, loff_t pos)
515537
{
516538
iter->pos = pos;
517539

540+
if ((!iter->pos_arch_end || iter->pos_arch_end > pos) &&
541+
get_ksymbol_arch(iter))
542+
return 1;
543+
518544
if ((!iter->pos_mod_end || iter->pos_mod_end > pos) &&
519545
get_ksymbol_mod(iter))
520546
return 1;

0 commit comments

Comments
 (0)