All of lore.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, Jerry Snitselaar <jsnitsel@redhat.com>,
	Wen Jin <wen.jin@intel.com>, Lu Baolu <baolu.lu@linux.intel.com>,
	Joerg Roedel <jroedel@suse.de>, Sasha Levin <sashal@kernel.org>
Subject: [PATCH 5.15 12/35] iommu/vt-d: Fix kdump kernels boot failure with scalable mode
Date: Fri, 16 Sep 2022 12:08:35 +0200	[thread overview]
Message-ID: <20220916100447.454737005@linuxfoundation.org> (raw)
In-Reply-To: <20220916100446.916515275@linuxfoundation.org>

From: Lu Baolu <baolu.lu@linux.intel.com>

[ Upstream commit 0c5f6c0d8201a809a6585b07b6263e9db2c874a3 ]

The translation table copying code for kdump kernels is currently based
on the extended root/context entry formats of ECS mode defined in older
VT-d v2.5, and doesn't handle the scalable mode formats. This causes
the kexec capture kernel boot failure with DMAR faults if the IOMMU was
enabled in scalable mode by the previous kernel.

The ECS mode has already been deprecated by the VT-d spec since v3.0 and
Intel IOMMU driver doesn't support this mode as there's no real hardware
implementation. Hence this converts ECS checking in copying table code
into scalable mode.

The existing copying code consumes a bit in the context entry as a mark
of copied entry. It needs to work for the old format as well as for the
extended context entries. As it's hard to find such a common bit for both
legacy and scalable mode context entries. This replaces it with a per-
IOMMU bitmap.

Fixes: 7373a8cc38197 ("iommu/vt-d: Setup context and enable RID2PASID support")
Cc: stable@vger.kernel.org
Reported-by: Jerry Snitselaar <jsnitsel@redhat.com>
Tested-by: Wen Jin <wen.jin@intel.com>
Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
Link: https://lore.kernel.org/r/20220817011035.3250131-1-baolu.lu@linux.intel.com
Signed-off-by: Joerg Roedel <jroedel@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/iommu/intel/iommu.c | 100 ++++++++++++++++--------------------
 include/linux/intel-iommu.h |   9 ++--
 2 files changed, 50 insertions(+), 59 deletions(-)

diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index bc5444daca9b4..2affdccb58e47 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -191,38 +191,6 @@ static phys_addr_t root_entry_uctp(struct root_entry *re)
 	return re->hi & VTD_PAGE_MASK;
 }
 
-static inline void context_clear_pasid_enable(struct context_entry *context)
-{
-	context->lo &= ~(1ULL << 11);
-}
-
-static inline bool context_pasid_enabled(struct context_entry *context)
-{
-	return !!(context->lo & (1ULL << 11));
-}
-
-static inline void context_set_copied(struct context_entry *context)
-{
-	context->hi |= (1ull << 3);
-}
-
-static inline bool context_copied(struct context_entry *context)
-{
-	return !!(context->hi & (1ULL << 3));
-}
-
-static inline bool __context_present(struct context_entry *context)
-{
-	return (context->lo & 1);
-}
-
-bool context_present(struct context_entry *context)
-{
-	return context_pasid_enabled(context) ?
-	     __context_present(context) :
-	     __context_present(context) && !context_copied(context);
-}
-
 static inline void context_set_present(struct context_entry *context)
 {
 	context->lo |= 1;
@@ -270,6 +238,26 @@ static inline void context_clear_entry(struct context_entry *context)
 	context->hi = 0;
 }
 
