Hi Robin,
On Wed, Mar 16, 2022 at 07:17:57PM +0000, Robin Murphy wrote:
The feeling I'm getting from all this is that if we've got as far as
iommu_dma_protection_show() then it's really too late to meaningfully
mitigate bad firmware.
Note, these are requirements from Microsoft in order for the system to
use the "Kernel DMA protection". Because of this, likelyhood of "bad
firmware" should be quite low since these systems ship with Windows
installed so they should get at least some soft of validation that this
actually works.
We should be able to detect missing
untrusted/external-facing properties as early as nhi_probe(), and if we
could go into "continue at your own risk" mode right then *before* anything
else happens, it all becomes a lot easier to reason about.
I think what we want is that the DMAR opt-in bit is set in the ACPI
tables and that we know the full IOMMU translation is happening for the
devices behind "external facing ports". If that's not the case the
iommu_dma_protection_show() should return 0 meaning the userspace can
ask the user whether the connected device is allowed to use DMA (e.g
PCIe is tunneled or not).
We do check for the DMAR bit in the Intel IOMMU code and we also do
check that there actually are PCIe ports marked external facing but we
could issue warning there if that's not the case. Similarly if the user
explicitly disabled the IOMMU translation. This can be done inside a new
IOMMU API that does something like the below pseudo-code:
#if IOMMU_ENABLED
bool iommu_dma_protected(struct device *dev)
{
if (dmar_platform_optin() /* or the AMD equivalent */) {
if (!iommu_present(...)) /* whatever is needed to check that the full translation is enabled */
dev_warn(dev, "IOMMU protection disabled!");
/*
* Look for the external facing ports. Should be at
* least 1 or issue warning.
*/
...
return true;
}
return false;
}
#else
static inline bool iommu_dma_protected(struct device *dev)
{
return false;
}
#endif
Then we can make iommu_dma_protection_show() to call this function.