From: Yi Liu <yi.l.liu@intel.com>
To: joro@8bytes.org, alex.williamson@redhat.com, jgg@nvidia.com,
kevin.tian@intel.com, robin.murphy@arm.com,
baolu.lu@linux.intel.com
Cc: cohuck@redhat.com, eric.auger@redhat.com, nicolinc@nvidia.com,
kvm@vger.kernel.org, mjrosato@linux.ibm.com,
chao.p.peng@linux.intel.com, yi.l.liu@intel.com,
yi.y.sun@linux.intel.com, peterx@redhat.com, jasowang@redhat.com,
shameerali.kolothum.thodi@huawei.com, lulu@redhat.com,
suravee.suthikulpanit@amd.com, iommu@lists.linux.dev,
linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org,
zhenzhong.duan@intel.com
Subject: [PATCH v4 12/12] iommu/vt-d: Disallow nesting on domains with read-only mappings
Date: Mon, 24 Jul 2023 04:13:34 -0700 [thread overview]
Message-ID: <20230724111335.107427-13-yi.l.liu@intel.com> (raw)
In-Reply-To: <20230724111335.107427-1-yi.l.liu@intel.com>
From: Lu Baolu <baolu.lu@linux.intel.com>
When remapping hardware is configured by system software in scalable mode
as Nested (PGTT=011b) and with PWSNP field Set in the PASID-table-entry,
it may Set Accessed bit and Dirty bit (and Extended Access bit if enabled)
in first-stage page-table entries even when second-stage mappings indicate
that corresponding first-stage page-table is Read-Only.
As the result, contents of pages designated by VMM as Read-Only can be
modified by IOMMU via PML5E (PML4E for 4-level tables) access as part of
address translation process due to DMAs issued by Guest.
Disallow the nested translation when there are read-only pages in the
corresponding second-stage mappings. And, no read-only pages are allowed
to be configured in the second-stage table of a nested translation.
For simplicity the 2nd restriction is not relaxed even when the nesting
is turned off later due to vIOMMU config change. In concept if the user
understands this errata and does expect to enable nested translation
it should never install any RO mapping in stage-2 in the entire VM life
cycle. Accordingly introduce a single sticky bit to mark the parent role
on a domain instead of tracking the role with a counter.
Reference from Sapphire Rapids Specification Update [1], errata details,
SPR17.
[1] https://www.intel.com/content/www/us/en/content-details/772415/content-details.html
Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
Signed-off-by: Yi Liu <yi.l.liu@intel.com>
---
drivers/iommu/intel/iommu.c | 14 ++++++++++++++
drivers/iommu/intel/iommu.h | 4 ++++
drivers/iommu/intel/nested.c | 14 +++++++++++++-
include/uapi/linux/iommufd.h | 12 +++++++++++-
4 files changed, 42 insertions(+), 2 deletions(-)
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index ba34827045e6..caaa3a58dc94 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -2138,6 +2138,7 @@ __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
struct dma_pte *first_pte = NULL, *pte = NULL;
unsigned int largepage_lvl = 0;
unsigned long lvl_pages = 0;
+ unsigned long flags;
phys_addr_t pteval;
u64 attr;
@@ -2147,6 +2148,18 @@ __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
if ((prot & (DMA_PTE_READ|DMA_PTE_WRITE)) == 0)
return -EINVAL;
+ if (!(prot & DMA_PTE_WRITE) && !domain->read_only_mapped) {
+ spin_lock_irqsave(&domain->lock, flags);
+ if (domain->set_nested) {
+ pr_err_ratelimited("No read-only mapping permitted\n");
+ spin_unlock_irqrestore(&domain->lock, flags);
+ return -EINVAL;
+ }
+
+ domain->read_only_mapped = true;
+ spin_unlock_irqrestore(&domain->lock, flags);
+ }
+
attr = prot & (DMA_PTE_READ | DMA_PTE_WRITE | DMA_PTE_SNP);
attr |= DMA_FL_PTE_PRESENT;
if (domain->use_first_level) {
@@ -4758,6 +4771,7 @@ static void *intel_iommu_hw_info(struct device *dev, u32 *length)
if (!vtd)
return ERR_PTR(-ENOMEM);
+ vtd->flags = IOMMU_HW_INFO_VTD_ERRATA_772415_SPR17;
vtd->cap_reg = iommu->cap;
vtd->ecap_reg = iommu->ecap;
*length = sizeof(*vtd);
diff --git a/drivers/iommu/intel/iommu.h b/drivers/iommu/intel/iommu.h
index 5b292213bcb8..2a14fab6ac4f 100644
--- a/drivers/iommu/intel/iommu.h
+++ b/drivers/iommu/intel/iommu.h
@@ -592,6 +592,10 @@ struct dmar_domain {
* otherwise, goes through the second
* level.
*/
+ u8 read_only_mapped:1; /* domain has mappings with read-only
+ * permission.
+ */
+ u8 set_nested:1; /* has other domains nested on it */
spinlock_t lock; /* Protect device tracking lists */
struct list_head devices; /* all devices' list */
diff --git a/drivers/iommu/intel/nested.c b/drivers/iommu/intel/nested.c
index 2739c0d7880d..50934da613fa 100644
--- a/drivers/iommu/intel/nested.c
+++ b/drivers/iommu/intel/nested.c
@@ -142,14 +142,26 @@ struct iommu_domain *intel_nested_domain_alloc(struct iommu_domain *s2_domain,
const union iommu_domain_user_data *user_data)
{
const struct iommu_hwpt_vtd_s1 *vtd = (struct iommu_hwpt_vtd_s1 *)user_data;
+ struct dmar_domain *s2_dmar_domain = to_dmar_domain(s2_domain);
struct dmar_domain *domain;
+ unsigned long flags;
domain = kzalloc(sizeof(*domain), GFP_KERNEL_ACCOUNT);
if (!domain)
return NULL;
+ spin_lock_irqsave(&s2_dmar_domain->lock, flags);
+ if (s2_dmar_domain->read_only_mapped) {
+ spin_unlock_irqrestore(&s2_dmar_domain->lock, flags);
+ pr_err_ratelimited("S2 domain has read-only mappings\n");
+ kfree(domain);
+ return NULL;
+ }
+ s2_dmar_domain->set_nested = true;
+ spin_unlock_irqrestore(&s2_dmar_domain->lock, flags);
+
domain->use_first_level = true;
- domain->s2_domain = to_dmar_domain(s2_domain);
+ domain->s2_domain = s2_dmar_domain;
domain->s1_pgtbl = vtd->pgtbl_addr;
domain->s1_cfg = *vtd;
domain->domain.ops = &intel_nested_domain_ops;
diff --git a/include/uapi/linux/iommufd.h b/include/uapi/linux/iommufd.h
index 0dfb6f3d8dda..2f8f2dab95a7 100644
--- a/include/uapi/linux/iommufd.h
+++ b/include/uapi/linux/iommufd.h
@@ -435,10 +435,20 @@ struct iommu_hwpt_alloc {
};
#define IOMMU_HWPT_ALLOC _IO(IOMMUFD_TYPE, IOMMUFD_CMD_HWPT_ALLOC)
+/**
+ * enum iommu_hw_info_vtd_flags - Flags for VT-d hw_info
+ * @IOMMU_HW_INFO_VTD_ERRATA_772415_SPR17: If set, disallow nesting on domains
+ * with read-only mapping.
+ * https://www.intel.com/content/www/us/en/content-details/772415/content-details.html
+ */
+enum iommu_hw_info_vtd_flags {
+ IOMMU_HW_INFO_VTD_ERRATA_772415_SPR17 = 1 << 0,
+};
+
/**
* struct iommu_hw_info_vtd - Intel VT-d hardware information
*
- * @flags: Must be 0
+ * @flags: Combination of enum iommu_hw_info_vtd_flags
* @__reserved: Must be 0
*
* @cap_reg: Value of Intel VT-d capability register defined in VT-d spec
--
2.34.1
next prev parent reply other threads:[~2023-07-24 11:14 UTC|newest]
Thread overview: 75+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-07-24 11:13 [PATCH v4 00/12] Add Intel VT-d nested translation Yi Liu
2023-07-24 11:13 ` [PATCH v4 01/12] iommufd: Add data structure for Intel VT-d stage-1 domain allocation Yi Liu
2023-08-02 6:40 ` Tian, Kevin
2023-07-24 11:13 ` [PATCH v4 02/12] iommu/vt-d: Extend dmar_domain to support nested domain Yi Liu
2023-08-02 6:42 ` Tian, Kevin
2023-07-24 11:13 ` [PATCH v4 03/12] iommu/vt-d: Add helper for nested domain allocation Yi Liu
2023-08-02 6:44 ` Tian, Kevin
2023-07-24 11:13 ` [PATCH v4 04/12] iommu/vt-d: Add helper to setup pasid nested translation Yi Liu
2023-08-02 7:10 ` Tian, Kevin
2023-08-02 8:09 ` Baolu Lu
2023-08-02 8:11 ` Baolu Lu
2023-08-02 8:13 ` Tian, Kevin
2023-08-03 3:13 ` Baolu Lu
2023-08-03 3:58 ` Tian, Kevin
2023-07-24 11:13 ` [PATCH v4 05/12] iommu/vt-d: Make domain attach helpers to be extern Yi Liu
2023-08-02 7:14 ` Tian, Kevin
2023-07-24 11:13 ` [PATCH v4 06/12] iommu/vt-d: Set the nested domain to a device Yi Liu
2023-08-02 7:22 ` Tian, Kevin
2023-08-03 3:17 ` Baolu Lu
2023-07-24 11:13 ` [PATCH v4 07/12] iommufd: Add data structure for Intel VT-d stage-1 cache invalidation Yi Liu
2023-08-02 7:41 ` Tian, Kevin
2023-08-02 13:47 ` Jason Gunthorpe
2023-08-03 0:38 ` Tian, Kevin
2023-08-04 13:04 ` Liu, Yi L
2023-08-04 14:03 ` Jason Gunthorpe
2023-08-07 14:02 ` Liu, Yi L
2023-07-24 11:13 ` [PATCH v4 08/12] iommu/vt-d: Make iotlb flush helpers to be extern Yi Liu
2023-08-02 7:41 ` Tian, Kevin
2023-07-24 11:13 ` [PATCH v4 09/12] iommu/vt-d: Add iotlb flush for nested domain Yi Liu
2023-08-02 7:46 ` Tian, Kevin
2023-08-03 3:24 ` Baolu Lu
2023-08-03 4:00 ` Tian, Kevin
2023-08-03 4:05 ` Baolu Lu
2023-08-03 4:13 ` Tian, Kevin
2023-08-03 7:36 ` Baolu Lu
2023-08-07 15:08 ` Liu, Yi L
2023-08-08 3:12 ` Nicolin Chen
2023-08-08 12:34 ` Jason Gunthorpe
2023-08-08 17:41 ` Nicolin Chen
2023-08-09 8:22 ` Tian, Kevin
2023-08-09 8:50 ` Liu, Yi L
2023-08-09 8:58 ` Tian, Kevin
2023-08-09 9:30 ` Liu, Yi L
2023-08-09 16:24 ` Jason Gunthorpe
2023-08-09 19:12 ` Nicolin Chen
2023-08-09 19:19 ` Jason Gunthorpe
2023-08-09 20:17 ` Nicolin Chen
2023-08-10 2:49 ` Tian, Kevin
2023-08-10 15:57 ` Jason Gunthorpe
2023-08-10 17:14 ` Nicolin Chen
2023-08-10 19:27 ` Jason Gunthorpe
2023-08-10 21:02 ` Nicolin Chen
2023-08-11 3:52 ` Tian, Kevin
2023-08-11 16:45 ` Nicolin Chen
2023-08-15 6:18 ` Nicolin Chen
2023-08-18 16:56 ` Jason Gunthorpe
2023-08-18 17:56 ` Nicolin Chen
2023-08-18 18:20 ` Jason Gunthorpe
2023-08-18 18:25 ` Nicolin Chen
2023-08-21 1:24 ` Tian, Kevin
2023-08-10 3:28 ` Liu, Yi L
2023-08-10 3:33 ` Nicolin Chen
2023-07-24 11:13 ` [PATCH v4 10/12] iommu/vt-d: Add nested domain allocation Yi Liu
2023-08-02 7:47 ` Tian, Kevin
2023-07-24 11:13 ` [PATCH v4 11/12] iommu/vt-d: Implement hw_info for iommu capability query Yi Liu
2023-08-15 16:31 ` Jason Gunthorpe
2023-08-16 0:35 ` Baolu Lu
2023-08-16 1:10 ` Nicolin Chen
2023-08-16 11:46 ` Jason Gunthorpe
2023-08-16 11:48 ` Baolu Lu
2023-08-16 12:03 ` Liu, Yi L
2023-07-24 11:13 ` Yi Liu [this message]
2023-08-02 7:59 ` [PATCH v4 12/12] iommu/vt-d: Disallow nesting on domains with read-only mappings Tian, Kevin
2023-08-03 3:27 ` Baolu Lu
2023-08-03 4:00 ` Tian, Kevin
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=20230724111335.107427-13-yi.l.liu@intel.com \
--to=yi.l.liu@intel.com \
--cc=alex.williamson@redhat.com \
--cc=baolu.lu@linux.intel.com \
--cc=chao.p.peng@linux.intel.com \
--cc=cohuck@redhat.com \
--cc=eric.auger@redhat.com \
--cc=iommu@lists.linux.dev \
--cc=jasowang@redhat.com \
--cc=jgg@nvidia.com \
--cc=joro@8bytes.org \
--cc=kevin.tian@intel.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=lulu@redhat.com \
--cc=mjrosato@linux.ibm.com \
--cc=nicolinc@nvidia.com \
--cc=peterx@redhat.com \
--cc=robin.murphy@arm.com \
--cc=shameerali.kolothum.thodi@huawei.com \
--cc=suravee.suthikulpanit@amd.com \
--cc=yi.y.sun@linux.intel.com \
--cc=zhenzhong.duan@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox