linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Fenghua Yu <fenghua.yu@intel.com>
To: "Thomas Gleixner" <tglx@linutronix.de>,
	"Ingo Molnar" <mingo@redhat.com>,
	"Borislav Petkov" <bp@alien8.de>,
	"Peter Zijlstra" <peterz@infradead.org>,
	"Andy Lutomirski" <luto@kernel.org>,
	"Dave Hansen" <dave.hansen@linux.intel.com>,
	"Tony Luck" <tony.luck@intel.com>,
	"Lu Baolu" <baolu.lu@linux.intel.com>,
	"Joerg Roedel" <joro@8bytes.org>,
	Josh Poimboeuf <jpoimboe@redhat.com>,
	"Jacob Pan" <jacob.jun.pan@linux.intel.com>,
	"Ashok Raj" <ashok.raj@intel.com>,
	"Ravi V Shankar" <ravi.v.shankar@intel.com>
Cc: iommu@lists.linux-foundation.org, "x86" <x86@kernel.org>,
	"linux-kernel" <linux-kernel@vger.kernel.org>,
	Fenghua Yu <fenghua.yu@intel.com>
Subject: [PATCH v2 08/11] x86/traps: Demand-populate PASID MSR via #GP
Date: Fri, 17 Dec 2021 22:01:33 +0000	[thread overview]
Message-ID: <20211217220136.2762116-9-fenghua.yu@intel.com> (raw)
In-Reply-To: <20211217220136.2762116-1-fenghua.yu@intel.com>

All tasks start with PASID state disabled. This means that the first
time they execute an ENQCMD instruction they will take a #GP fault.

Modify the #GP fault handler to check if the "mm" for the task has
already been allocated a PASID. If so, try to fix the #GP fault by
loading the IA32_PASID MSR.

Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
Reviewed-by: Tony Luck <tony.luck@intel.com>
---
v2:
- Directly write IA32_PASID MSR in fixup while local IRQ is still disabled
  (Thomas)
- Move #ifdef over to CONFIG_IOMMU_SVA since it is what
  defines mm->pasid and ->pasid_activated (Dave Hansen).
- Rename try_fixup_pasid() -> try_fixup_enqcmd_gp(). This
  code really is highly specific to ENQCMD, not PASIDs (Dave Hansen).
- Add lockdep assert and comment about context (Dave Hansen).
- Re-flow the if() mess (Dave Hansen).

 arch/x86/kernel/traps.c | 55 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 55 insertions(+)

diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index c9d566dcf89a..7ef00dee35be 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -39,6 +39,7 @@
 #include <linux/io.h>
 #include <linux/hardirq.h>
 #include <linux/atomic.h>
+#include <linux/ioasid.h>
 
 #include <asm/stacktrace.h>
 #include <asm/processor.h>
@@ -559,6 +560,57 @@ static bool fixup_iopl_exception(struct pt_regs *regs)
 	return true;
 }
 
