Skip to content

Commit

Permalink
kallsyms, x86: Export addresses of PTI entry trampolines
Browse files Browse the repository at this point in the history
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 <[email protected]>
Acked-by: Andi Kleen <[email protected]>
Acked-by: Peter Zijlstra (Intel) <[email protected]>
Cc: Andy Lutomirski <[email protected]>
Cc: Dave Hansen <[email protected]>
Cc: H. Peter Anvin <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Joerg Roedel <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: [email protected]
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
  • Loading branch information
virtuoso authored and acmel committed Aug 14, 2018
1 parent b966794 commit d83212d
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 1 deletion.
23 changes: 23 additions & 0 deletions arch/x86/mm/cpu_entry_area.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <linux/spinlock.h>
#include <linux/percpu.h>
#include <linux/kallsyms.h>

#include <asm/cpu_entry_area.h>
#include <asm/pgtable.h>
Expand Down Expand Up @@ -150,6 +151,28 @@ static void __init setup_cpu_entry_area(int cpu)
percpu_setup_debug_store(cpu);
}

#ifdef CONFIG_X86_64
int arch_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
char *name)
{
unsigned int cpu, ncpu = 0;

if (symnum >= num_possible_cpus())
return -EINVAL;

for_each_possible_cpu(cpu) {
if (ncpu++ >= symnum)
break;
}

*value = (unsigned long)&get_cpu_entry_area(cpu)->entry_trampoline;
*type = 't';
strlcpy(name, "__entry_SYSCALL_64_trampoline", KSYM_NAME_LEN);

return 0;
}
#endif

static __init void setup_cpu_entry_area_ptes(void)
{
#ifdef CONFIG_X86_32
Expand Down
28 changes: 27 additions & 1 deletion kernel/kallsyms.c
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,7 @@ int sprint_backtrace(char *buffer, unsigned long address)
/* To avoid using get_symbol_offset for every symbol, we carry prefix along. */
struct kallsym_iter {
loff_t pos;
loff_t pos_arch_end;
loff_t pos_mod_end;
loff_t pos_ftrace_mod_end;
unsigned long value;
Expand All @@ -443,9 +444,29 @@ struct kallsym_iter {
int show_value;
};

int __weak arch_get_kallsym(unsigned int symnum, unsigned long *value,
char *type, char *name)
{
return -EINVAL;
}

static int get_ksymbol_arch(struct kallsym_iter *iter)
{
int ret = arch_get_kallsym(iter->pos - kallsyms_num_syms,
&iter->value, &iter->type,
iter->name);

if (ret < 0) {
iter->pos_arch_end = iter->pos;
return 0;
}

return 1;
}

static int get_ksymbol_mod(struct kallsym_iter *iter)
{
int ret = module_get_kallsym(iter->pos - kallsyms_num_syms,
int ret = module_get_kallsym(iter->pos - iter->pos_arch_end,
&iter->value, &iter->type,
iter->name, iter->module_name,
&iter->exported);
Expand Down Expand Up @@ -501,6 +522,7 @@ static void reset_iter(struct kallsym_iter *iter, loff_t new_pos)
iter->nameoff = get_symbol_offset(new_pos);
iter->pos = new_pos;
if (new_pos == 0) {
iter->pos_arch_end = 0;
iter->pos_mod_end = 0;
iter->pos_ftrace_mod_end = 0;
}
Expand All @@ -515,6 +537,10 @@ static int update_iter_mod(struct kallsym_iter *iter, loff_t pos)
{
iter->pos = pos;

if ((!iter->pos_arch_end || iter->pos_arch_end > pos) &&
get_ksymbol_arch(iter))
return 1;

if ((!iter->pos_mod_end || iter->pos_mod_end > pos) &&
get_ksymbol_mod(iter))
return 1;
Expand Down

0 comments on commit d83212d

Please sign in to comment.