Commit | Line | Data |
---|---|---|
b7cdc182 | 1 | /* SPDX-License-Identifier: (GPL-2.0-only or LGPL-2.1-only) |
389d7070 MD |
2 | * wrapper/page_alloc.c |
3 | * | |
0e14d6e7 MD |
4 | * wrapper around get_pfnblock_flags_mask and Ubuntu |
5 | * get_pageblock_flags_mask. Using KALLSYMS to get their address when | |
6 | * available, else we need to have a kernel that exports this function | |
7 | * to GPL modules. | |
389d7070 MD |
8 | * |
9 | * Copyright (C) 2015 Mathieu Desnoyers <mathieu.desnoyers@efficios.com> | |
389d7070 MD |
10 | */ |
11 | ||
5a90857e | 12 | #ifdef CONFIG_KALLSYMS |
389d7070 MD |
13 | |
14 | #include <linux/kallsyms.h> | |
15 | #include <linux/mm_types.h> | |
16 | #include <linux/module.h> | |
5a2f5e92 MD |
17 | #include <wrapper/kallsyms.h> |
18 | #include <wrapper/page_alloc.h> | |
389d7070 MD |
19 | |
20 | static | |
21 | unsigned long (*get_pfnblock_flags_mask_sym)(struct page *page, | |
22 | unsigned long pfn, | |
23 | unsigned long end_bitidx, | |
24 | unsigned long mask); | |
25 | ||
26 | unsigned long wrapper_get_pfnblock_flags_mask(struct page *page, | |
27 | unsigned long pfn, | |
28 | unsigned long end_bitidx, | |
29 | unsigned long mask) | |
30 | { | |
31 | WARN_ON_ONCE(!get_pfnblock_flags_mask_sym); | |
32 | if (get_pfnblock_flags_mask_sym) { | |
33 | return get_pfnblock_flags_mask_sym(page, pfn, end_bitidx, mask); | |
34 | } else { | |
35 | return -ENOSYS; | |
36 | } | |
37 | } | |
38 | EXPORT_SYMBOL_GPL(wrapper_get_pfnblock_flags_mask); | |
39 | ||
40 | int wrapper_get_pfnblock_flags_mask_init(void) | |
41 | { | |
42 | get_pfnblock_flags_mask_sym = | |
43 | (void *) kallsyms_lookup_funcptr("get_pfnblock_flags_mask"); | |
44 | if (!get_pfnblock_flags_mask_sym) | |
45 | return -1; | |
46 | return 0; | |
47 | } | |
1c999280 | 48 | EXPORT_SYMBOL_GPL(wrapper_get_pfnblock_flags_mask_init); |
389d7070 | 49 | |
3dfec228 MJ |
50 | /* |
51 | * Canary function to check for 'get_pfnblock_flags_mask()' at compile time. | |
52 | * | |
53 | * From 'include/linux/pageblock-flags.h': | |
54 | * | |
55 | * unsigned long get_pfnblock_flags_mask(struct page *page, | |
56 | * unsigned long pfn, | |
57 | * unsigned long end_bitidx, | |
58 | * unsigned long mask); | |
59 | */ | |
60 | __attribute__((unused)) static | |
61 | unsigned long __canary__get_pfnblock_flags_mask(struct page *page, | |
62 | unsigned long pfn, | |
63 | unsigned long end_bitidx, | |
64 | unsigned long mask) | |
65 | { | |
66 | return get_pfnblock_flags_mask(page, pfn, end_bitidx, mask); | |
67 | } | |
68 | ||
0e14d6e7 | 69 | #else |
389d7070 MD |
70 | |
71 | #include <linux/pageblock-flags.h> | |
72 | ||
0e14d6e7 | 73 | #endif |