#include <linux/spinlock.h>
 #include <linux/percpu.h>
+#include <linux/kallsyms.h>
 
 #include <asm/cpu_entry_area.h>
 #include <asm/pgtable.h>
        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
 
 /* 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;
        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);
        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;
        }
 {
        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;