summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorPetr Mladek <pmladek@suse.com>2018-01-22 10:40:32 +0100
committerPetr Mladek <pmladek@suse.com>2018-01-22 10:40:32 +0100
commit3ccdc5190f8df12dfafff9264e406c5496401da5 (patch)
treeca4afea86b2ae2625125658b2e0af2e043e84017 /include
parent6fd78a1a99c9580da49ee8f951fdce9846256375 (diff)
parent1df7338ac96558d5ae4c1a9dd5d1cb60fcd1bdb2 (diff)
Merge branch 'for-4.16-deprecate-printk-pf' into for-4.16
Diffstat (limited to 'include')
-rw-r--r--include/asm-generic/sections.h8
-rw-r--r--include/linux/kallsyms.h54
-rw-r--r--include/linux/module.h10
3 files changed, 70 insertions, 2 deletions
diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h
index 03cc5f9bba71..849cd8eb5ca0 100644
--- a/include/asm-generic/sections.h
+++ b/include/asm-generic/sections.h
@@ -30,6 +30,7 @@
* __ctors_start, __ctors_end
* __irqentry_text_start, __irqentry_text_end
* __softirqentry_text_start, __softirqentry_text_end
+ * __start_opd, __end_opd
*/
extern char _text[], _stext[], _etext[];
extern char _data[], _sdata[], _edata[];
@@ -49,12 +50,15 @@ extern char __start_once[], __end_once[];
/* Start and end of .ctors section - used for constructor calls. */
extern char __ctors_start[], __ctors_end[];
+/* Start and end of .opd section - used for function descriptors. */
+extern char __start_opd[], __end_opd[];
+
extern __visible const void __nosave_begin, __nosave_end;
-/* function descriptor handling (if any). Override
- * in asm/sections.h */
+/* Function descriptor handling (if any). Override in asm/sections.h */
#ifndef dereference_function_descriptor
#define dereference_function_descriptor(p) (p)
+#define dereference_kernel_function_descriptor(p) (p)
#endif
/* random extra sections (if any). Override
diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h
index 708f337d780b..e4f2e5a65f14 100644
--- a/include/linux/kallsyms.h
+++ b/include/linux/kallsyms.h
@@ -9,6 +9,10 @@
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/stddef.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+
+#include <asm/sections.h>
#define KSYM_NAME_LEN 128
#define KSYM_SYMBOL_LEN (sizeof("%s+%#lx/%#lx [%s]") + (KSYM_NAME_LEN - 1) + \
@@ -22,6 +26,56 @@
struct module;
+static inline int is_kernel_inittext(unsigned long addr)
+{
+ if (addr >= (unsigned long)_sinittext
+ && addr <= (unsigned long)_einittext)
+ return 1;
+ return 0;
+}
+
+static inline int is_kernel_text(unsigned long addr)
+{
+ if ((addr >= (unsigned long)_stext && addr <= (unsigned long)_etext) ||
+ arch_is_kernel_text(addr))
+ return 1;
+ return in_gate_area_no_mm(addr);
+}
+
+static inline int is_kernel(unsigned long addr)
+{
+ if (addr >= (unsigned long)_stext && addr <= (unsigned long)_end)
+ return 1;
+ return in_gate_area_no_mm(addr);
+}
+
+static inline int is_ksym_addr(unsigned long addr)
+{
+ if (IS_ENABLED(CONFIG_KALLSYMS_ALL))
+ return is_kernel(addr);
+
+ return is_kernel_text(addr) || is_kernel_inittext(addr);
+}
+
+static inline void *dereference_symbol_descriptor(void *ptr)
+{
+#ifdef HAVE_DEREFERENCE_FUNCTION_DESCRIPTOR
+ struct module *mod;
+
+ ptr = dereference_kernel_function_descriptor(ptr);
+ if (is_ksym_addr((unsigned long)ptr))
+ return ptr;
+
+ preempt_disable();
+ mod = __module_address((unsigned long)ptr);
+ preempt_enable();
+
+ if (mod)
+ ptr = dereference_module_function_descriptor(mod, ptr);
+#endif
+ return ptr;
+}
+
#ifdef CONFIG_KALLSYMS
/* Lookup the address for a symbol. Returns 0 if not found. */
unsigned long kallsyms_lookup_name(const char *name);
diff --git a/include/linux/module.h b/include/linux/module.h
index c69b49abe877..e6249795f9e2 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -606,6 +606,9 @@ int ref_module(struct module *a, struct module *b);
__mod ? __mod->name : "kernel"; \
})
+/* Dereference module function descriptor */
+void *dereference_module_function_descriptor(struct module *mod, void *ptr);
+
/* For kallsyms to ask for address resolution. namebuf should be at
* least KSYM_NAME_LEN long: a pointer to namebuf is returned if
* found, otherwise NULL. */
@@ -760,6 +763,13 @@ static inline bool is_module_sig_enforced(void)
return false;
}
+/* Dereference module function descriptor */
+static inline
+void *dereference_module_function_descriptor(struct module *mod, void *ptr)
+{
+ return ptr;
+}
+
#endif /* CONFIG_MODULES */
#ifdef CONFIG_SYSFS