From: Fenghua Yu <fenghua.yu@intel.com>
To: "Thomas Gleixner" <tglx@linutronix.de>,
"Ingo Molnar" <mingo@redhat.com>,
"Borislav Petkov" <bp@alien8.de>, "H Peter Anvin" <hpa@zytor.com>,
"David Woodhouse" <dwmw2@infradead.org>,
"Lu Baolu" <baolu.lu@linux.intel.com>,
"Dave Hansen" <dave.hansen@intel.com>,
"Tony Luck" <tony.luck@intel.com>,
"Ashok Raj" <ashok.raj@intel.com>,
"Jacob Jun Pan" <jacob.jun.pan@intel.com>,
"Dave Jiang" <dave.jiang@intel.com>,
"Sohil Mehta" <sohil.mehta@intel.com>,
"Ravi V Shankar" <ravi.v.shankar@intel.com>
Cc: "linux-kernel" <linux-kernel@vger.kernel.org>,
"x86" <x86@kernel.org>,
iommu@lists.linux-foundation.org,
Fenghua Yu <fenghua.yu@intel.com>
Subject: [PATCH 6/7] x86/traps: Fix up invalid PASID
Date: Mon, 30 Mar 2020 12:33:07 -0700 [thread overview]
Message-ID: <1585596788-193989-7-git-send-email-fenghua.yu@intel.com> (raw)
In-Reply-To: <1585596788-193989-1-git-send-email-fenghua.yu@intel.com>
A #GP fault is generated when ENQCMD instruction is executed without
a valid PASID value programmed in. The #GP fault handler will initialize
the current thread's PASID MSR.
The following heuristic is used to avoid decoding the user instructions
to determine the precise reason for the #GP fault:
1) If the mm for the process has not been allocated a PASID, this #GP
cannot be fixed.
2) If the PASID MSR is already initialized, then the #GP was for some
other reason
3) Try initializing the PASID MSR and returning. If the #GP was from
an ENQCMD this will fix it. If not, the #GP fault will be repeated
and we will hit case "2".
Suggested-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
Reviewed-by: Tony Luck <tony.luck@intel.com>
---
arch/x86/include/asm/iommu.h | 1 +
arch/x86/kernel/traps.c | 17 +++++++++++++++++
drivers/iommu/intel-svm.c | 37 ++++++++++++++++++++++++++++++++++++
3 files changed, 55 insertions(+)
diff --git a/arch/x86/include/asm/iommu.h b/arch/x86/include/asm/iommu.h
index ed41259fe7ac..e9365a5d6f7d 100644
--- a/arch/x86/include/asm/iommu.h
+++ b/arch/x86/include/asm/iommu.h
@@ -27,5 +27,6 @@ arch_rmrr_sanity_check(struct acpi_dmar_reserved_memory *rmrr)
}
void __free_pasid(struct mm_struct *mm);
+bool __fixup_pasid_exception(void);
#endif /* _ASM_X86_IOMMU_H */
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 6ef00eb6fbb9..369b5ba94635 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -56,6 +56,7 @@
#include <asm/umip.h>
#include <asm/insn.h>
#include <asm/insn-eval.h>
+#include <asm/iommu.h>
#ifdef CONFIG_X86_64
#include <asm/x86_init.h>
@@ -488,6 +489,16 @@ static enum kernel_gp_hint get_kernel_gp_address(struct pt_regs *regs,
return GP_CANONICAL;
}
+static bool fixup_pasid_exception(void)
+{
+ if (!IS_ENABLED(CONFIG_INTEL_IOMMU_SVM))
+ return false;
+ if (!static_cpu_has(X86_FEATURE_ENQCMD))
+ return false;
+
+ return __fixup_pasid_exception();
+}
+
#define GPFSTR "general protection fault"
dotraplinkage void do_general_protection(struct pt_regs *regs, long error_code)
@@ -499,6 +510,12 @@ dotraplinkage void do_general_protection(struct pt_regs *regs, long error_code)
int ret;
RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU");
+
+ if (user_mode(regs) && fixup_pasid_exception()) {
+ cond_local_irq_enable(regs);
+ return;
+ }
+
cond_local_irq_enable(regs);
if (static_cpu_has(X86_FEATURE_UMIP)) {
diff --git a/drivers/iommu/intel-svm.c b/drivers/iommu/intel-svm.c
index da718a49e91e..5ed39a022adb 100644
--- a/drivers/iommu/intel-svm.c
+++ b/drivers/iommu/intel-svm.c
@@ -759,3 +759,40 @@ void __free_pasid(struct mm_struct *mm)
*/
ioasid_free(pasid);
}
+
+/*
+ * Fix up the PASID MSR if possible.
+ *
+ * But if the #GP was due to another reason, a second #GP might be triggered
+ * to force proper behavior.
+ */
+bool __fixup_pasid_exception(void)
+{
+ struct mm_struct *mm;
+ bool ret = true;
+ u64 pasid_msr;
+ int pasid;
+
+ mm = get_task_mm(current);
+ /* This #GP was triggered from user mode. So mm cannot be NULL. */
+ pasid = mm->context.pasid;
+ /* Ensure this process has been bound to a PASID. */
+ if (!pasid) {
+ ret = false;
+ goto out;
+ }
+
+ /* Check to see if the PASID MSR has already been set for this task. */
+ rdmsrl(MSR_IA32_PASID, pasid_msr);
+ if (pasid_msr & MSR_IA32_PASID_VALID) {
+ ret = false;
+ goto out;
+ }
+
+ /* Fix up the MSR. */
+ wrmsrl(MSR_IA32_PASID, pasid | MSR_IA32_PASID_VALID);
+out:
+ mmput(mm);
+
+ return ret;
+}
--
2.19.1
next prev parent reply other threads:[~2020-03-30 20:38 UTC|newest]
Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-03-30 19:33 [PATCH 0/7] x86: tag application address space for devices Fenghua Yu
2020-03-30 19:33 ` [PATCH 1/7] docs: x86: Add a documentation for ENQCMD Fenghua Yu
2020-04-26 11:02 ` Thomas Gleixner
2020-04-27 20:13 ` Fenghua Yu
2020-03-30 19:33 ` [PATCH 2/7] x86/cpufeatures: Enumerate ENQCMD and ENQCMDS instructions Fenghua Yu
2020-04-26 11:06 ` Thomas Gleixner
2020-04-27 20:17 ` Fenghua Yu
2020-03-30 19:33 ` [PATCH 3/7] x86/fpu/xstate: Add supervisor PASID state for ENQCMD feature Fenghua Yu
2020-04-26 11:17 ` Thomas Gleixner
2020-04-27 20:33 ` Fenghua Yu
2020-03-30 19:33 ` [PATCH 4/7] x86/msr-index: Define IA32_PASID MSR Fenghua Yu
2020-04-26 11:22 ` Thomas Gleixner
2020-04-27 20:50 ` Fenghua Yu
2020-03-30 19:33 ` [PATCH 5/7] x86/mmu: Allocate/free PASID Fenghua Yu
2020-04-26 14:55 ` Thomas Gleixner
2020-04-27 22:18 ` Fenghua Yu
2020-04-27 23:44 ` Thomas Gleixner
2020-04-28 18:21 ` Jacob Pan (Jun)
2020-04-28 18:54 ` Thomas Gleixner
2020-04-28 19:07 ` Luck, Tony
2020-04-28 20:42 ` Jacob Pan (Jun)
2020-04-28 20:59 ` Luck, Tony
2020-04-28 22:13 ` Jacob Pan (Jun)
2020-04-28 22:32 ` Luck, Tony
2020-04-28 20:40 ` Jacob Pan (Jun)
2020-04-28 20:57 ` Fenghua Yu
2020-03-30 19:33 ` Fenghua Yu [this message]
2020-04-26 15:25 ` [PATCH 6/7] x86/traps: Fix up invalid PASID Thomas Gleixner
2020-04-27 20:11 ` Fenghua Yu
2020-04-28 0:13 ` Thomas Gleixner
2020-04-27 22:46 ` Raj, Ashok
2020-04-27 23:08 ` Luck, Tony
2020-04-28 0:20 ` Thomas Gleixner
2020-04-28 0:54 ` Thomas Gleixner
2020-04-28 1:08 ` Raj, Ashok
2020-03-30 19:33 ` [PATCH 7/7] x86/process: Clear PASID state for a newly forked/cloned thread Fenghua Yu
2020-04-22 20:41 ` [PATCH 0/7] x86: tag application address space for devices Fenghua Yu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1585596788-193989-7-git-send-email-fenghua.yu@intel.com \
--to=fenghua.yu@intel.com \
--cc=ashok.raj@intel.com \
--cc=baolu.lu@linux.intel.com \
--cc=bp@alien8.de \
--cc=dave.hansen@intel.com \
--cc=dave.jiang@intel.com \
--cc=dwmw2@infradead.org \
--cc=hpa@zytor.com \
--cc=iommu@lists.linux-foundation.org \
--cc=jacob.jun.pan@intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=ravi.v.shankar@intel.com \
--cc=sohil.mehta@intel.com \
--cc=tglx@linutronix.de \
--cc=tony.luck@intel.com \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).