On Tue, Aug 26, 2025 at 08:52:55PM -0700, Dan Williams wrote: > --- a/drivers/base/base.h > +++ b/drivers/base/base.h > @@ -98,6 +98,8 @@ struct driver_private { > * the device; typically because it depends on another driver getting > * probed first. > * @async_driver - pointer to device driver awaiting probe via async_probe > + * @cc_accepted - track the TEE acceptance state of the device for deferred > + * probing, MMIO mapping type, and SWIOTLB bypass for private memory DMA. > * @device - pointer back to the struct device that this structure is > * associated with. > * @dead - This device is currently either in the process of or has been > @@ -115,6 +117,9 @@ struct device_private { > struct list_head deferred_probe; > const struct device_driver *async_driver; > char *deferred_probe_reason; > +#ifdef CONFIG_CONFIDENTIAL_DEVICES > + bool cc_accepted; > +#endif > struct device *device; > u8 dead:1; Why did you not just use another u8:1 at the end? You kind of added a big hole in the structure that is created for every device :( > }; > diff --git a/drivers/base/coco.c b/drivers/base/coco.c > new file mode 100644 > index 000000000000..97c22d0e9247 > --- /dev/null > +++ b/drivers/base/coco.c > @@ -0,0 +1,96 @@ > +// SPDX-License-Identifier: GPL-2.0 No copyright at the top? Bold :) > +#include <linux/device.h> > +#include <linux/dev_printk.h> > +#include <linux/lockdep.h> > +#include "base.h" > + > +/* > + * Confidential devices implement encrypted + integrity protected MMIO and have > + * the ability to issue DMA to encrypted + integrity protected System RAM. The > + * device_cc_*() helpers aid buses in setting the acceptance state, drivers in > + * preparing and probing the acceptance state, and other kernel subsystem in > + * augmenting behavior in the presence of accepted devices (e.g. > + * ioremap_encrypted()). > + */ > + > +/** > + * device_cc_accept(): Mark a device as accepted for TEE operation What does TEE mean here? I feel you mix "confidential" and TEE a bunch. > + * @dev: device to accept > + * > + * Confidential bus drivers use this helper to accept devices at initial > + * enumeration, or dynamically one attestation has been performed. > + * > + * Given that moving a device into confidential / private operation implicates > + * any of MMIO mapping attributes, physical address, and IOMMU mappings this > + * transition must be done while the device is idle (driver detached). > + * > + * This is an internal helper for buses not device drivers. > + */ > +int device_cc_accept(struct device *dev) > +{ > + lockdep_assert_held(&dev->mutex); > + > + if (dev->driver) > + return -EBUSY; > + dev->p->cc_accepted = true; > + > + return 0; > +} > + > +int device_cc_reject(struct device *dev) > +{ > + lockdep_assert_held(&dev->mutex); > + > + if (dev->driver) > + return -EBUSY; > + dev->p->cc_accepted = false; > + > + return 0; > +} > + > +/** > + * device_cc_accepted(): Get the TEE operational state of a device > + * @dev: device to check > + * > + * Various subsystems, mm/ioremap, drivers/iommu, drivers/vfio, kernel/dma... > + * need to augment their behavior in the presence of confidential devices. This > + * simple, deliberately not exported, helper is for those built-in consumers. > + * > + * This is an internal helper for subsystems not device drivers. > + */ > +bool device_cc_accepted(struct device *dev) > +{ > + return dev->p->cc_accepted; > +} > + > +/** > + * device_cc_probe(): Coordinate dynamic acceptance with a device driver > + * @dev: device to defer probing while acceptance pending > + * > + * Dynamically accepted devices may need a driver to perform initial > + * configuration to get the device into a state where it can be accepted. Use > + * this helper to exit driver probe at that partial device-init point and log > + * this TEE acceptance specific deferral reason. > + * > + * This is an exported helper for device drivers that need to coordinate device > + * configuration state and acceptance. > + */ > +int device_cc_probe(struct device *dev) > +{ > + /* > + * See work_on_cpu() in local_pci_probe() for one reason why > + * lockdep_assert_held() can not be used here. > + */ > + WARN_ON_ONCE(!mutex_is_locked(&dev->mutex)); If not locked you just keep going? Why not return an error? thanks, greg k-h