asm-uaccess.h 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #ifndef __ASM_ASM_UACCESS_H
  3. #define __ASM_ASM_UACCESS_H
  4. #include <asm/alternative-macros.h>
  5. #include <asm/asm-extable.h>
  6. #include <asm/assembler.h>
  7. #include <asm/kernel-pgtable.h>
  8. #include <asm/mmu.h>
  9. #include <asm/sysreg.h>
  10. /*
  11. * User access enabling/disabling macros.
  12. */
  13. #ifdef CONFIG_ARM64_SW_TTBR0_PAN
  14. .macro __uaccess_ttbr0_disable, tmp1
  15. mrs \tmp1, ttbr1_el1 // swapper_pg_dir
  16. bic \tmp1, \tmp1, #TTBR_ASID_MASK
  17. sub \tmp1, \tmp1, #RESERVED_SWAPPER_OFFSET // reserved_pg_dir
  18. msr ttbr0_el1, \tmp1 // set reserved TTBR0_EL1
  19. add \tmp1, \tmp1, #RESERVED_SWAPPER_OFFSET
  20. msr ttbr1_el1, \tmp1 // set reserved ASID
  21. isb
  22. .endm
  23. .macro __uaccess_ttbr0_enable, tmp1, tmp2
  24. get_current_task \tmp1
  25. ldr \tmp1, [\tmp1, #TSK_TI_TTBR0] // load saved TTBR0_EL1
  26. mrs \tmp2, ttbr1_el1
  27. extr \tmp2, \tmp2, \tmp1, #48
  28. ror \tmp2, \tmp2, #16
  29. msr ttbr1_el1, \tmp2 // set the active ASID
  30. msr ttbr0_el1, \tmp1 // set the non-PAN TTBR0_EL1
  31. isb
  32. .endm
  33. .macro uaccess_ttbr0_disable, tmp1, tmp2
  34. alternative_if_not ARM64_HAS_PAN
  35. save_and_disable_irq \tmp2 // avoid preemption
  36. __uaccess_ttbr0_disable \tmp1
  37. restore_irq \tmp2
  38. alternative_else_nop_endif
  39. .endm
  40. .macro uaccess_ttbr0_enable, tmp1, tmp2, tmp3
  41. alternative_if_not ARM64_HAS_PAN
  42. save_and_disable_irq \tmp3 // avoid preemption
  43. __uaccess_ttbr0_enable \tmp1, \tmp2
  44. restore_irq \tmp3
  45. alternative_else_nop_endif
  46. .endm
  47. #else
  48. .macro uaccess_ttbr0_disable, tmp1, tmp2
  49. .endm
  50. .macro uaccess_ttbr0_enable, tmp1, tmp2, tmp3
  51. .endm
  52. #endif
  53. #define USER(l, x...) \
  54. 9999: x; \
  55. _asm_extable_uaccess 9999b, l
  56. /*
  57. * Generate the assembly for LDTR/STTR with exception table entries.
  58. * This is complicated as there is no post-increment or pair versions of the
  59. * unprivileged instructions, and USER() only works for single instructions.
  60. */
  61. .macro user_ldp l, reg1, reg2, addr, post_inc
  62. 8888: ldtr \reg1, [\addr];
  63. 8889: ldtr \reg2, [\addr, #8];
  64. add \addr, \addr, \post_inc;
  65. _asm_extable_uaccess 8888b, \l;
  66. _asm_extable_uaccess 8889b, \l;
  67. .endm
  68. .macro user_stp l, reg1, reg2, addr, post_inc
  69. 8888: sttr \reg1, [\addr];
  70. 8889: sttr \reg2, [\addr, #8];
  71. add \addr, \addr, \post_inc;
  72. _asm_extable_uaccess 8888b,\l;
  73. _asm_extable_uaccess 8889b,\l;
  74. .endm
  75. .macro user_ldst l, inst, reg, addr, post_inc
  76. 8888: \inst \reg, [\addr];
  77. add \addr, \addr, \post_inc;
  78. _asm_extable_uaccess 8888b, \l;
  79. .endm
  80. #endif