All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Leon Romanovsky" <leon@kernel.org>
Cc: linux-input@vger.kernel.org, linux-usb@vger.kernel.org,
	linux-pci@vger.kernel.org, dmitry.torokhov@gmail.com
Subject: Re: [PATCH 17/17] PCI: Replace untrusted state with device trust
Date: Fri, 06 Nov 2026 11:43:49 +0000	[thread overview]
Message-ID: <sashiko-outbox-201350@kernel.org> (raw)
In-Reply-To: <20261105-device-trust-core-v1-17-1e536825b4eb@nvidia.com>

Thank you for your contribution! Sashiko AI review found 3 potential
issues to consider:
- [High] PCI: default trust policy overwrites adversarial default in
  pci_setup_device()
- [High] PCI: broken adversarial trust inheritance in
  pci_set_default_trust_policy()
- [Medium] PCI: pci_dev_ats_permitted() drops PCI_ACS_TB after full
  authorization
--

commit 4f93e031c1b1cdb8175550bd66ba1ab96c7a1e00
Author: Leon Romanovsky <leon@kernel.org>

PCI: Replace untrusted state with device trust

This commit replaces the PCI-specific untrusted flag in struct pci_dev with
the generic device trust policy and trust level infrastructure, defaulting
removable PCI devices to DEVICE_TRUST_POLICY_ADVERSARY and updating IOMMU,
ATS, and ACS callers accordingly.

> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index 5b6960bbb35bc..139e6f7b4e022 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -1738,24 +1738,27 @@ static void set_pcie_cxl(struct pci_dev *dev)
>  
>  }
>  
> -static void set_pcie_untrusted(struct pci_dev *dev)
> +static void pci_set_default_trust_policy(struct pci_dev *dev)
>  {
> -	struct pci_dev *parent = pci_upstream_bridge(dev);
> +	struct pci_dev *parent = pci_physfn(dev);
> +
> +	if (dev->dev.trust_policy != DEVICE_TRUST_POLICY_DEFAULT)
> +		return;
> +
> +	if (parent == dev)
> +		parent = pci_upstream_bridge(dev);
>  
>  	if (!parent)
>  		return;
> -	/*
> -	 * If the upstream bridge is untrusted we treat this device as
> -	 * untrusted as well.
> -	 */
> -	if (parent->untrusted) {
> -		dev->untrusted = true;
> +
> +	if (device_policy_is_adversarial(&parent->dev)) {
> +		dev->dev.trust_policy = DEVICE_TRUST_POLICY_ADVERSARY;
>  		return;
>  	}
>  
>  	if (arch_pci_dev_is_removable(dev)) {
> -		pci_dbg(dev, "marking as untrusted\n");
> -		dev->untrusted = true;
> +		pci_dbg(dev, "setting adversarial trust policy\n");
> +		dev->dev.trust_policy = DEVICE_TRUST_POLICY_ADVERSARY;
>  	}
>  }

[Severity: High]
Can checking device_policy_is_adversarial(&parent->dev) in
pci_set_default_trust_policy() fail to propagate the adversarial default to
downstream ports and endpoints when the upstream bridge's trust_policy has
been overridden?

On x86 ACPI systems, for a PCIe switch connected to an integrated
USB4/Thunderbolt Root Port where root->external_facing and
pcie_has_usb4_host_interface(root) are true, arch_pci_dev_is_removable() in
arch/x86/pci/acpi.c returns true only for the Switch Upstream Port directly
under the Root Port:

arch/x86/pci/acpi.c:arch_pci_dev_is_removable() {
	...
	/* Anything directly behind a "usb4-host-interface" is tunneled */
	if (pcie_has_usb4_host_interface(parent))
		return true;

	/*
	 * Check if this is a discrete Thunderbolt/USB4 controller that is
	 * directly behind the non-USB4 PCIe Root Port marked as
	 * "ExternalFacingPort". Those are not behind a PCIe tunnel.
	 */
	if (pcie_switch_directly_under(root, pdev))
		return false;
	...
}

For the Switch Downstream Ports and Endpoints on that switch,
pcie_has_usb4_host_interface(parent) is false and
pcie_switch_directly_under(root, pdev) returns true, so
arch_pci_dev_is_removable() returns false and relies on inheritance from the
parent bridge.

Because pci_setup_device() calls device_trust_init(&dev->dev) on the parent
bridge before subordinate buses are scanned (or userspace updates the bridge's
trust_policy via sysfs before hotplugging a downstream device), overriding the
Switch Upstream Port's trust_policy to disabled or full changes
parent->dev.trust_policy away from DEVICE_TRUST_POLICY_ADVERSARY.

When child devices are subsequently set up, both
device_policy_is_adversarial(&parent->dev) and arch_pci_dev_is_removable(dev)
return false, leaving removable external devices at
DEVICE_TRUST_POLICY_DEFAULT (which resolves to DEVICE_TRUST_FULL) and
bypassing IOMMU DMA domain enforcement, ATS restrictions, ACS Translation
Blocking, and SWIOTLB bounce buffering.

>  
> @@ -2082,7 +2085,7 @@ int pci_setup_device(struct pci_dev *dev)
>  
>  	set_pcie_cxl(dev);
>  
> -	set_pcie_untrusted(dev);
> +	pci_set_default_trust_policy(dev);
>  	device_trust_init(&dev->dev);

[Severity: High]
What happens if a removable PCI device is configured with an explicit default
policy via device_trust=, device_trust.driver=, or sysfs trust_policy?

In pci_setup_device(), pci_set_default_trust_policy(dev) runs on a freshly
zero-allocated struct pci_dev before device_trust_init(&dev->dev). Because
dev->dev.trust_policy is always DEVICE_TRUST_POLICY_DEFAULT at that point, the
early return in pci_set_default_trust_policy() is never taken, and a removable
device is set to DEVICE_TRUST_POLICY_ADVERSARY.

Immediately afterward, device_trust_init(&dev->dev) invokes
device_trust_apply_boot_policy(). If the kernel command line contains a
per-device default rule such as:

  device_trust.default=disabled device_trust=pci:<bdf>=default

or if default is later selected via device_trust.driver= or by writing default
to sysfs trust_policy before binding, dev->dev.trust_policy is set to
DEVICE_TRUST_POLICY_DEFAULT.

Because pci_set_default_trust_policy() is never called again and pci_bus_type
does not implement bus_type->trust_resolve():
1. pci_dev_default_is_restricted() returns false for
   DEVICE_TRUST_POLICY_DEFAULT, allowing identity IOMMU domains in
   iommu_get_default_domain_type() and amd_iommu_def_domain_type(), IOMMU
   bypass quirks in risky_device(), ATS capability registration in
   pci_ats_init(), and omission of PCI_ACS_TB in pci_enable_acs().
2. At driver bind time, device_trust_prepare() calls
   device_trust_resolve_default(), which resolves DEVICE_TRUST_POLICY_DEFAULT
   to DEVICE_TRUST_FULL instead of DEVICE_TRUST_ADVERSARY, so
   device_is_adversarial() returns false and SWIOTLB bounce buffering in
   drivers/iommu/dma-iommu.c is skipped.

> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index aa3765a20a96c..087c63b177c85 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
[ ... ]
> @@ -616,6 +608,28 @@ static inline struct pci_dev *to_pci_dev(const struct device *dev)
>  {
>  	return container_of(dev, struct pci_dev, dev);
>  }
> +
> +static inline bool
> +pci_dev_default_is_restricted(const struct pci_dev *pdev)
> +{
> +	enum device_trust_policy policy = READ_ONCE(pdev->dev.trust_policy);
> +
> +	return policy == DEVICE_TRUST_POLICY_DISABLED ||
> +	       policy == DEVICE_TRUST_POLICY_ADVERSARY;
> +}
> +
> +static inline bool pci_dev_ats_permitted(const struct pci_dev *pdev)
> +{
> +	enum device_trust_level level = device_get_trust_level(&pdev->dev);
> +	enum device_trust_policy policy = READ_ONCE(pdev->dev.trust_policy);
> +
> +	if (level == DEVICE_TRUST_DISABLED)
> +		return policy != DEVICE_TRUST_POLICY_ADVERSARY &&
> +		       policy != DEVICE_TRUST_POLICY_DISABLED;
> +
> +	return level == DEVICE_TRUST_FULL;
> +}

[Severity: Medium]
Won't a device discovered with DEVICE_TRUST_POLICY_DISABLED lose PCI_ACS_TB
after being authorized as full and undergoing a reset or D3cold transition?

When a PCIe port or device is discovered with DEVICE_TRUST_POLICY_DISABLED
(for example via device_trust.default=disabled), pci_ats_init() sees
pci_dev_default_is_restricted(dev) == true and permanently skips recording
dev->ats_cap, while initial pci_enable_acs() sees
!pci_dev_ats_permitted(dev) == true and enables PCI_ACS_TB in
pci_std_enable_acs() or pci_quirk_enable_intel_spt_pch_acs().

If userspace in initrd later sets trust_policy to full and binds a driver,
dev->dev.trust_level becomes DEVICE_TRUST_FULL and pci_dev_ats_permitted(dev)
returns true even though dev->ats_cap is still 0.

Because PCI_EXT_CAP_ID_ACS is not saved in saved_cap_space, a subsequent PCI
reset or D3cold-to-D0 resume resets the hardware ACS control register and runs:

  pci_restore_state()
    -> pci_enable_acs()
      -> pci_std_enable_acs() / pci_quirk_enable_intel_spt_pch_acs()

At that point pci_dev_ats_permitted(dev) returns true, so PCI_ACS_TB is no
longer set even though ATS was never initialized for the device.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261105-device-trust-core-v1-0-1e536825b4eb@nvidia.com?part=17

      parent reply	other threads:[~2026-11-06 11:43 UTC|newest]

Thread overview: 72+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-05 11:42 [PATCH 00/17] driver core: Authorize device trust before driver binding Leon Romanovsky
2026-11-05 11:42 ` [PATCH 01/17] Input: gameport - attach manual drivers through the driver core Leon Romanovsky
2026-11-05 17:05   ` driver core: Authorize device trust before driver binding bluez.test.bot
2026-11-06 11:43   ` [PATCH 01/17] Input: gameport - attach manual drivers through the driver core sashiko-bot
2026-11-05 11:42 ` [PATCH 02/17] Input: serio " Leon Romanovsky
2026-11-05 17:05   ` Dmitry Torokhov
2026-11-05 19:19     ` Leon Romanovsky
2026-11-05 20:34       ` Dmitry Torokhov
2026-11-06 14:33         ` Leon Romanovsky
2026-11-06 11:43   ` sashiko-bot
2026-11-05 11:42 ` [PATCH 03/17] net: phy: Attach generic PHY " Leon Romanovsky
2026-11-05 14:50   ` Andrew Lunn
2026-11-05 18:35     ` Leon Romanovsky
2026-11-05 15:33   ` Andrew Lunn
2026-11-05 18:45     ` Leon Romanovsky
2026-11-06 11:43   ` sashiko-bot
2026-11-05 11:42 ` [PATCH 04/17] wifi: mac80211_hwsim: lock device for manual driver binding Leon Romanovsky
2026-11-06 11:43   ` sashiko-bot
2026-11-05 11:42 ` [PATCH 05/17] USB: Lock registered interfaces during " Leon Romanovsky
2026-11-05 17:24   ` Alan Stern
2026-11-05 18:44     ` Leon Romanovsky
2026-11-05 20:04       ` Alan Stern
2026-11-08 11:09         ` Leon Romanovsky
2026-11-08 16:59           ` Alan Stern
2026-11-09  9:23             ` Leon Romanovsky
2026-11-06 11:43   ` sashiko-bot
2026-11-05 11:42 ` [PATCH 06/17] PNP: Attach card devices through the driver core Leon Romanovsky
2026-11-06 11:43   ` sashiko-bot
2026-11-05 11:42 ` [PATCH 07/17] cdx: Propagate DMA configuration errors Leon Romanovsky
2026-11-06 11:43   ` sashiko-bot
2026-11-05 11:42 ` [PATCH 08/17] driver core: Allow userspace to detect EPROBE_DEFER when using sysfs drivers_probe Leon Romanovsky
2026-11-06 11:43   ` sashiko-bot
2026-11-05 11:42 ` [PATCH 09/17] driver core: Introduce a generic device trust level Leon Romanovsky
2026-11-06 11:43   ` sashiko-bot
2026-11-05 11:42 ` [PATCH 10/17] driver core: Expose device trust authorization through sysfs Leon Romanovsky
2026-11-05 13:10   ` Greg Kroah-Hartman
2026-11-05 13:27     ` Leon Romanovsky
2026-11-05 13:40       ` Greg Kroah-Hartman
2026-11-05 13:59         ` Robin Murphy
2026-11-05 14:03           ` Greg Kroah-Hartman
2026-11-05 14:17             ` Leon Romanovsky
2026-11-05 14:26             ` Robin Murphy
2026-11-05 15:45               ` Greg Kroah-Hartman
2026-11-05 14:06           ` Jason Gunthorpe
2026-11-05 14:43           ` Andrew Lunn
2026-11-05 14:59             ` Jason Gunthorpe
2026-11-05 15:09             ` Robin Murphy
2026-11-05 13:42       ` Robin Murphy
2026-11-05 17:02   ` Jason Gunthorpe
2026-11-05 19:06     ` Leon Romanovsky
2026-11-06 11:43   ` sashiko-bot
2026-11-05 11:42 ` [PATCH 11/17] driver core: Accept device trust policy on the kernel command line Leon Romanovsky
2026-11-06 11:43   ` sashiko-bot
2026-11-05 11:42 ` [PATCH 12/17] driver core: Accept device trust policy by driver name Leon Romanovsky
2026-11-06 11:43   ` sashiko-bot
2026-11-05 11:42 ` [PATCH 13/17] driver core: Preserve trust commitment beyond driver binding Leon Romanovsky
2026-11-06 11:43   ` sashiko-bot
2026-11-05 11:42 ` [PATCH 14/17] driver core: Add a global initial device trust policy Leon Romanovsky
2026-11-06 11:43   ` sashiko-bot
2026-11-05 11:42 ` [PATCH 15/17] driver core: Cover trust authorization and binding with KUnit Leon Romanovsky
2026-11-06 11:43   ` sashiko-bot
2026-11-05 11:42 ` [PATCH 16/17] driver core: Document trust admission and initrd authorization Leon Romanovsky
2026-11-06 11:43   ` sashiko-bot
2026-11-05 11:42 ` [PATCH 17/17] PCI: Replace untrusted state with device trust Leon Romanovsky
2026-11-05 13:12   ` Greg Kroah-Hartman
2026-11-05 13:18     ` Leon Romanovsky
2026-11-05 13:26       ` Greg Kroah-Hartman
2026-11-05 14:03       ` Jason Gunthorpe
2026-11-05 15:43         ` Greg Kroah-Hartman
2026-11-05 16:26           ` Jason Gunthorpe
2026-11-05 18:26           ` Leon Romanovsky
2026-11-06 11:43   ` sashiko-bot [this message]

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=sashiko-outbox-201350@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=dmitry.torokhov@gmail.com \
    --cc=leon@kernel.org \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /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.