asm-uaccess.h 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  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. #define USER_CPY(l, uaccess_is_write, x...) \
  57. 9999: x; \
  58. _asm_extable_uaccess_cpy 9999b, l, uaccess_is_write
  59. /*
  60. * Generate the assembly for LDTR/STTR with exception table entries.
  61. * This is complicated as there is no post-increment or pair versions of the
  62. * unprivileged instructions, and USER() only works for single instructions.
  63. */
  64. .macro user_ldp l, reg1, reg2, addr, post_inc
  65. 8888: ldtr \reg1, [\addr];
  66. 8889: ldtr \reg2, [\addr, #8];
  67. add \addr, \addr, \post_inc;
  68. _asm_extable_uaccess 8888b, \l;
  69. _asm_extable_uaccess 8889b, \l;
  70. .endm
  71. .macro user_stp l, reg1, reg2, addr, post_inc
  72. 8888: sttr \reg1, [\addr];
  73. 8889: sttr \reg2, [\addr, #8];
  74. add \addr, \addr, \post_inc;
  75. _asm_extable_uaccess 8888b,\l;
  76. _asm_extable_uaccess 8889b,\l;
  77. .endm
  78. .macro user_ldst l, inst, reg, addr, post_inc
  79. 8888: \inst \reg, [\addr];
  80. add \addr, \addr, \post_inc;
  81. _asm_extable_uaccess 8888b, \l;
  82. .endm
  83. #endif