asm-uaccess.h 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  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. isb
  20. add \tmp1, \tmp1, #RESERVED_SWAPPER_OFFSET
  21. msr ttbr1_el1, \tmp1 // set reserved ASID
  22. isb
  23. .endm
  24. .macro __uaccess_ttbr0_enable, tmp1, tmp2
  25. get_current_task \tmp1
  26. ldr \tmp1, [\tmp1, #TSK_TI_TTBR0] // load saved TTBR0_EL1
  27. mrs \tmp2, ttbr1_el1
  28. extr \tmp2, \tmp2, \tmp1, #48
  29. ror \tmp2, \tmp2, #16
  30. msr ttbr1_el1, \tmp2 // set the active ASID
  31. isb
  32. msr ttbr0_el1, \tmp1 // set the non-PAN TTBR0_EL1
  33. isb
  34. .endm
  35. .macro uaccess_ttbr0_disable, tmp1, tmp2
  36. alternative_if_not ARM64_HAS_PAN
  37. save_and_disable_irq \tmp2 // avoid preemption
  38. __uaccess_ttbr0_disable \tmp1
  39. restore_irq \tmp2
  40. alternative_else_nop_endif
  41. .endm
  42. .macro uaccess_ttbr0_enable, tmp1, tmp2, tmp3
  43. alternative_if_not ARM64_HAS_PAN
  44. save_and_disable_irq \tmp3 // avoid preemption
  45. __uaccess_ttbr0_enable \tmp1, \tmp2
  46. restore_irq \tmp3
  47. alternative_else_nop_endif
  48. .endm
  49. #else
  50. .macro uaccess_ttbr0_disable, tmp1, tmp2
  51. .endm
  52. .macro uaccess_ttbr0_enable, tmp1, tmp2, tmp3
  53. .endm
  54. #endif
  55. #define USER(l, x...) \
  56. 9999: x; \
  57. _asm_extable_uaccess 9999b, l
  58. /*
  59. * Generate the assembly for LDTR/STTR with exception table entries.
  60. * This is complicated as there is no post-increment or pair versions of the
  61. * unprivileged instructions, and USER() only works for single instructions.
  62. */
  63. .macro user_ldp l, reg1, reg2, addr, post_inc
  64. 8888: ldtr \reg1, [\addr];
  65. 8889: ldtr \reg2, [\addr, #8];
  66. add \addr, \addr, \post_inc;
  67. _asm_extable_uaccess 8888b, \l;
  68. _asm_extable_uaccess 8889b, \l;
  69. .endm
  70. .macro user_stp l, reg1, reg2, addr, post_inc
  71. 8888: sttr \reg1, [\addr];
  72. 8889: sttr \reg2, [\addr, #8];
  73. add \addr, \addr, \post_inc;
  74. _asm_extable_uaccess 8888b,\l;
  75. _asm_extable_uaccess 8889b,\l;
  76. .endm
  77. .macro user_ldst l, inst, reg, addr, post_inc
  78. 8888: \inst \reg, [\addr];
  79. add \addr, \addr, \post_inc;
  80. _asm_extable_uaccess 8888b, \l;
  81. .endm
  82. #endif