0210-x86-mm-Optimize-RESTORE_CR3.patch 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. From eb4a670cb54266bfab7bb4d9fd9e5da7b296ecdf Mon Sep 17 00:00:00 2001
  2. From: Peter Zijlstra <[email protected]>
  3. Date: Mon, 4 Dec 2017 15:08:00 +0100
  4. Subject: [PATCH 210/242] x86/mm: Optimize RESTORE_CR3
  5. MIME-Version: 1.0
  6. Content-Type: text/plain; charset=UTF-8
  7. Content-Transfer-Encoding: 8bit
  8. CVE-2017-5754
  9. Most NMI/paranoid exceptions will not in fact change pagetables and would
  10. thus not require TLB flushing, however RESTORE_CR3 uses flushing CR3
  11. writes.
  12. Restores to kernel PCIDs can be NOFLUSH, because we explicitly flush the
  13. kernel mappings and now that we track which user PCIDs need flushing we can
  14. avoid those too when possible.
  15. This does mean RESTORE_CR3 needs an additional scratch_reg, luckily both
  16. sites have plenty available.
  17. Signed-off-by: Peter Zijlstra (Intel) <[email protected]>
  18. Signed-off-by: Thomas Gleixner <[email protected]>
  19. Cc: Andy Lutomirski <[email protected]>
  20. Cc: Boris Ostrovsky <[email protected]>
  21. Cc: Borislav Petkov <[email protected]>
  22. Cc: Brian Gerst <[email protected]>
  23. Cc: Dave Hansen <[email protected]>
  24. Cc: David Laight <[email protected]>
  25. Cc: Denys Vlasenko <[email protected]>
  26. Cc: Eduardo Valentin <[email protected]>
  27. Cc: Greg KH <[email protected]>
  28. Cc: H. Peter Anvin <[email protected]>
  29. Cc: Josh Poimboeuf <[email protected]>
  30. Cc: Juergen Gross <[email protected]>
  31. Cc: Linus Torvalds <[email protected]>
  32. Cc: Peter Zijlstra <[email protected]>
  33. Cc: Will Deacon <[email protected]>
  34. Cc: [email protected]
  35. Cc: [email protected]
  36. Cc: [email protected]
  37. Cc: [email protected]
  38. Signed-off-by: Ingo Molnar <[email protected]>
  39. (cherry picked from commit 21e94459110252d41b45c0c8ba50fd72a664d50c)
  40. Signed-off-by: Andy Whitcroft <[email protected]>
  41. Signed-off-by: Kleber Sacilotto de Souza <[email protected]>
  42. (cherry picked from commit 6ebe6e2896841282357d43c09394b0ca47c41e4a)
  43. Signed-off-by: Fabian Grünbichler <[email protected]>
  44. ---
  45. arch/x86/entry/calling.h | 30 ++++++++++++++++++++++++++++--
  46. arch/x86/entry/entry_64.S | 4 ++--
  47. 2 files changed, 30 insertions(+), 4 deletions(-)
  48. diff --git a/arch/x86/entry/calling.h b/arch/x86/entry/calling.h
  49. index ce5fb309926d..015e0a84bb99 100644
  50. --- a/arch/x86/entry/calling.h
  51. +++ b/arch/x86/entry/calling.h
  52. @@ -280,8 +280,34 @@ For 32-bit we have the following conventions - kernel is built with
  53. .Ldone_\@:
  54. .endm
  55. -.macro RESTORE_CR3 save_reg:req
  56. +.macro RESTORE_CR3 scratch_reg:req save_reg:req
  57. ALTERNATIVE "jmp .Lend_\@", "", X86_FEATURE_PTI
  58. +
  59. + ALTERNATIVE "jmp .Lwrcr3_\@", "", X86_FEATURE_PCID
  60. +
  61. + /*
  62. + * KERNEL pages can always resume with NOFLUSH as we do
  63. + * explicit flushes.
  64. + */
  65. + bt $X86_CR3_PTI_SWITCH_BIT, \save_reg
  66. + jnc .Lnoflush_\@
  67. +
  68. + /*
  69. + * Check if there's a pending flush for the user ASID we're
  70. + * about to set.
  71. + */
  72. + movq \save_reg, \scratch_reg
  73. + andq $(0x7FF), \scratch_reg
  74. + bt \scratch_reg, THIS_CPU_user_pcid_flush_mask
  75. + jnc .Lnoflush_\@
  76. +
  77. + btr \scratch_reg, THIS_CPU_user_pcid_flush_mask
  78. + jmp .Lwrcr3_\@
  79. +
  80. +.Lnoflush_\@:
  81. + SET_NOFLUSH_BIT \save_reg
  82. +
  83. +.Lwrcr3_\@:
  84. /*
  85. * The CR3 write could be avoided when not changing its value,
  86. * but would require a CR3 read *and* a scratch register.
  87. @@ -300,7 +326,7 @@ For 32-bit we have the following conventions - kernel is built with
  88. .endm
  89. .macro SAVE_AND_SWITCH_TO_KERNEL_CR3 scratch_reg:req save_reg:req
  90. .endm
  91. -.macro RESTORE_CR3 save_reg:req
  92. +.macro RESTORE_CR3 scratch_reg:req save_reg:req
  93. .endm
  94. #endif
  95. diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
  96. index fb43f14ed299..b48f2c78a9bf 100644
  97. --- a/arch/x86/entry/entry_64.S
  98. +++ b/arch/x86/entry/entry_64.S
  99. @@ -1300,7 +1300,7 @@ ENTRY(paranoid_exit)
  100. testl %ebx, %ebx /* swapgs needed? */
  101. jnz .Lparanoid_exit_no_swapgs
  102. TRACE_IRQS_IRETQ
  103. - RESTORE_CR3 save_reg=%r14
  104. + RESTORE_CR3 scratch_reg=%rbx save_reg=%r14
  105. SWAPGS_UNSAFE_STACK
  106. jmp .Lparanoid_exit_restore
  107. .Lparanoid_exit_no_swapgs:
  108. @@ -1742,7 +1742,7 @@ end_repeat_nmi:
  109. movq $-1, %rsi
  110. call do_nmi
  111. - RESTORE_CR3 save_reg=%r14
  112. + RESTORE_CR3 scratch_reg=%r15 save_reg=%r14
  113. testl %ebx, %ebx /* swapgs needed? */
  114. jnz nmi_restore
  115. --
  116. 2.14.2