+static inline bool context_copied(struct intel_iommu *iommu, u8 bus, u8 devfn)
+{
+	if (!iommu->copied_tables)
+		return false;
+
+	return test_bit(((long)bus << 8) | devfn, iommu->copied_tables);
+}
+
+static inline void
+set_context_copied(struct intel_iommu *iommu, u8 bus, u8 devfn)
+{
+	set_bit(((long)bus << 8) | devfn, iommu->copied_tables);
+}
+
+static inline void
+clear_context_copied(struct intel_iommu *iommu, u8 bus, u8 devfn)
+{
+	clear_bit(((long)bus << 8) | devfn, iommu->copied_tables);
+}
+
 /*
  * This domain is a statically identity mapping domain.
  *	1. This domain creats a static 1:1 mapping to all usable memory.
@@ -792,6 +780,13 @@ struct context_entry *iommu_context_addr(struct intel_iommu *iommu, u8 bus,
 	struct context_entry *context;
 	u64 *entry;
 
+	/*
+	 * Except that the caller requested to allocate a new entry,
+	 * returning a copied context entry makes no sense.
+	 */
+	if (!alloc && context_copied(iommu, bus, devfn))
+		return NULL;
+
 	entry = &root->lo;
 	if (sm_supported(iommu)) {
 		if (devfn >= 0x80) {
@@ -1899,6 +1894,11 @@ static void free_dmar_iommu(struct intel_iommu *iommu)
 		iommu->domain_ids = NULL;
 	}
 
+	if (iommu->copied_tables) {
+		bitmap_free(iommu->copied_tables);
+		iommu->copied_tables = NULL;
+	}
+
 	g_iommus[iommu->seq_id] = NULL;
 
 	/* free context mapping */
@@ -2107,7 +2107,7 @@ static int domain_context_mapping_one(struct dmar_domain *domain,
 		goto out_unlock;
 
 	ret = 0;
-	if (context_present(context))
+	if (context_present(context) && !context_copied(iommu, bus, devfn))
 		goto out_unlock;
 
 	/*
@@ -2119,7 +2119,7 @@ static int domain_context_mapping_one(struct dmar_domain *domain,
 	 * in-flight DMA will exist, and we don't need to worry anymore
 	 * hereafter.
 	 */
-	if (context_copied(context)) {
+	if (context_copied(iommu, bus, devfn)) {
 		u16 did_old = context_domain_id(context);
 
 		if (did_old < cap_ndoms(iommu->cap)) {
@@ -2130,6 +2130,8 @@ static int domain_context_mapping_one(struct dmar_domain *domain,
 			iommu->flush.flush_iotlb(iommu, did_old, 0, 0,
 						 DMA_TLB_DSI_FLUSH);
 		}
+
+		clear_context_copied(iommu, bus, devfn);
 	}
 
 	context_clear_entry(context);
@@ -3024,32 +3026,14 @@ static int copy_context_table(struct intel_iommu *iommu,
 		/* Now copy the context entry */
 		memcpy(&ce, old_ce + idx, sizeof(ce));
 
-		if (!__context_present(&ce))
+		if (!context_present(&ce))
 			continue;
 
 		did = context_domain_id(&ce);
 		if (did >= 0 && did < cap_ndoms(iommu->cap))
 			set_bit(did, iommu->domain_ids);
 
-		/*
-		 * We need a marker for copied context entries. This
-		 * marker needs to work for the old format as well as
-		 * for extended context entries.
-		 *
-		 * Bit 67 of the context entry is used. In the old
-		 * format this bit is available to software, in the
-		 * extended format it is the PGE bit, but PGE is ignored
-		 * by HW if PASIDs are disabled (and thus still
-		 * available).
-		 *
-		 * So disable PASIDs first and then mark the entry
-		 * copied. This means that we don't copy PASID
-		 * translations from the old kernel, but this is fine as
-		 * faults there are not fatal.
-		 */
-		context_clear_pasid_enable(&ce);
-		context_set_copied(&ce);
-
+		set_context_copied(iommu, bus, devfn);
 		new_ce[idx] = ce;
 	}
 
@@ -3076,8 +3060,8 @@ static int copy_translation_tables(struct intel_iommu *iommu)
 	bool new_ext, ext;
 
 	rtaddr_reg = dmar_readq(iommu->reg + DMAR_RTADDR_REG);
-	ext        = !!(rtaddr_reg & DMA_RTADDR_RTT);
-	new_ext    = !!ecap_ecs(iommu->ecap);
+	ext        = !!(rtaddr_reg & DMA_RTADDR_SMT);
+	new_ext    = !!sm_supported(iommu);
 
 	/*
 	 * The RTT bit can only be changed when translation is disabled,
@@ -3088,6 +3072,10 @@ static int copy_translation_tables(struct intel_iommu *iommu)
 	if (new_ext != ext)
 		return -EINVAL;
 
+	iommu->copied_tables = bitmap_zalloc(BIT_ULL(16), GFP_KERNEL);
+	if (!iommu->copied_tables)
+		return -ENOMEM;
+
 	old_rt_phys = rtaddr_reg & VTD_PAGE_MASK;
 	if (!old_rt_phys)
 		return -EINVAL;
diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h
index 05a65eb155f76..81da7107e3bd0 100644
--- a/include/linux/intel-iommu.h
+++ b/include/linux/intel-iommu.h
@@ -196,7 +196,6 @@
 #define ecap_dis(e)		(((e) >> 27) & 0x1)
 #define ecap_nest(e)		(((e) >> 26) & 0x1)
 #define ecap_mts(e)		(((e) >> 25) & 0x1)
-#define ecap_ecs(e)		(((e) >> 24) & 0x1)
 #define ecap_iotlb_offset(e) 	((((e) >> 8) & 0x3ff) * 16)
 #define ecap_max_iotlb_offset(e) (ecap_iotlb_offset(e) + 16)
 #define ecap_coherent(e)	((e) & 0x1)
@@ -264,7 +263,6 @@
 #define DMA_GSTS_CFIS (((u32)1) << 23)
 
 /* DMA_RTADDR_REG */
-#define DMA_RTADDR_RTT (((u64)1) << 11)
 #define DMA_RTADDR_SMT (((u64)1) << 10)
 
 /* CCMD_REG */
@@ -594,6 +592,7 @@ struct intel_iommu {
 #ifdef CONFIG_INTEL_IOMMU
 	unsigned long 	*domain_ids; /* bitmap of domains */
 	struct dmar_domain ***domains; /* ptr to domains */
+	unsigned long	*copied_tables; /* bitmap of copied tables */
 	spinlock_t	lock; /* protect context, domain ids */
 	struct root_entry *root_entry; /* virtual address */
 
@@ -713,6 +712,11 @@ static inline int first_pte_in_page(struct dma_pte *pte)
 	return !((unsigned long)pte & ~VTD_PAGE_MASK);
 }
 
+static inline bool context_present(struct context_entry *context)
+{
+	return (context->lo & 1);
+}
+
 extern struct dmar_drhd_unit * dmar_find_matched_drhd_unit(struct pci_dev *dev);
 extern int dmar_find_matched_atsr_unit(struct pci_dev *dev);
 
@@ -806,7 +810,6 @@ static inline void intel_iommu_debugfs_init(void) {}
 #endif /* CONFIG_INTEL_IOMMU_DEBUGFS */
 
 extern const struct attribute_group *intel_iommu_groups[];
-bool context_present(struct context_entry *context);
 struct context_entry *iommu_context_addr(struct intel_iommu *iommu, u8 bus,
 					 u8 devfn, int alloc);
 
-- 
2.35.1




  parent reply	other threads:[~2022-09-16 10:19 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-16 10:08 [PATCH 5.15 00/35] 5.15.69-rc1 review Greg Kroah-Hartman
2022-09-16 10:08 ` [PATCH 5.15 01/35] NFS: Fix WARN_ON due to unionization of nfs_inode.nrequests Greg Kroah-Hartman
2022-09-16 10:08 ` [PATCH 5.15 02/35] ACPI: resource: skip IRQ override on AMD Zen platforms Greg Kroah-Hartman
2022-09-16 10:08 ` [PATCH 5.15 03/35] ARM: dts: imx: align SPI NOR node name with dtschema Greg Kroah-Hartman
2022-09-16 10:08 ` [PATCH 5.15 04/35] ARM: dts: imx6qdl-kontron-samx6i: fix spi-flash compatible Greg Kroah-Hartman
2022-09-16 10:08 ` [PATCH 5.15 05/35] ARM: dts: at91: fix low limit for CPU regulator Greg Kroah-Hartman
2022-09-16 10:08 ` [PATCH 5.15 06/35] ARM: dts: at91: sama7g5ek: specify proper regulator output ranges Greg Kroah-Hartman
2022-09-16 10:08 ` [PATCH 5.15 07/35] lockdep: Fix -Wunused-parameter for _THIS_IP_ Greg Kroah-Hartman
2022-09-16 10:08 ` [PATCH 5.15 08/35] x86/mm: Force-inline __phys_addr_nodebug() Greg Kroah-Hartman
2022-09-16 10:08 ` [PATCH 5.15 09/35] task_stack, x86/cea: Force-inline stack helpers Greg Kroah-Hartman
2022-09-16 10:08 ` [PATCH 5.15 10/35] tracing: hold caller_addr to hardirq_{enable,disable}_ip Greg Kroah-Hartman
2022-09-16 10:08 ` [PATCH 5.15 11/35] tracefs: Only clobber mode/uid/gid on remount if asked Greg Kroah-Hartman
2022-09-16 10:08 ` Greg Kroah-Hartman [this message]
2022-09-16 10:08 ` [PATCH 5.15 13/35] Input: goodix - add support for GT1158 Greg Kroah-Hartman
2022-09-16 10:08 ` [PATCH 5.15 14/35] platform/surface: aggregator_registry: Add support for Surface Laptop Go 2 Greg Kroah-Hartman
2022-09-16 10:08 ` [PATCH 5.15 15/35] drm/msm/rd: Fix FIFO-full deadlock Greg Kroah-Hartman
2022-09-16 10:08 ` [PATCH 5.15 16/35] hwmon: (pmbus) Use dev_err_probe() to filter -EPROBE_DEFER error messages Greg Kroah-Hartman
2022-09-16 10:08 ` [PATCH 5.15 17/35] dt-bindings: iio: gyroscope: bosch,bmg160: correct number of pins Greg Kroah-Hartman
2022-09-16 10:08 ` [PATCH 5.15 18/35] HID: ishtp-hid-clientHID: ishtp-hid-client: Fix comment typo Greg Kroah-Hartman
2022-09-16 10:08 ` [PATCH 5.15 19/35] hid: intel-ish-hid: ishtp: Fix ishtp client sending disordered message Greg Kroah-Hartman
2022-09-16 10:08 ` [PATCH 5.15 20/35] tg3: Disable tg3 device on system reboot to avoid triggering AER Greg Kroah-Hartman
2022-09-16 10:08 ` [PATCH 5.15 21/35] gpio: mockup: remove gpio debugfs when remove device Greg Kroah-Hartman
2022-09-16 10:08 ` [PATCH 5.15 22/35] ieee802154: cc2520: add rc code in cc2520_tx() Greg Kroah-Hartman
2022-09-16 10:08 ` [PATCH 5.15 23/35] Input: iforce - add support for Boeder Force Feedback Wheel Greg Kroah-Hartman
2022-09-16 10:08 ` [PATCH 5.15 24/35] nvmet-tcp: fix unhandled tcp states in nvmet_tcp_state_change() Greg Kroah-Hartman
2022-09-16 10:08 ` [PATCH 5.15 25/35] drm/amd/amdgpu: skip ucode loading if ucode_size == 0 Greg Kroah-Hartman
2022-09-16 10:08 ` [PATCH 5.15 26/35] net: dsa: hellcreek: Print warning only once Greg Kroah-Hartman
2022-09-16 10:08 ` [PATCH 5.15 27/35] perf/arm_pmu_platform: fix tests for platform_get_irq() failure Greg Kroah-Hartman
2022-09-16 10:08 ` [PATCH 5.15 28/35] platform/x86: acer-wmi: Acer Aspire One AOD270/Packard Bell Dot keymap fixes Greg Kroah-Hartman
2022-09-16 10:08 ` [PATCH 5.15 29/35] usb: storage: Add ASUS <0x0b05:0x1932> to IGNORE_UAS Greg Kroah-Hartman
2022-09-16 10:08 ` [PATCH 5.15 30/35] mm: Fix TLB flush for not-first PFNMAP mappings in unmap_region() Greg Kroah-Hartman
2022-09-16 10:08 ` [PATCH 5.15 31/35] soc: fsl: select FSL_GUTS driver for DPIO Greg Kroah-Hartman
2022-09-16 10:08 ` [PATCH 5.15 32/35] usb: gadget: f_uac2: clean up some inconsistent indenting Greg Kroah-Hartman
2022-09-16 10:08 ` [PATCH 5.15 33/35] usb: gadget: f_uac2: fix superspeed transfer Greg Kroah-Hartman
2022-09-16 10:08 ` [PATCH 5.15 34/35] RDMA/irdma: Use s/g array in post send only when its valid Greg Kroah-Hartman
2022-09-16 10:08 ` [PATCH 5.15 35/35] Input: goodix - add compatible string for GT1158 Greg Kroah-Hartman
2022-09-16 21:48 ` [PATCH 5.15 00/35] 5.15.69-rc1 review Guenter Roeck
2022-09-17  4:11 ` Bagas Sanjaya
2022-09-17 10:19 ` Ron Economos
2022-09-17 14:09 ` Sudip Mukherjee (Codethink)
2022-09-17 15:57 ` Naresh Kamboju
2022-09-19  0:00 ` Florian Fainelli

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=20220916100447.454737005@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=baolu.lu@linux.intel.com \
    --cc=jroedel@suse.de \
    --cc=jsnitsel@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=sashal@kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=wen.jin@intel.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.