diff options
-rw-r--r-- | arch/x86/mm/cpu_entry_area.c | 10 | ||||
-rw-r--r-- | fs/proc/kcore.c | 7 | ||||
-rw-r--r-- | include/linux/kcore.h | 13 |
3 files changed, 28 insertions, 2 deletions
diff --git a/arch/x86/mm/cpu_entry_area.c b/arch/x86/mm/cpu_entry_area.c index fab49fd5190f..076ebdce9bd4 100644 --- a/arch/x86/mm/cpu_entry_area.c +++ b/arch/x86/mm/cpu_entry_area.c @@ -3,6 +3,7 @@ #include <linux/spinlock.h> #include <linux/percpu.h> #include <linux/kallsyms.h> +#include <linux/kcore.h> #include <asm/cpu_entry_area.h> #include <asm/pgtable.h> @@ -14,6 +15,7 @@ static DEFINE_PER_CPU_PAGE_ALIGNED(struct entry_stack_page, entry_stack_storage) #ifdef CONFIG_X86_64 static DEFINE_PER_CPU_PAGE_ALIGNED(char, exception_stacks [(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + DEBUG_STKSZ]); +static DEFINE_PER_CPU(struct kcore_list, kcore_entry_trampoline); #endif struct cpu_entry_area *get_cpu_entry_area(int cpu) @@ -147,6 +149,14 @@ static void __init setup_cpu_entry_area(int cpu) cea_set_pte(&get_cpu_entry_area(cpu)->entry_trampoline, __pa_symbol(_entry_trampoline), PAGE_KERNEL_RX); + /* + * The cpu_entry_area alias addresses are not in the kernel binary + * so they do not show up in /proc/kcore normally. This adds entries + * for them manually. + */ + kclist_add_remap(&per_cpu(kcore_entry_trampoline, cpu), + _entry_trampoline, + &get_cpu_entry_area(cpu)->entry_trampoline, PAGE_SIZE); #endif percpu_setup_debug_store(cpu); } diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c index e64ecb9f2720..00282f134336 100644 --- a/fs/proc/kcore.c +++ b/fs/proc/kcore.c @@ -383,8 +383,11 @@ static void elf_kcore_store_hdr(char *bufp, int nphdr, int dataoff) phdr->p_type = PT_LOAD; phdr->p_flags = PF_R|PF_W|PF_X; phdr->p_offset = kc_vaddr_to_offset(m->addr) + dataoff; - phdr->p_vaddr = (size_t)m->addr; - if (m->type == KCORE_RAM || m->type == KCORE_TEXT) + if (m->type == KCORE_REMAP) + phdr->p_vaddr = (size_t)m->vaddr; + else + phdr->p_vaddr = (size_t)m->addr; + if (m->type == KCORE_RAM || m->type == KCORE_TEXT || m->type == KCORE_REMAP) phdr->p_paddr = __pa(m->addr); else phdr->p_paddr = (elf_addr_t)-1; diff --git a/include/linux/kcore.h b/include/linux/kcore.h index 8de55e4b5ee9..bc088ef96358 100644 --- a/include/linux/kcore.h +++ b/include/linux/kcore.h @@ -12,11 +12,13 @@ enum kcore_type { KCORE_VMEMMAP, KCORE_USER, KCORE_OTHER, + KCORE_REMAP, }; struct kcore_list { struct list_head list; unsigned long addr; + unsigned long vaddr; size_t size; int type; }; @@ -36,11 +38,22 @@ struct vmcoredd_node { #ifdef CONFIG_PROC_KCORE extern void kclist_add(struct kcore_list *, void *, size_t, int type); +static inline +void kclist_add_remap(struct kcore_list *m, void *addr, void *vaddr, size_t sz) +{ + m->vaddr = (unsigned long)vaddr; + kclist_add(m, addr, sz, KCORE_REMAP); +} #else static inline void kclist_add(struct kcore_list *new, void *addr, size_t size, int type) { } + +static inline +void kclist_add_remap(struct kcore_list *m, void *addr, void *vaddr, size_t sz) +{ +} #endif #endif /* _LINUX_KCORE_H */ |