blob: 38f79e42bf3c614caa44955eb253269d8b47310f [file] [log] [blame]
Greg Kroah-Hartmanb2441312017-11-01 15:07:57 +01001/* SPDX-License-Identifier: GPL-2.0 */
Jon Loeligerfbcd54b2005-09-17 10:39:46 -05002#ifndef _ASM_POWERPC_SECTIONS_H
3#define _ASM_POWERPC_SECTIONS_H
Arnd Bergmann88ced032005-12-16 22:43:46 +01004#ifdef __KERNEL__
Jon Loeligerfbcd54b2005-09-17 10:39:46 -05005
James Bottomley2d291e92008-09-09 14:04:18 +00006#include <linux/elf.h>
7#include <linux/uaccess.h>
Michael Ellerman6f070482019-11-27 18:41:26 +11008
Jon Loeligerfbcd54b2005-09-17 10:39:46 -05009#include <asm-generic/sections.h>
10
Naveen N. Rao7aa5b012017-04-19 20:59:51 +053011extern char __head_end[];
12
Jon Loeligerfbcd54b2005-09-17 10:39:46 -050013#ifdef __powerpc64__
14
Mahesh Salgaonkar429d2e82014-01-31 00:31:04 +053015extern char __start_interrupts[];
Anton Blanchardd715e432011-11-14 12:54:47 +000016extern char __end_interrupts[];
Jon Loeligerfbcd54b2005-09-17 10:39:46 -050017
Anton Blanchard5ac47f72012-11-26 17:39:03 +000018extern char __prom_init_toc_start[];
19extern char __prom_init_toc_end[];
20
Nicholas Pigginbd3524f2019-03-01 22:56:36 +100021#ifdef CONFIG_PPC_POWERNV
22extern char start_real_trampolines[];
23extern char end_real_trampolines[];
24extern char start_virt_trampolines[];
25extern char end_virt_trampolines[];
26#endif
27
Alan Modraa3ad84d2021-12-21 16:58:59 +110028/*
29 * This assumes the kernel is never compiled -mcmodel=small or
30 * the total .toc is always less than 64k.
31 */
Michael Ellermana5cab832016-03-03 15:26:53 +110032static inline unsigned long kernel_toc_addr(void)
33{
Alan Modraa3ad84d2021-12-21 16:58:59 +110034 unsigned long toc_ptr;
Michael Ellermana5cab832016-03-03 15:26:53 +110035
Alan Modraa3ad84d2021-12-21 16:58:59 +110036 asm volatile("mr %0, 2" : "=r" (toc_ptr));
37 return toc_ptr;
Michael Ellermana5cab832016-03-03 15:26:53 +110038}
39
Mahesh Salgaonkar429d2e82014-01-31 00:31:04 +053040static inline int overlaps_interrupt_vector_text(unsigned long start,
41 unsigned long end)
42{
43 unsigned long real_start, real_end;
44 real_start = __start_interrupts - _stext;
45 real_end = __end_interrupts - _stext;
46
47 return start < (unsigned long)__va(real_end) &&
48 (unsigned long)__va(real_start) < end;
49}
50
Paul Mackerras549e8152008-08-30 11:43:47 +100051static inline int overlaps_kernel_text(unsigned long start, unsigned long end)
52{
53 return start < (unsigned long)__init_end &&
54 (unsigned long)_stext < end;
55}
56
Michael Ellermanf55d9662016-06-06 22:26:10 +053057#ifdef PPC64_ELF_ABI_v1
Sergey Senozhatsky5633e852017-11-10 08:48:27 +090058
59#define HAVE_DEREFERENCE_FUNCTION_DESCRIPTOR 1
60
James Bottomleydeac93d2008-09-03 20:43:36 -050061#undef dereference_function_descriptor
James Bottomley2d291e92008-09-09 14:04:18 +000062static inline void *dereference_function_descriptor(void *ptr)
63{
64 struct ppc64_opd_entry *desc = ptr;
65 void *p;
66
Linus Torvalds0c389d892020-06-18 12:10:37 -070067 if (!get_kernel_nofault(p, (void *)&desc->funcaddr))
James Bottomley2d291e92008-09-09 14:04:18 +000068 ptr = p;
69 return ptr;
70}
Sergey Senozhatsky5633e852017-11-10 08:48:27 +090071
72#undef dereference_kernel_function_descriptor
73static inline void *dereference_kernel_function_descriptor(void *ptr)
74{
75 if (ptr < (void *)__start_opd || ptr >= (void *)__end_opd)
76 return ptr;
77
78 return dereference_function_descriptor(ptr);
79}
Michael Ellermanf55d9662016-06-06 22:26:10 +053080#endif /* PPC64_ELF_ABI_v1 */
James Bottomleydeac93d2008-09-03 20:43:36 -050081
Jon Loeligerfbcd54b2005-09-17 10:39:46 -050082#endif
83
Arnd Bergmann88ced032005-12-16 22:43:46 +010084#endif /* __KERNEL__ */
Jon Loeligerfbcd54b2005-09-17 10:39:46 -050085#endif /* _ASM_POWERPC_SECTIONS_H */