Merge remote-tracking branch 'origin/upstream/linux-linaro-lsk-v3.10-android+android...
[firefly-linux-kernel-4.4.55.git] / include / linux / pie.h
1 /*
2  * Copyright 2013 Texas Instruments, Inc.
3  *      Russ Dill <russ.dill@ti.com>
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms and conditions of the GNU General Public License,
7  * version 2, as published by the Free Software Foundation.
8  */
9
10 #ifndef _LINUX_PIE_H
11 #define _LINUX_PIE_H
12
13 #include <linux/kernel.h>
14 #include <linux/err.h>
15
16 #include <asm/fncpy.h>
17 #include <asm/bug.h>
18
19 struct gen_pool;
20 struct pie_chunk;
21
22 /**
23  * pie_arch_fixup - arch specific fixups of copied PIE code
24  * @chunk:      identifier to be used with kern_to_pie/pie_to_phys
25  * @base:       virtual address of start of copied PIE section
26  * @tail:       virtual address of tail data in copied PIE
27  * @offset:     offset to apply to relocation entries.
28  *
29  * When this code is done executing, it should be possible to jump to code
30  * so long as it is located at the given offset.
31  */
32 extern int pie_arch_fixup(struct pie_chunk *chunk, void *base, void *tail,
33                                                         unsigned long offset);
34
35 /**
36  * pie_arch_fill_tail - arch specific tail information for copied PIE
37  * @tail:               virtual address of tail data in copied PIE to be filled
38  * @common_start:       virtual address of common code within kernel data
39  * @common_end:         virtual end address of common code within kernel data
40  * @overlay_start:      virtual address of first overlay within kernel data
41  * @code_start:         virtual address of this overlay within kernel data
42  * @code_end:           virtual end address of this overlay within kernel data
43  *
44  * Fill tail data with data necessary to for pie_arch_fixup to perform
45  * relocations. If tail is NULL, do not update data, but still calculate
46  * the number of bytes required.
47  *
48  * Returns number of bytes required/used for tail on success, -EERROR otherwise.
49  */
50 extern int pie_arch_fill_tail(void *tail, void *common_start, void *common_end,
51                         void *overlay_start, void *code_start, void *code_end);
52
53 #ifdef CONFIG_PIE
54
55 /**
56  * __pie_load_data - load and fixup PIE code from kernel data
57  * @pool:       pool to allocate memory from and copy code into
58  * @start:      virtual start address in kernel of chunk specific code
59  * @end:        virtual end address in kernel of chunk specific code
60  * @phys:       %true to fixup to physical address of destination, %false to
61  *              fixup to virtual address of destination
62  *
63  * Returns 0 on success, -EERROR otherwise
64  */
65 extern struct pie_chunk *__pie_load_data(struct gen_pool *pool,
66                                 void *start, void *end, bool phys);
67
68 /**
69  * pie_to_phys - translate a virtual PIE address into a physical one
70  * @chunk:      identifier returned by pie_load_sections
71  * @addr:       virtual address within pie chunk
72  *
73  * Returns physical address on success, -1 otherwise
74  */
75 extern phys_addr_t pie_to_phys(struct pie_chunk *chunk, unsigned long addr);
76
77 extern void __iomem *__kern_to_pie(struct pie_chunk *chunk, void *ptr);
78
79 /**
80  * pie_free - free the pool space used by an pie chunk
81  * @chunk:      identifier returned by pie_load_sections
82  */
83 extern void pie_free(struct pie_chunk *chunk);
84
85 #define __pie_load_sections(pool, name, phys) ({                        \
86         extern char __pie_##name##_start[];                             \
87         extern char __pie_##name##_end[];                               \
88                                                                         \
89         __pie_load_data(pool, __pie_##name##_start,                     \
90                                         __pie_##name##_end, phys);      \
91 })
92
93 /*
94  * Required for any symbol within an PIE section that is referenced by the
95  * kernel
96  */
97 #define EXPORT_PIE_SYMBOL(sym)          extern typeof(sym) sym __weak
98
99 /* For marking data and functions that should be part of a PIE */
100 #define __pie(name)     __attribute__ ((__section__(".pie." #name ".text")))
101 #define __pie_data(name) __attribute__ ((__section__(".pie." #name ".data")))
102
103 #else
104
105 static inline struct pie_chunk *__pie_load_data(struct gen_pool *pool,
106                                         void *start, void *end, bool phys)
107 {
108         return ERR_PTR(-EINVAL);
109 }
110
111 static inline phys_addr_t pie_to_phys(struct pie_chunk *chunk,
112                                                 unsigned long addr)
113 {
114         return -1;
115 }
116
117 static inline void __iomem *__kern_to_pie(struct pie_chunk *chunk, void *ptr)
118 {
119         return NULL;
120 }
121
122 static inline void pie_free(struct pie_chunk *chunk)
123 {
124 }
125
126 #define __pie_load_sections(pool, name, phys) ({ ERR_PTR(-EINVAL); })
127
128 #define EXPORT_PIE_SYMBOL(sym)
129
130 #define __pie(name)
131 #define __pie_data(name)
132
133 #endif
134
135 /**
136  * pie_load_sections - load and fixup sections associated with the given name
137  * @pool:       pool to allocate memory from and copy code into
138  *              fixup to virtual address of destination
139  * @name:       the name given to __pie() and __pie_data() when marking
140  *              data and code
141  *
142  * Returns 0 on success, -EERROR otherwise
143  */
144 #define pie_load_sections(pool, name) ({                                \
145         __pie_load_sections(pool, name, false);                         \
146 })
147
148 /**
149  * pie_load_sections_phys - load and fixup sections associated with the given
150  * name for execution with the MMU off
151  *
152  * @pool:       pool to allocate memory from and copy code into
153  *              fixup to virtual address of destination
154  * @name:       the name given to __pie() and __pie_data() when marking
155  *              data and code
156  *
157  * Returns 0 on success, -EERROR otherwise
158  */
159 #define pie_load_sections_phys(pool, name) ({                           \
160         __pie_load_sections(pool, name, true);                          \
161 })
162
163 /**
164  * kern_to_pie - convert a kernel symbol to the virtual address of where
165  * that symbol is loaded into the given PIE chunk.
166  *
167  * @chunk:      identifier returned by pie_load_sections
168  * @p:          symbol to convert
169  *
170  * Return type is the same as type passed
171  */
172 #define kern_to_pie(chunk, p) ({                                        \
173         void *__ptr = (void *) (p);                                     \
174         typeof(p) __result = (typeof(p)) __kern_to_pie(chunk, __ptr);   \
175         __result;                                                       \
176 })
177
178 /**
179  * kern_to_fn - convert a kernel function symbol to the virtual address of where
180  * that symbol is loaded into the given PIE chunk
181  *
182  * @chunk:      identifier returned by pie_load_sections
183  * @p:          function to convert
184  *
185  * Return type is the same as type passed
186  */
187 #define fn_to_pie(chunk, funcp) ({                                      \
188         uintptr_t __kern_addr, __pie_addr;                              \
189                                                                         \
190         __kern_addr = fnptr_to_addr(funcp);                             \
191         __pie_addr = kern_to_pie(chunk, __kern_addr);                   \
192                                                                         \
193         fnptr_translate(funcp, __pie_addr);                             \
194 })
195
196 #endif