[RFC PATCH 18/21] RFC: pci: Add BUS_NOTIFY_PCI_BUS_MASTER event

Alexey Kardashevskiy
2024-08-23T13:32:47Z

TDISP allows secure MMIO access to a validated MMIO range.
The validation is done in the TSM and after that point changing
the device's Memory Space enable (MSE) or Bus Master enable (BME)
transitions the device into the error state.

For PCI device drivers which enable MSE, then BME, and then
start using the device, enabling BME is a logical point to perform
the MMIO range validation in the TSM.

Define new event for a bus. TSM is going to listen to it in the TVM
and do the validation for TEE ranges.

This does not switch MMIO to private by default though as this is
for the driver to decide (at least, for now).

Signed-off-by: Alexey Kardashevskiy <aik@amd.com>
---
include/linux/device/bus.h | 3 +++
drivers/pci/pci.c | 3 +++
drivers/virt/coco/tsm.c | 4 ++++
3 files changed, 10 insertions(+)

diff --git a/include/linux/device/bus.h b/include/linux/device/bus.h
index 807831d6bf0f..314349149cd3 100644
--- a/include/linux/device/bus.h
+++ b/include/linux/device/bus.h
@@ -269,8 +269,11 @@ enum bus_notifier_event {
BUS_NOTIFY_UNBIND_DRIVER,
BUS_NOTIFY_UNBOUND_DRIVER,
BUS_NOTIFY_DRIVER_NOT_BOUND,
+ BUS_NOTIFY_PCI_BUS_MASTER,
};

+void bus_notify(struct device *dev, enum bus_notifier_event value);
+
struct kset *bus_get_kset(const struct bus_type *bus);
struct device *bus_get_dev_root(const struct bus_type *bus);

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 15c0bb86ab01..b8bb322d1659 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -4271,6 +4271,9 @@ static void __pci_set_master(struct pci_dev *dev, bool enable)
pci_write_config_word(dev, PCI_COMMAND, cmd);
}
dev->is_busmaster = enable;
+
+ if (enable && dev->dev.tdi_enabled)
+ bus_notify(&dev->dev, BUS_NOTIFY_PCI_BUS_MASTER);
}

/**
diff --git a/drivers/virt/coco/tsm.c b/drivers/virt/coco/tsm.c
index e90455a0267f..b16b5d33c80f 100644
--- a/drivers/virt/coco/tsm.c
+++ b/drivers/virt/coco/tsm.c
@@ -1193,6 +1193,10 @@ static int tsm_pci_bus_notifier(struct notifier_block *nb, unsigned long action,
case BUS_NOTIFY_DEL_DEVICE:
tsm_dev_freeice(data);
break;
+ case BUS_NOTIFY_PCI_BUS_MASTER:
+ /* Validating before the driver or after the driver just does not work so don't! */
+ tsm_tdi_validate(tsm_tdi_get(data), false, tsm.private_data);
+ break;
case BUS_NOTIFY_UNBOUND_DRIVER:
tsm_tdi_validate(tsm_tdi_get(data), true, tsm.private_data);
break;
--
2.45.2