+/*
+ * The unprivileged ENQCMD instruction generates #GPs if the
+ * IA32_PASID MSR has not been populated.  If possible, populate
+ * the MSR from a PASID previously allocated to the mm.
+ */
+static bool try_fixup_enqcmd_gp(void)
+{
+#ifdef CONFIG_IOMMU_SVA
+	u32 pasid;
+
+	/*
+	 * MSR_IA32_PASID is managed using XSAVE.  Directly
+	 * writing to the MSR is only possible when fpregs
+	 * are valid and the fpstate is not.  This is
+	 * guaranteed when handling a userspace exception
+	 * in *before* interrupts are re-enabled.
+	 */
+	lockdep_assert_irqs_disabled();
+
+	/*
+	 * Hardware without ENQCMD will not generate
+	 * #GPs that can be fixed up here.
+	 */
+	if (!cpu_feature_enabled(X86_FEATURE_ENQCMD))
+		return false;
+
+	pasid = current->mm->pasid;
+
+	/*
+	 * If the mm has not been allocated a
+	 * PASID, the #GP can not be fixed up.
+	 */
+	if (!pasid_valid(pasid))
+		return false;
+
+	/*
+	 * Did this thread already have its PASID activated?
+	 * If so, the #GP must be from something else.
+	 */
+	if (current->pasid_activated)
+		return false;
+
+	wrmsrl(MSR_IA32_PASID, pasid | MSR_IA32_PASID_VALID);
+	current->pasid_activated = 1;
+
+	return true;
+#else
+	return false;
+#endif
+}
+
 DEFINE_IDTENTRY_ERRORCODE(exc_general_protection)
 {
 	char desc[sizeof(GPFSTR) + 50 + 2*sizeof(unsigned long) + 1] = GPFSTR;
@@ -567,6 +619,9 @@ DEFINE_IDTENTRY_ERRORCODE(exc_general_protection)
 	unsigned long gp_addr;
 	int ret;
 
+	if (user_mode(regs) && try_fixup_enqcmd_gp())
+		return;
+
 	cond_local_irq_enable(regs);
 
 	if (static_cpu_has(X86_FEATURE_UMIP)) {
-- 
2.34.1


  parent reply	other threads:[~2021-12-17 22:02 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-17 22:01 [PATCH v2 00/11] Re-enable ENQCMD and PASID MSR Fenghua Yu
2021-12-17 22:01 ` [PATCH v2 01/11] iommu/sva: Rename CONFIG_IOMMU_SVA_LIB to CONFIG_IOMMU_SVA Fenghua Yu
2021-12-17 22:01 ` [PATCH v2 02/11] mm: Change CONFIG option for mm->pasid field Fenghua Yu
2021-12-17 22:01 ` [PATCH v2 03/11] iommu/ioasid: Introduce a helper to check for valid PASIDs Fenghua Yu
2021-12-17 22:01 ` [PATCH v2 04/11] kernel/fork: Initialize mm's PASID Fenghua Yu
2021-12-17 22:01 ` [PATCH v2 05/11] iommu/sva: Assign a PASID to mm on PASID allocation and free it on mm exit Fenghua Yu
2022-01-24 20:21   ` Thomas Gleixner
2022-01-24 20:33     ` Fenghua Yu
2022-01-24 20:36     ` Thomas Gleixner
2022-01-24 20:52       ` Fenghua Yu
2022-01-24 20:55         ` Thomas Gleixner
2022-01-25 15:18           ` Fenghua Yu
2022-01-26 14:23             ` Thomas Gleixner
2022-01-26 17:36               ` Fenghua Yu
2022-01-26 21:38                 ` Thomas Gleixner
2022-01-28  2:42                   ` Fenghua Yu
2022-01-28 14:53                     ` Thomas Gleixner
2021-12-17 22:01 ` [PATCH v2 06/11] x86/fpu: Clear PASID when copying fpstate Fenghua Yu
2021-12-17 22:01 ` [PATCH v2 07/11] sched: Define and initialize a flag to identify valid PASID in the task Fenghua Yu
2021-12-17 22:01 ` Fenghua Yu [this message]
2021-12-17 22:01 ` [PATCH v2 09/11] x86/cpufeatures: Re-enable ENQCMD Fenghua Yu
2021-12-17 22:01 ` [PATCH v2 10/11] tools/objtool: Check for use of the ENQCMD instruction in the kernel Fenghua Yu
2021-12-17 22:57   ` Josh Poimboeuf
2021-12-27 17:50     ` Fenghua Yu
2021-12-17 22:01 ` [PATCH v2 11/11] docs: x86: Change documentation for SVA (Shared Virtual Addressing) Fenghua Yu
2021-12-27 17:52 ` [PATCH v2 00/11] Re-enable ENQCMD and PASID MSR 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=20211217220136.2762116-9-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@linux.intel.com \
    --cc=iommu@lists.linux-foundation.org \
    --cc=jacob.jun.pan@linux.intel.com \
    --cc=joro@8bytes.org \
    --cc=jpoimboe@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@kernel.org \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.org \
    --cc=ravi.v.shankar@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).