From nobody Sun Feb 8 07:59:09 2026 Received: from mail-ed1-f50.google.com (mail-ed1-f50.google.com [209.85.208.50]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EC4501624D5 for ; Sun, 21 Dec 2025 01:43:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1766281396; cv=none; b=CfzOjb5hu1ihck/CFdajaEtJs++hmXVCic9GClKn52jg9olo34+co8nYFAjNvFDkEcKkPqb0HQO4CkkKRGF5m8Ye5YHwVqwFMlYdbaF7fee570svyfQZIyuC0eTHUEOg8f0WjWCrCrMN7AfOSQfBFuDHSfPRa2NwjbWJEn6fu8E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1766281396; c=relaxed/simple; bh=c6l+DaU5BDXL/1UKC1uRvyXoD6pUE+hzGySChC03UOU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=cRkppXPSLIFtvEfzPPLiwmlkHre2PSw2p1/p7UhJROYGkuCO1PfBlYecEaHy8VfM2b1DzQ0+gg66XNb1HFxjsSYdJ35nXo15a6/PHQbjnvRsHz3jg6mSXlYXP3FyhAcJkGFIuxScLvCibWsJV8QQ+C2yQh9oBCnVW4LgTU+h+zc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=ApfP8sKO; arc=none smtp.client-ip=209.85.208.50 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="ApfP8sKO" Received: by mail-ed1-f50.google.com with SMTP id 4fb4d7f45d1cf-63c489f1e6cso2643054a12.1 for ; Sat, 20 Dec 2025 17:43:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1766281393; x=1766886193; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=zzPkvFiJPIiBH8gY2E1M7voQ7WOeiTfZU7yF7kFKn4c=; b=ApfP8sKOdHwQpJMlhdxAYIXh4UBRQ1E9FaHGpZWlSd3+dPymMx2PkVZkHEkqlG3gGz ztyQvwxLmjk6sjO1R9aexxhTopem4ygxDjnysCd5vfqyWOZHpxn7/PTMm0wzU1MNh5Zj Fgl4WCulWksXbcpiyMDLki5huCj8wMQqYqcts= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1766281393; x=1766886193; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=zzPkvFiJPIiBH8gY2E1M7voQ7WOeiTfZU7yF7kFKn4c=; b=u90D6tWY46H3HZqoHUAV5ibBvqOicKqswyp/ZPQ4WMwgM44c/dziuZPzHFjZDAgxzD +UtMbuzOeGBhCNfVpsRhifbB5qbhj5n1zmdLyNg4XtnY3EuF6812iNzyF9E+fJ2LTQ15 +2rw+wji/5/4i+k1NEVj12Gmtvs0PyLf0jKLwkbGEazDbCmMWjuuGpXkrgQR8LOAa1La zinW8Imd/YvR9i2hr2gGx365pEEqasOX/AIvBwPaTNbRBHab610FYUy4GnsplJOIDlCd vcgK8OnesGbgEG0t7RlHfF45WMUA3cm4jyROIK9IGT4ilOWOhEAkdLeekxG18hqGPGyv PDpw== X-Forwarded-Encrypted: i=1; AJvYcCXtQMJhTDDHQOHFAKy/PA4rQzwuD75wLdp2hCJGeiVZHdVhMCHmfKcgTJ2EXgaIyTlb9n83TUbOKL/Qyuo=@vger.kernel.org X-Gm-Message-State: AOJu0YyPGH3Z1/ktd5g7uovvo2P8pOkQ1pSqFk7jEFKmSdh/+GYW8K1s pEl7ML3aX9EhHWkTkC5iQ3NMG3fXGYlaMZGZqpU3OrJCS3IsgC68C5CwkO3QEnfTLw== X-Gm-Gg: AY/fxX7F1br207Awnk6rm8WQKIc8vT+KoJdCxm9hxfaT/hKY8XLleESTCMpvwwSmUWo bqzwo9nUkdW+OFZjL1Xb2gfp8ShbRkcevg0ghUXNIIdt5lWd39+knIQBXMBIS+F2wjsZj/GaK6H Mr8C8PaxYMdLGUU34BN9lM9obqBOJVMcUEV22WG7fQqsbUjJuZ4CU3xtJOqEERjlzF+WLC7cBfB b1kdChwP0v5em+FVi0gu7QkydsRlMC2N1ww4YYZtMbJfvKVaSWghkG2eKycNbh+6F7S7E+BvUQX vTtVlhbLsHuRzqeHjF91WCeVYm5BbS3kh3Q1cHmzdzbGo615JIUhuB5E5iwXTxhkFx8ktkSgay2 gFnMtK0tlZPVnKQTyT8gINedShf4ePbytmYtlWB/kUfnnnWbTXzF1xRDJpsCsBeaFcNo6r4Q7Fp CNJT9BmVBs9nLnbmvF3DPsmEjXyYxv1w== X-Google-Smtp-Source: AGHT+IESd/5ZjLIUwnYgaHogwawMT0Vq1dN1amO4mHbs9tVB78ygz08actIt/pnZ5iaj+QSjD2Ia6w== X-Received: by 2002:a05:6402:1467:b0:64b:5851:5e7b with SMTP id 4fb4d7f45d1cf-64b8d34f12dmr7723823a12.14.1766281393302; Sat, 20 Dec 2025 17:43:13 -0800 (PST) Received: from localhost.localdomain ([2a02:a31b:20c3:6680:4cc9:1698:dce5:4976]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-64b91494cd7sm6035057a12.16.2025.12.20.17.43.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 20 Dec 2025 17:43:12 -0800 (PST) From: Dmytro Maluka To: David Woodhouse , Lu Baolu , iommu@lists.linux.dev Cc: Joerg Roedel , Will Deacon , Robin Murphy , linux-kernel@vger.kernel.org, "Vineeth Pillai (Google)" , Aashish Sharma , Grzegorz Jaszczyk , Chuanxiao Dong , Kevin Tian , Dmytro Maluka Subject: [PATCH 1/2] iommu/vt-d: Ensure memory ordering in context entry updates Date: Sun, 21 Dec 2025 02:43:01 +0100 Message-ID: <20251221014302.17738-2-dmaluka@chromium.org> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251221014302.17738-1-dmaluka@chromium.org> References: <20251221014302.17738-1-dmaluka@chromium.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" When updating context table entries, we do take care to set the present bit as the last step, i.e. in the following order: context_clear_entry(context); context_set_present(context); However, we don't actually ensure this order, i.e. don't prevent the compiler from reordering it. And since context entries may be updated at runtime when translation is already enabled, this may potentially allow a time window when a device can already do DMA while the translation is not properly set up yet (e.g. the context entry may point to an arbitrary page table). To easily fix this, change context_set_*() and context_clear_*() helpers to use READ_ONCE/WRITE_ONCE, to ensure that the ordering between updates of individual bits in context entries matches the order of calling those helpers, just like we already do for PASID table entries. Link: https://lore.kernel.org/all/aTG7gc7I5wExai3S@google.com/ Signed-off-by: Dmytro Maluka --- drivers/iommu/intel/iommu.h | 37 +++++++++++++++++++++---------------- drivers/iommu/intel/pasid.c | 3 ++- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/drivers/iommu/intel/iommu.h b/drivers/iommu/intel/iommu.h index 25c5e22096d4..7f8f004fa756 100644 --- a/drivers/iommu/intel/iommu.h +++ b/drivers/iommu/intel/iommu.h @@ -869,7 +869,7 @@ static inline bool dma_pte_superpage(struct dma_pte *pt= e) =20 static inline bool context_present(struct context_entry *context) { - return (context->lo & 1); + return READ_ONCE(context->lo) & 1; } =20 #define LEVEL_STRIDE (9) @@ -897,46 +897,51 @@ static inline int pfn_level_offset(u64 pfn, int level) return (pfn >> level_to_offset_bits(level)) & LEVEL_MASK; } =20 +static inline void context_set_bits(u64 *ptr, u64 mask, u64 bits) +{ + u64 old; + + old =3D READ_ONCE(*ptr); + WRITE_ONCE(*ptr, (old & ~mask) | bits); +} =20 static inline void context_set_present(struct context_entry *context) { - context->lo |=3D 1; + context_set_bits(&context->lo, 1 << 0, 1); } =20 static inline void context_set_fault_enable(struct context_entry *context) { - context->lo &=3D (((u64)-1) << 2) | 1; + context_set_bits(&context->lo, 1 << 1, 0); } =20 static inline void context_set_translation_type(struct context_entry *cont= ext, unsigned long value) { - context->lo &=3D (((u64)-1) << 4) | 3; - context->lo |=3D (value & 3) << 2; + context_set_bits(&context->lo, GENMASK_ULL(3, 2), value << 2); } =20 static inline void context_set_address_root(struct context_entry *context, unsigned long value) { - context->lo &=3D ~VTD_PAGE_MASK; - context->lo |=3D value & VTD_PAGE_MASK; + context_set_bits(&context->lo, VTD_PAGE_MASK, value); } =20 static inline void context_set_address_width(struct context_entry *context, unsigned long value) { - context->hi |=3D value & 7; + context_set_bits(&context->hi, GENMASK_ULL(2, 0), value); } =20 static inline void context_set_domain_id(struct context_entry *context, unsigned long value) { - context->hi |=3D (value & ((1 << 16) - 1)) << 8; + context_set_bits(&context->hi, GENMASK_ULL(23, 8), value << 8); } =20 static inline void context_set_pasid(struct context_entry *context) { - context->lo |=3D CONTEXT_PASIDE; + context_set_bits(&context->lo, CONTEXT_PASIDE, CONTEXT_PASIDE); } =20 static inline int context_domain_id(struct context_entry *c) @@ -946,8 +951,8 @@ static inline int context_domain_id(struct context_entr= y *c) =20 static inline void context_clear_entry(struct context_entry *context) { - context->lo =3D 0; - context->hi =3D 0; + WRITE_ONCE(context->lo, 0); + WRITE_ONCE(context->hi, 0); } =20 #ifdef CONFIG_INTEL_IOMMU @@ -980,7 +985,7 @@ clear_context_copied(struct intel_iommu *iommu, u8 bus,= u8 devfn) static inline void context_set_sm_rid2pasid(struct context_entry *context, unsigned long pasi= d) { - context->hi |=3D pasid & ((1 << 20) - 1); + context_set_bits(&context->hi, GENMASK_ULL(19, 0), pasid); } =20 /* @@ -989,7 +994,7 @@ context_set_sm_rid2pasid(struct context_entry *context,= unsigned long pasid) */ static inline void context_set_sm_dte(struct context_entry *context) { - context->lo |=3D BIT_ULL(2); + context_set_bits(&context->lo, BIT_ULL(2), BIT_ULL(2)); } =20 /* @@ -998,7 +1003,7 @@ static inline void context_set_sm_dte(struct context_e= ntry *context) */ static inline void context_set_sm_pre(struct context_entry *context) { - context->lo |=3D BIT_ULL(4); + context_set_bits(&context->lo, BIT_ULL(4), BIT_ULL(4)); } =20 /* @@ -1007,7 +1012,7 @@ static inline void context_set_sm_pre(struct context_= entry *context) */ static inline void context_clear_sm_pre(struct context_entry *context) { - context->lo &=3D ~BIT_ULL(4); + context_set_bits(&context->lo, BIT_ULL(4), 0); } =20 /* Returns a number of VTD pages, but aligned to MM page size */ diff --git a/drivers/iommu/intel/pasid.c b/drivers/iommu/intel/pasid.c index 77b9b147ab50..7e2b75bcecd4 100644 --- a/drivers/iommu/intel/pasid.c +++ b/drivers/iommu/intel/pasid.c @@ -984,7 +984,8 @@ static int context_entry_set_pasid_table(struct context= _entry *context, context_clear_entry(context); =20 pds =3D context_get_sm_pds(table); - context->lo =3D (u64)virt_to_phys(table->table) | context_pdts(pds); + WRITE_ONCE(context->lo, + (u64)virt_to_phys(table->table) | context_pdts(pds)); context_set_sm_rid2pasid(context, IOMMU_NO_PASID); =20 if (info->ats_supported) --=20 2.47.3 From nobody Sun Feb 8 07:59:09 2026 Received: from mail-ed1-f49.google.com (mail-ed1-f49.google.com [209.85.208.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D4D68208994 for ; Sun, 21 Dec 2025 01:43:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1766281399; cv=none; b=Iy/iAfrpdnnCeeBSxOX/SUPsds/v8n4RRBFbtao+ZwmymTNOjn6OtsZ5KPikEN5v5tPb8bxDf31b/Fwd3DQv2G4MFZ/l5WWggjsznkOFrFS5HKd15IBpQmRFRuLae35XzIGXieCrdBpoIwSyfuhe4Sbiecw38LFyQiVyNJO9ptY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1766281399; c=relaxed/simple; bh=9RiGqegA+I06hOdZVhqRmVQPuiaovCLQJvml01CovCo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=eUSmttDoStCHjP+uzl2ffxLXVuRxjw7mu4Xh2wWUITGaBQnW0AlebnnZRnCRaxkxQJblcQ1GPMi5UUhK+c99G/e9kQ5BWrDor+lk/77D+/4qp8sff9AahZfJn1k65qiuYe5i77R4hv6awkKNTGTqN9WCzQEqK/WpX4VhlbATaA0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=Tmn7P0sQ; arc=none smtp.client-ip=209.85.208.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="Tmn7P0sQ" Received: by mail-ed1-f49.google.com with SMTP id 4fb4d7f45d1cf-64b9230f564so2714897a12.1 for ; Sat, 20 Dec 2025 17:43:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1766281396; x=1766886196; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=xQloxxqbMq59HRml2naqXd5o6tDHZgoJwROCKxXlYAs=; b=Tmn7P0sQ5lIWvzQGKZ2m8+HI3uHIR0OGQjkH8XjFEYczrZXsaMCLKxqnf1RSZrPE6G C7F8Okd2hcSegsY221dGpwWwN+bJBS5QpmqSSe3zZX+zaR38Fvlb2qgL4X939Vo7bzQD 1QCn7QbsnvTQWwF6DUrSxvl9Eju9wHLf3uHKg= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1766281396; x=1766886196; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=xQloxxqbMq59HRml2naqXd5o6tDHZgoJwROCKxXlYAs=; b=YmHepD2q+dsLed8p0WXyDpHFzPpM/tnOmaHbSYJWBoSS5e2V9PshLp0STLf2UoK5tf OvKiWVZ6QwV8ehd1M7GgAkyKe09Rhhi5Zlu3f0oM+5mqA9vXWVlbv2LLr5tvyT0iXqIH 6Vct0vadDpWMyvvbVE7hoDBaRFxTsQzh3nG9EUIFej8edge24JtocgqhO/va4OzP0ETa NR4bxA1O0xuGEIBgMbO5P0Gkd4aY0cWTf0AEPm0CmZjDhjX5RmzAWHQODv7j+iTHxEeB KfR6wOszxFbGf2e3D745RUlUl+Ee8ABQEsIbdnMqq5FCO4vqsr1lNEqew2ZlZtd/XqNz q+zg== X-Forwarded-Encrypted: i=1; AJvYcCUmhWOntTJuQoJRYH1cL4nSBUZZgZYsdAvGhHfZEBJQlQLsmqqJldxKJOW2QqyZoTVFa0CUP86KDhL5dA4=@vger.kernel.org X-Gm-Message-State: AOJu0YzMGTWqdxOOvmbAVW9oBJz4S5qfTULom4pJ5haQcfUq9yd+SURy S88uUgD6BsIResY/pAVDu8+ZxhLNcjNQ6bbK92n+qQ+5NFcJb1Y6ub9KAVHYATf4MA== X-Gm-Gg: AY/fxX50SrmLPDz3RtZSkq7LciDAMJkcVIilkAG5Yqk/5bu1eAeEYC+IXLwk1YgD/Ll dDNIJqW2eHDqQp2xJEgfkPvSJ19H67542E6ZJCqhpNDhXhK8DpK9ixnGkugkd7jlifcWQ5ptv4u qGEIVuElJqWS8ARorzyjlsHE+Bn5nka6sNzU3UIgyFpwcIE8WtjpXhKPET+R3uUj0GOlynbguas s1Q55Jq6WPQHCu03ld26MauwOehmVc0CPySN7a0Qv+ZEtnG0b/Pmw0RJw+dqpRCQXWl3nCM/3La 82cUgGZ6+zT1Ijtly1jvSsPrFJzwyy1Ym8rfP2oCiQheArhGS5d0Pf5RXGKpL+WrfEy03Uu0bki Rhxn6540GznsecvDjweeuRIBrbxqXdptFMSlj582+lq4TLIjXene2lyMFz/RjN6DrhJrfXyZXYe D33WQYglDHKaR/laIrEdPHsDyuk7vUMg== X-Google-Smtp-Source: AGHT+IE6mMRclKAr1rYh6yhTZWqrpVE1fjTnJAOiLMa5n/4qjlrNROGwi5MSihG5EECAzufaISb6qA== X-Received: by 2002:a05:6402:350e:b0:649:afbf:ce4c with SMTP id 4fb4d7f45d1cf-64b8ea60cf2mr6239796a12.3.1766281396039; Sat, 20 Dec 2025 17:43:16 -0800 (PST) Received: from localhost.localdomain ([2a02:a31b:20c3:6680:4cc9:1698:dce5:4976]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-64b91494cd7sm6035057a12.16.2025.12.20.17.43.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 20 Dec 2025 17:43:15 -0800 (PST) From: Dmytro Maluka To: David Woodhouse , Lu Baolu , iommu@lists.linux.dev Cc: Joerg Roedel , Will Deacon , Robin Murphy , linux-kernel@vger.kernel.org, "Vineeth Pillai (Google)" , Aashish Sharma , Grzegorz Jaszczyk , Chuanxiao Dong , Kevin Tian , Dmytro Maluka Subject: [PATCH 2/2] iommu/vt-d: Use WRITE_ONCE for setting root table entries Date: Sun, 21 Dec 2025 02:43:02 +0100 Message-ID: <20251221014302.17738-3-dmaluka@chromium.org> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251221014302.17738-1-dmaluka@chromium.org> References: <20251221014302.17738-1-dmaluka@chromium.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Like context table entries in the previous patch, root table entries may also be set up at runtime, when DMA translation is already enabled (e.g. due to a device hotplug). So to stay on the safe side, use WRITE_ONCE when setting a root table entry, to prevent the compiler from doing store tearing which could result in setting the present bit earlier than the context table address bits. Signed-off-by: Dmytro Maluka --- drivers/iommu/intel/iommu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index 134302fbcd92..fe4d0d210a5f 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -374,7 +374,7 @@ struct context_entry *iommu_context_addr(struct intel_i= ommu *iommu, u8 bus, =20 __iommu_flush_cache(iommu, (void *)context, CONTEXT_SIZE); phy_addr =3D virt_to_phys((void *)context); - *entry =3D phy_addr | 1; + WRITE_ONCE(*entry, phy_addr | 1); __iommu_flush_cache(iommu, entry, sizeof(*entry)); } return &context[devfn]; --=20 2.47.3