diff --git a/include/linux/module.h b/include/linux/module.h index b6a646c..c520a3a 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -16,6 +16,7 @@ #include #include #include +#include #include @@ -371,6 +372,7 @@ static inline int module_is_live(struct module *mod) struct module *module_text_address(unsigned long addr); struct module *__module_text_address(unsigned long addr); int is_module_address(unsigned long addr); +struct page *module_to_page(void *kaddr); /* Returns 0 and fills in value, defined and namebuf, or -ERANGE if symnum out of range. */ @@ -498,6 +500,11 @@ static inline int is_module_address(unsigned long addr) return 0; } +static inline struct page *module_to_page(void *kaddr) +{ + return virt_to_page(kaddr); +} + /* Get/put a kernel symbol (calls should be symmetric) */ #define symbol_get(x) ({ extern typeof(x) x __attribute__((weak)); &(x); }) #define symbol_put(x) do { } while(0) diff --git a/kernel/module.c b/kernel/module.c index 33c04ad..4618792 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -2347,6 +2347,16 @@ int is_module_address(unsigned long addr) return 0; } +/* + * Convert a virtual address, possibly in a module, to a struct page. + */ +struct page *module_to_page(void *kaddr) +{ + if (is_module_address((unsigned long)kaddr)) + return vmalloc_to_page(kaddr); + else + return virt_to_page(kaddr); +} /* Is this a valid kernel address? */ struct module *__module_text_address(unsigned long addr)