linux/arch/powerpc/include/asm/sections.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2#ifndef _ASM_POWERPC_SECTIONS_H
   3#define _ASM_POWERPC_SECTIONS_H
   4#ifdef __KERNEL__
   5
   6#include <linux/elf.h>
   7#include <linux/uaccess.h>
   8
   9#define arch_is_kernel_initmem_freed arch_is_kernel_initmem_freed
  10
  11#include <asm-generic/sections.h>
  12
  13extern bool init_mem_is_free;
  14
  15static inline int arch_is_kernel_initmem_freed(unsigned long addr)
  16{
  17        if (!init_mem_is_free)
  18                return 0;
  19
  20        return addr >= (unsigned long)__init_begin &&
  21                addr < (unsigned long)__init_end;
  22}
  23
  24extern char __head_end[];
  25
  26#ifdef __powerpc64__
  27
  28extern char __start_interrupts[];
  29extern char __end_interrupts[];
  30
  31extern char __prom_init_toc_start[];
  32extern char __prom_init_toc_end[];
  33
  34#ifdef CONFIG_PPC_POWERNV
  35extern char start_real_trampolines[];
  36extern char end_real_trampolines[];
  37extern char start_virt_trampolines[];
  38extern char end_virt_trampolines[];
  39#endif
  40
  41static inline int in_kernel_text(unsigned long addr)
  42{
  43        if (addr >= (unsigned long)_stext && addr < (unsigned long)__init_end)
  44                return 1;
  45
  46        return 0;
  47}
  48
  49static inline unsigned long kernel_toc_addr(void)
  50{
  51        /* Defined by the linker, see vmlinux.lds.S */
  52        extern unsigned long __toc_start;
  53
  54        /*
  55         * The TOC register (r2) points 32kB into the TOC, so that 64kB of
  56         * the TOC can be addressed using a single machine instruction.
  57         */
  58        return (unsigned long)(&__toc_start) + 0x8000UL;
  59}
  60
  61static inline int overlaps_interrupt_vector_text(unsigned long start,
  62                                                        unsigned long end)
  63{
  64        unsigned long real_start, real_end;
  65        real_start = __start_interrupts - _stext;
  66        real_end = __end_interrupts - _stext;
  67
  68        return start < (unsigned long)__va(real_end) &&
  69                (unsigned long)__va(real_start) < end;
  70}
  71
  72static inline int overlaps_kernel_text(unsigned long start, unsigned long end)
  73{
  74        return start < (unsigned long)__init_end &&
  75                (unsigned long)_stext < end;
  76}
  77
  78#ifdef PPC64_ELF_ABI_v1
  79
  80#define HAVE_DEREFERENCE_FUNCTION_DESCRIPTOR 1
  81
  82#undef dereference_function_descriptor
  83static inline void *dereference_function_descriptor(void *ptr)
  84{
  85        struct ppc64_opd_entry *desc = ptr;
  86        void *p;
  87
  88        if (!get_kernel_nofault(p, (void *)&desc->funcaddr))
  89                ptr = p;
  90        return ptr;
  91}
  92
  93#undef dereference_kernel_function_descriptor
  94static inline void *dereference_kernel_function_descriptor(void *ptr)
  95{
  96        if (ptr < (void *)__start_opd || ptr >= (void *)__end_opd)
  97                return ptr;
  98
  99        return dereference_function_descriptor(ptr);
 100}
 101#endif /* PPC64_ELF_ABI_v1 */
 102
 103#endif
 104
 105#endif /* __KERNEL__ */
 106#endif  /* _ASM_POWERPC_SECTIONS_H */
 107