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) { | |
92e2c5fe MD |
33 | struct irq_ibt_state irq_ibt_state; |
34 | unsigned long ret; | |
35 | ||
36 | irq_ibt_state = wrapper_irq_ibt_save(); | |
37 | ret = get_pfnblock_flags_mask_sym(page, pfn, end_bitidx, mask); | |
38 | wrapper_irq_ibt_restore(irq_ibt_state); | |
39 | return ret; | |
389d7070 MD |
40 | } else { |
41 | return -ENOSYS; | |
42 | } | |
43 | } | |
44 | EXPORT_SYMBOL_GPL(wrapper_get_pfnblock_flags_mask); | |
45 | ||
46 | int wrapper_get_pfnblock_flags_mask_init(void) | |
47 | { | |
48 | get_pfnblock_flags_mask_sym = | |
49 | (void *) kallsyms_lookup_funcptr("get_pfnblock_flags_mask"); | |
50 | if (!get_pfnblock_flags_mask_sym) | |
51 | return -1; | |
52 | return 0; | |
53 | } | |
1c999280 | 54 | EXPORT_SYMBOL_GPL(wrapper_get_pfnblock_flags_mask_init); |
389d7070 | 55 | |
3dfec228 MJ |
56 | /* |
57 | * Canary function to check for 'get_pfnblock_flags_mask()' at compile time. | |
58 | * | |
59 | * From 'include/linux/pageblock-flags.h': | |
60 | * | |
61 | * unsigned long get_pfnblock_flags_mask(struct page *page, | |
62 | * unsigned long pfn, | |
63 | * unsigned long end_bitidx, | |
64 | * unsigned long mask); | |
65 | */ | |
66 | __attribute__((unused)) static | |
67 | unsigned long __canary__get_pfnblock_flags_mask(struct page *page, | |
68 | unsigned long pfn, | |
69 | unsigned long end_bitidx, | |
70 | unsigned long mask) | |
71 | { | |
72 | return get_pfnblock_flags_mask(page, pfn, end_bitidx, mask); | |
73 | } | |
74 | ||
0e14d6e7 | 75 | #else |
389d7070 MD |
76 | |
77 | #include <linux/pageblock-flags.h> | |
78 | ||
0e14d6e7 | 79 | #endif |