[PATCH 15/16] x86/entry/32: Switch between kernel and user cr3 on entry/exit

From: Joerg Roedel
Date: Tue Jan 16 2018 - 11:57:10 EST


From: Joerg Roedel <jroedel@xxxxxxx>

Add the cr3 switches between the kernel and the user
page-table when PTI is enabled.

Signed-off-by: Joerg Roedel <jroedel@xxxxxxx>
---
arch/x86/entry/entry_32.S | 25 ++++++++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S
index 14018eeb11c3..6a1d9f1e1f89 100644
--- a/arch/x86/entry/entry_32.S
+++ b/arch/x86/entry/entry_32.S
@@ -221,6 +221,25 @@
POP_GS_EX
.endm

+#define PTI_SWITCH_MASK (1 << PAGE_SHIFT)
+
+.macro SWITCH_TO_KERNEL_CR3
+ ALTERNATIVE "jmp .Lend_\@", "", X86_FEATURE_PTI
+ movl %cr3, %edi
+ andl $(~PTI_SWITCH_MASK), %edi
+ movl %edi, %cr3
+.Lend_\@:
+.endm
+
+.macro SWITCH_TO_USER_CR3
+ ALTERNATIVE "jmp .Lend_\@", "", X86_FEATURE_PTI
+ mov %cr3, %edi
+ /* Flip the PGD to the user version */
+ orl $(PTI_SWITCH_MASK), %edi
+ mov %edi, %cr3
+.Lend_\@:
+.endm
+
/*
* Switch from the entry-trampline stack to the kernel stack of the
* running task.
@@ -240,6 +259,7 @@
.endif

pushl %edi
+ SWITCH_TO_KERNEL_CR3
movl %esp, %edi

/*
@@ -309,9 +329,12 @@
.endif

pushl 4(%edi) /* fs */
+ pushl (%edi) /* edi */
+
+ SWITCH_TO_USER_CR3

/* Restore user %edi and user %fs */
- movl (%edi), %edi
+ popl %edi
popl %fs

.Lend_\@:
--
2.13.6