2 * Copyright 2013 Texas Instruments, Inc.
3 * Russ Dill <russ.dill@ti.com>
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.
13 #include <linux/kernel.h>
14 #include <linux/err.h>
16 #include <asm/fncpy.h>
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.
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.
32 extern int pie_arch_fixup(struct pie_chunk *chunk, void *base, void *tail,
33 unsigned long offset);
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
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.
48 * Returns number of bytes required/used for tail on success, -EERROR otherwise.
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);
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
63 * Returns 0 on success, -EERROR otherwise
65 extern struct pie_chunk *__pie_load_data(struct gen_pool *pool,
66 void *start, void *end, bool phys);
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
73 * Returns physical address on success, -1 otherwise
75 extern phys_addr_t pie_to_phys(struct pie_chunk *chunk, unsigned long addr);
77 extern void __iomem *__kern_to_pie(struct pie_chunk *chunk, void *ptr);
80 * pie_free - free the pool space used by an pie chunk
81 * @chunk: identifier returned by pie_load_sections
83 extern void pie_free(struct pie_chunk *chunk);
85 #define __pie_load_sections(pool, name, phys) ({ \
86 extern char __pie_##name##_start[]; \
87 extern char __pie_##name##_end[]; \
89 __pie_load_data(pool, __pie_##name##_start, \
90 __pie_##name##_end, phys); \
94 * Required for any symbol within an PIE section that is referenced by the
97 #define EXPORT_PIE_SYMBOL(sym) extern typeof(sym) sym __weak
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")))
105 static inline struct pie_chunk *__pie_load_data(struct gen_pool *pool,
106 void *start, void *end, bool phys)
108 return ERR_PTR(-EINVAL);
111 static inline phys_addr_t pie_to_phys(struct pie_chunk *chunk,
117 static inline void __iomem *__kern_to_pie(struct pie_chunk *chunk, void *ptr)
122 static inline void pie_free(struct pie_chunk *chunk)
126 #define __pie_load_sections(pool, name, phys) ({ ERR_PTR(-EINVAL); })
128 #define EXPORT_PIE_SYMBOL(sym)
131 #define __pie_data(name)
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
142 * Returns 0 on success, -EERROR otherwise
144 #define pie_load_sections(pool, name) ({ \
145 __pie_load_sections(pool, name, false); \
149 * pie_load_sections_phys - load and fixup sections associated with the given
150 * name for execution with the MMU off
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
157 * Returns 0 on success, -EERROR otherwise
159 #define pie_load_sections_phys(pool, name) ({ \
160 __pie_load_sections(pool, name, true); \
164 * kern_to_pie - convert a kernel symbol to the virtual address of where
165 * that symbol is loaded into the given PIE chunk.
167 * @chunk: identifier returned by pie_load_sections
168 * @p: symbol to convert
170 * Return type is the same as type passed
172 #define kern_to_pie(chunk, p) ({ \
173 void *__ptr = (void *) (p); \
174 typeof(p) __result = (typeof(p)) __kern_to_pie(chunk, __ptr); \
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
182 * @chunk: identifier returned by pie_load_sections
183 * @p: function to convert
185 * Return type is the same as type passed
187 #define fn_to_pie(chunk, funcp) ({ \
188 uintptr_t __kern_addr, __pie_addr; \
190 __kern_addr = fnptr_to_addr(funcp); \
191 __pie_addr = kern_to_pie(chunk, __kern_addr); \
193 fnptr_translate(funcp, __pie_addr); \