[PATCH 2/8] x86/process: Clear PASID state for a newly forked/cloned thread

From: Fenghua Yu
Date: Mon Sep 20 2021 - 16:06:28 EST


The PASID state has to be cleared on forks, since the child has a
different address space. The PASID is also cleared for thread clone. While
it would be correct to inherit the PASID in this case, it is unknown
whether the new task will use ENQCMD. Giving it the PASID "just in case"
would have the downside of increased context switch overhead to setting
the PASID MSR and losing init optimization.

Since #GP faults have to be handled on any threads that were created before
the PASID was assigned to the mm of the process, newly created threads
might as well be treated in a consistent way.

Signed-off-by: Fenghua Yu <fenghua.yu@xxxxxxxxx>
Reviewed-by: Tony Luck <tony.luck@xxxxxxxxx>
---
arch/x86/kernel/process.c | 8 ++++++++
1 file changed, 8 insertions(+)

diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 1d9463e3096b..c713986ef7d7 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -154,6 +154,14 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, unsigned long arg,
frame->flags = X86_EFLAGS_FIXED;
#endif

+ if (static_cpu_has(X86_FEATURE_ENQCMD)) {
+ /*
+ * Clear the PASID bit in xfeatures so that the PASID MSR
+ * will be initialized as init state (0).
+ */
+ p->thread.fpu.state.xsave.header.xfeatures &= ~XFEATURE_MASK_PASID;
+ }
+
/* Kernel thread ? */
if (unlikely(p->flags & PF_KTHREAD)) {
p->thread.pkru = pkru_get_init_value();
--
2.33.0