[PATCH 13/17] driver core: Preserve trust commitment beyond driver binding

From: Leon Romanovsky

Date: Thu Nov 05 2026 - 06:53:31 EST


From: Leon Romanovsky <leonro@xxxxxxxxxx>

IOMMU state can outlive a functional driver, including after failed setup
and unbind. The active trust level becomes disabled in those states, so
it cannot describe the authorization governing persistent translation
state. Infrastructure needs the immutable commitment to avoid treating
an unbound, previously authorized device as newly untrusted.

Signed-off-by: Leon Romanovsky <leonro@xxxxxxxxxx>
---
drivers/base/base.h | 2 --
drivers/base/trust.c | 17 +++++++++++++++--
include/linux/device.h | 3 +++
include/linux/device/trust.h | 1 +
4 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/drivers/base/base.h b/drivers/base/base.h
index b4441242496f7..dd78857abf74f 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -113,7 +113,6 @@ enum device_trust_state {
* dev_err_probe() for later retrieval via debugfs
* @device: pointer back to the struct device that this structure is
* associated with.
- * @trust_committed_level: operating level retained across bind transactions
* @trust_state: policy admission state
* @trust_initialized: bus and boot policy have initialized admission state
* @trust_policy_override: explicit policy prevents deferred driver boot policy
@@ -133,7 +132,6 @@ struct device_private {
const struct device_driver *async_driver;
char *deferred_probe_reason;
struct device *device;
- enum device_trust_level trust_committed_level;
enum device_trust_state trust_state;
u8 trust_initialized:1;
u8 trust_policy_override:1;
diff --git a/drivers/base/trust.c b/drivers/base/trust.c
index b38f69e440eae..4bcda888591a5 100644
--- a/drivers/base/trust.c
+++ b/drivers/base/trust.c
@@ -88,10 +88,10 @@ int device_trust_prepare(struct device *dev, const struct device_driver *drv)
if (level != DEVICE_TRUST_ADVERSARY && level != DEVICE_TRUST_FULL)
return -EINVAL;
if (dev->p->trust_state == DEVICE_TRUST_COMMITTED &&
- dev->p->trust_committed_level != level)
+ dev->trust_committed_level != level)
return -EINVAL;

- dev->p->trust_committed_level = level;
+ WRITE_ONCE(dev->trust_committed_level, level);
dev->p->trust_state = DEVICE_TRUST_COMMITTED;
WRITE_ONCE(dev->trust_level, level);
return 0;
@@ -119,6 +119,19 @@ enum device_trust_level device_get_trust_level(const struct device *dev)
}
EXPORT_SYMBOL_GPL(device_get_trust_level);

+/**
+ * device_get_committed_trust_level - Return the lifetime trust commitment
+ * @dev: device to inspect
+ *
+ * Return: %DEVICE_TRUST_DISABLED before admission, otherwise the level fixed
+ * before driver setup. The commitment survives setup failure and unbind.
+ */
+enum device_trust_level device_get_committed_trust_level(const struct device *dev)
+{
+ return READ_ONCE(dev->trust_committed_level);
+}
+EXPORT_SYMBOL_GPL(device_get_committed_trust_level);
+
/**
* device_is_adversarial - Test whether a device is operated as an adversary
* @dev: device to inspect
diff --git a/include/linux/device.h b/include/linux/device.h
index 5bd0cee874731..65ea07c9ac35b 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -699,6 +699,8 @@ enum struct_device_flags {
* @trust_policy: Requested operating policy, resolved before driver probe.
* @trust_level: Active trust level while a driver is bound, see
* device_get_trust_level().
+ * @trust_committed_level: Operating level retained across bind transactions,
+ * see device_get_committed_trust_level().
* @flags: DEV_FLAG_XXX flags. Use atomic bitfield operations to modify.
*
* At the lowest level, every device in a Linux system is represented by an
@@ -804,6 +806,7 @@ struct device {
enum device_removable removable;
enum device_trust_policy trust_policy;
enum device_trust_level trust_level;
+ enum device_trust_level trust_committed_level;

DECLARE_BITMAP(flags, DEV_FLAG_COUNT);
};
diff --git a/include/linux/device/trust.h b/include/linux/device/trust.h
index 552af3e73d4fc..19052e3301729 100644
--- a/include/linux/device/trust.h
+++ b/include/linux/device/trust.h
@@ -42,6 +42,7 @@ void device_trust_init(struct device *dev);
bool device_trust_may_claim(const struct device *dev,
const struct device_driver *drv);
enum device_trust_level device_get_trust_level(const struct device *dev);
+enum device_trust_level device_get_committed_trust_level(const struct device *dev);
bool device_is_adversarial(const struct device *dev);

#endif /* _DEVICE_TRUST_H_ */

--
2.56.0