linux/arch/mips/vdso/vdso.h
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2015 Imagination Technologies
   3 * Author: Alex Smith <alex.smith@imgtec.com>
   4 *
   5 * This program is free software; you can redistribute it and/or modify it
   6 * under the terms of the GNU General Public License as published by the
   7 * Free Software Foundation;  either version 2 of the  License, or (at your
   8 * option) any later version.
   9 */
  10
  11#include <asm/sgidefs.h>
  12
  13#if _MIPS_SIM != _MIPS_SIM_ABI64 && defined(CONFIG_64BIT)
  14
  15/* Building 32-bit VDSO for the 64-bit kernel. Fake a 32-bit Kconfig. */
  16#define BUILD_VDSO32_64
  17#undef CONFIG_64BIT
  18#define CONFIG_32BIT 1
  19#ifndef __ASSEMBLY__
  20#include <asm-generic/atomic64.h>
  21#endif
  22#endif
  23
  24#ifndef __ASSEMBLY__
  25
  26#include <asm/asm.h>
  27#include <asm/page.h>
  28#include <asm/vdso.h>
  29
  30static inline unsigned long get_vdso_base(void)
  31{
  32        unsigned long addr;
  33
  34        /*
  35         * We can't use cpu_has_mips_r6 since it needs the cpu_data[]
  36         * kernel symbol.
  37         */
  38#ifdef CONFIG_CPU_MIPSR6
  39        /*
  40         * lapc <symbol> is an alias to addiupc reg, <symbol> - .
  41         *
  42         * We can't use addiupc because there is no label-label
  43         * support for the addiupc reloc
  44         */
  45        __asm__("lapc   %0, _start                      \n"
  46                : "=r" (addr) : :);
  47#else
  48        /*
  49         * Get the base load address of the VDSO. We have to avoid generating
  50         * relocations and references to the GOT because ld.so does not peform
  51         * relocations on the VDSO. We use the current offset from the VDSO base
  52         * and perform a PC-relative branch which gives the absolute address in
  53         * ra, and take the difference. The assembler chokes on
  54         * "li %0, _start - .", so embed the offset as a word and branch over
  55         * it.
  56         *
  57         */
  58
  59        __asm__(
  60        "       .set push                               \n"
  61        "       .set noreorder                          \n"
  62        "       bal     1f                              \n"
  63        "        nop                                    \n"
  64        "       .word   _start - .                      \n"
  65        "1:     lw      %0, 0($31)                      \n"
  66        "       " STR(PTR_ADDU) " %0, $31, %0           \n"
  67        "       .set pop                                \n"
  68        : "=r" (addr)
  69        :
  70        : "$31");
  71#endif /* CONFIG_CPU_MIPSR6 */
  72
  73        return addr;
  74}
  75
  76static inline const union mips_vdso_data *get_vdso_data(void)
  77{
  78        return (const union mips_vdso_data *)(get_vdso_base() - PAGE_SIZE);
  79}
  80
  81#ifdef CONFIG_CLKSRC_MIPS_GIC
  82
  83static inline void __iomem *get_gic(const union mips_vdso_data *data)
  84{
  85        return (void __iomem *)data - PAGE_SIZE;
  86}
  87
  88#endif /* CONFIG_CLKSRC_MIPS_GIC */
  89
  90#endif /* __ASSEMBLY__ */
  91