From: Dan Williams <djbw@kernel.org>
To: linux-coco@lists.linux.dev
Cc: linux-pci@vger.kernel.org, driver-core@lists.linux.dev,
ankita@nvidia.com,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
"Rafael J. Wysocki" <rafael@kernel.org>,
Danilo Krummrich <dakr@kernel.org>,
Bjorn Helgaas <bhelgaas@google.com>,
Dexuan Cui <decui@microsoft.com>
Subject: [PATCH 13/15] PCI, device core: Add private memory access for DEVICE_TRUST_TCB
Date: Sun, 5 Jul 2026 15:08:17 -0700 [thread overview]
Message-ID: <20260705220819.2472765-14-djbw@kernel.org> (raw)
In-Reply-To: <20260705220819.2472765-1-djbw@kernel.org>
A device that wants to access private memory needs to have its trust
elevated to DEVICE_TRUST_TCB. That trust is established either at compile
time (unlikely), the bus knows the device is within the TCB to start (some
paravisor setups), or the device is dynamically added to the TCB in
coordination with a TSM driver (primary TDISP use case) and the trust is
elevated by driver match.
When a PCI device is associated with a TSM for security services the low
level TSM driver in the CC VM has the opportunity validate DMA access.
That validation happens at ->dma_configure() time when the device attaches
to a driver. The TSM driver is responsible for proving to the platform TSM
that the VM is enabling DMA with respect to the most recently generated
evidence. If that fails, driver attach fails.
When a PCI device is not associated with a TSM provider for security
services, but the device is trusted there are 3 options.
1/ Arch requires all DMA enable events to be acked by TSM driver
2/ Arch does not require, but admin policy is responsible for knowing which
devices need TSM coordination to become active within the TCB.
3/ Device is approved by a paravisor to operate within the TCB, no TSM
coordination required.
In cases 2 and 3 if the device needed TSM driver coordination, but the TSM
driver or association to the device is missing, it triggers hardware
errors. Those errors are a configuration error that the kernel does not
actively prevent.
Architectures still need to fixup force_dma_unencrypted() to call
device_tcb_trusted() to tell the DMA layer that TCB access is granted.
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Cc: Danilo Krummrich <dakr@kernel.org>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Dexuan Cui <decui@microsoft.com>
Signed-off-by: Dan Williams <djbw@kernel.org>
---
drivers/base/Kconfig | 19 ++++++++++++++++++-
include/linux/device/trust.h | 4 ++++
drivers/base/trust.c | 8 ++++++++
drivers/pci/pci-driver.c | 25 ++++++++++++++++---------
4 files changed, 46 insertions(+), 10 deletions(-)
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index a4233bdf9804..3597b39ee0e3 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -304,7 +304,17 @@ config DEVICE_TRUST_AUTO
help
Typical historical driver model, devices eagerly attempt to attach to
a driver and deploy all available mechanisms to allow performant
- direct memory access.
+ direct memory access. This trust level does not include TCB privileges.
+
+config DEVICE_TRUST_TCB
+ bool "TCB"
+ depends on EXPERT
+ help
+ Devices are assumed to be within the Trusted Compute Boundary (TCB)
+ with access to private TCB resources by default. This requires buses
+ to have trust awareness and opt devices out of private operation,
+ otherwise TCB integrity may fail the device's access or escalate to
+ terminating the execution context (kill the CC VM).
endchoice
@@ -330,6 +340,13 @@ config BUILTIN_DEVICE_TRUST_ADVERSARY
help
Deploy mitigations in the IOMMU layer and driver to limit access.
+config BUILTIN_DEVICE_TRUST_TCB
+ bool "TCB"
+ depends on EXPERT
+ help
+ Devices bound by built-in drivers are assumed to be within the
+ Trusted Compute Boundary with access to private/encrypted memory.
+
endchoice
endmenu
diff --git a/include/linux/device/trust.h b/include/linux/device/trust.h
index 283d3196e5e6..24951f5c56ba 100644
--- a/include/linux/device/trust.h
+++ b/include/linux/device/trust.h
@@ -13,6 +13,7 @@
* @DEVICE_TRUST_NONE: Blocked when idle, cannot bind
* @DEVICE_TRUST_ADVERSARY: Blocked when idle, constrained when active.
* @DEVICE_TRUST_AUTO: All typical privileges granted
+ * @DEVICE_TRUST_TCB: AUTO privileges + private/encrypted memory access
*
* Devices flagged as adversarial are the ones that can potentially
* execute DMA attacks and similar. They are typically connected through
@@ -25,11 +26,13 @@ enum device_trust {
DEVICE_TRUST_NONE,
DEVICE_TRUST_ADVERSARY,
DEVICE_TRUST_AUTO,
+ DEVICE_TRUST_TCB,
};
#define DEVICE_DEFAULT_TRUST \
(IS_ENABLED(CONFIG_DEVICE_TRUST_NONE) ? DEVICE_TRUST_NONE : \
IS_ENABLED(CONFIG_DEVICE_TRUST_ADVERSARY) ? DEVICE_TRUST_ADVERSARY : \
+ IS_ENABLED(CONFIG_DEVICE_TRUST_TCB) ? DEVICE_TRUST_TCB : \
DEVICE_TRUST_AUTO)
struct device;
@@ -37,6 +40,7 @@ struct device_driver;
#ifdef CONFIG_DEVICE_TRUST
bool device_untrusted(struct device *dev);
+bool device_tcb_trusted(struct device *dev);
void module_driver_trust(struct module *mod, const char *val);
void module_driver_trust_init(struct module *mod, bool require_trust);
#else
diff --git a/drivers/base/trust.c b/drivers/base/trust.c
index 8efbe5c51250..21d374affbba 100644
--- a/drivers/base/trust.c
+++ b/drivers/base/trust.c
@@ -23,11 +23,18 @@ bool device_untrusted(struct device *dev)
return dev->bus_trust && dev->bus_trust <= DEVICE_TRUST_ADVERSARY;
}
+bool device_tcb_trusted(struct device *dev)
+{
+ return dev->p->trust >= DEVICE_TRUST_TCB;
+}
+
/* Driver trust policy requires modules, builtin drivers always attach */
static enum device_trust builtin_driver_trust(void)
{
if (IS_ENABLED(CONFIG_BUILTIN_DEVICE_TRUST_ADVERSARY))
return DEVICE_TRUST_ADVERSARY;
+ else if (IS_ENABLED(CONFIG_BUILTIN_DEVICE_TRUST_TCB))
+ return DEVICE_TRUST_TCB;
return DEVICE_TRUST_AUTO;
}
@@ -61,6 +68,7 @@ static const char * const device_trust_names[] = {
[DEVICE_TRUST_NONE] = "none",
[DEVICE_TRUST_ADVERSARY] = "adversary",
[DEVICE_TRUST_AUTO] = "auto",
+ [DEVICE_TRUST_TCB] = "tcb",
};
static enum device_trust device_trust_parse(const char *name)
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index f36778e62ac1..e6a4bc3ca9b0 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -19,6 +19,7 @@
#include <linux/kexec.h>
#include <linux/of_device.h>
#include <linux/acpi.h>
+#include <linux/pci-tsm.h>
#include <linux/dma-map-ops.h>
#include <linux/iommu.h>
#include "pci.h"
@@ -1668,10 +1669,11 @@ static int pci_bus_num_vf(struct device *dev)
static int pci_dma_configure(struct device *dev)
{
const struct device_driver *drv = READ_ONCE(dev->driver);
- struct device *bridge;
+ struct pci_dev *pdev = to_pci_dev(dev);
int ret = 0;
- bridge = pci_get_host_bridge_device(to_pci_dev(dev));
+ struct device *bridge __free(put_device) =
+ pci_get_host_bridge_device(pdev);
if (IS_ENABLED(CONFIG_OF) && bridge->parent &&
bridge->parent->of_node) {
@@ -1688,16 +1690,21 @@ static int pci_dma_configure(struct device *dev)
* the standard ACS capability but still support ACS via those
* quirks.
*/
- pci_enable_acs(to_pci_dev(dev));
-
- pci_put_host_bridge_device(bridge);
+ pci_enable_acs(pdev);
/* @drv may not be valid when we're called from the IOMMU layer */
- if (!ret && drv && !to_pci_driver(drv)->driver_managed_dma) {
+ if (ret || !drv)
+ return ret;
+
+ if (device_tcb_trusted(dev))
+ ret = pci_tsm_enable_dma(pdev);
+
+ if (!ret && !to_pci_driver(drv)->driver_managed_dma)
ret = iommu_device_use_default_domain(dev);
- if (ret)
- arch_teardown_dma_ops(dev);
- }
+
+ /* undo {of,acpi}_dma_configure() */
+ if (ret)
+ arch_teardown_dma_ops(dev);
return ret;
}
--
2.54.0
next prev parent reply other threads:[~2026-07-05 22:08 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-05 22:08 [PATCH 00/15] Device Evidence and Trust for PCI Security Protocol (TDISP) Dan Williams
2026-07-05 22:08 ` [PATCH 01/15] netlink: specs: Introduce multi-message blobs for SPDM Dan Williams
2026-07-05 22:08 ` [PATCH 02/15] tools: ynl: Teach pyynl to handle blobs Dan Williams
2026-07-05 22:08 ` [PATCH 03/15] tools: ynl: Teach ynl_gen_c to validate and dump 'blob' attributes Dan Williams
2026-07-05 22:08 ` [PATCH 04/15] device core: Introduce "device evidence" over netlink Dan Williams
2026-07-05 22:08 ` [PATCH 05/15] device core: Add "device evidence" 'validate' command Dan Williams
2026-07-05 22:08 ` [PATCH 06/15] PCI/TSM: Add device evidence support Dan Williams
2026-07-05 22:08 ` [PATCH 07/15] modules: Document the global async_probe parameter Dan Williams
2026-07-05 22:08 ` [PATCH 08/15] device core: Initial device trust infrastructure Dan Williams
2026-07-06 13:45 ` Jason Gunthorpe
2026-07-05 22:08 ` [PATCH 09/15] PCI, device core: Move "untrusted" concept to DEVICE_TRUST_ADVERSARY Dan Williams
2026-07-06 13:49 ` Jason Gunthorpe
2026-07-05 22:08 ` [PATCH 10/15] PCI/TSM: Add device interface security LOCKED support Dan Williams
2026-07-05 22:08 ` [PATCH 11/15] PCI/TSM: Add device interface security RUN support Dan Williams
2026-07-05 22:08 ` [PATCH 12/15] PCI/TSM: Add device interface security DMA enable/disable Dan Williams
2026-07-05 22:08 ` Dan Williams [this message]
2026-07-06 12:42 ` [PATCH 13/15] PCI, device core: Add private memory access for DEVICE_TRUST_TCB Aneesh Kumar K.V
2026-07-05 22:08 ` [PATCH 14/15] PCI/TSM: Create MMIO descriptors via TDISP Report Dan Williams
2026-07-05 22:08 ` [PATCH 15/15] PCI/TSM: Add relative MMIO offset support? Dan Williams
2026-07-06 12:51 ` [PATCH 00/15] Device Evidence and Trust for PCI Security Protocol (TDISP) Jason Gunthorpe
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=20260705220819.2472765-14-djbw@kernel.org \
--to=djbw@kernel.org \
--cc=ankita@nvidia.com \
--cc=bhelgaas@google.com \
--cc=dakr@kernel.org \
--cc=decui@microsoft.com \
--cc=driver-core@lists.linux.dev \
--cc=gregkh@linuxfoundation.org \
--cc=linux-coco@lists.linux.dev \
--cc=linux-pci@vger.kernel.org \
--cc=rafael@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