From f81b9542f0d172c06cb38efb61b472786533ae3f Mon Sep 17 00:00:00 2001 From: yangxiangkai Date: Wed, 4 Sep 2024 03:43:09 +0000 Subject: [PATCH] Automatically unbind all devices' driver under same root port and bind to vfio-pci in the context of CVM. --- src/hypervisor/virhostdev.c | 5 ++++ src/hypervisor/virhostdev.h | 1 + src/qemu/qemu_process.c | 3 +++ src/util/virpci.c | 53 +++++++++++++++++++++++++++++++++++++ src/util/virpci.h | 3 +++ 5 files changed, 65 insertions(+) diff --git a/src/hypervisor/virhostdev.c b/src/hypervisor/virhostdev.c index 4672bd8785..43493fc64a 100644 --- a/src/hypervisor/virhostdev.c +++ b/src/hypervisor/virhostdev.c @@ -707,6 +707,8 @@ virHostdevPreparePCIDevicesImpl(virHostdevManager *mgr, * shared across guests. Check if that's the case. */ if (usesVFIO) { data.usesVFIO = true; + if (flags & VIR_HOSTDEV_SP_SECURE) + virtccaVirPCIDeviceSetSecure(pci, true); if (virPCIDeviceAddressIOMMUGroupIterate(devAddr, virHostdevIsPCINodeDeviceUsed, &data) < 0) @@ -735,6 +737,9 @@ virHostdevPreparePCIDevicesImpl(virHostdevManager *mgr, * actual device going forward */ VIR_DEBUG("Detaching managed PCI device %s", virPCIDeviceGetName(pci)); + if (virtccaVirPCIDeviceGetSecure(pci)) + virtccaVirPCIDeviceDetach(pci); + if (virPCIDeviceDetach(pci, mgr->activePCIHostdevs, mgr->inactivePCIHostdevs) < 0) diff --git a/src/hypervisor/virhostdev.h b/src/hypervisor/virhostdev.h index 642d753ffb..6150d327aa 100644 --- a/src/hypervisor/virhostdev.h +++ b/src/hypervisor/virhostdev.h @@ -38,6 +38,7 @@ typedef enum { VIR_HOSTDEV_SP_PCI = (1 << 8), /* support pci passthrough */ VIR_HOSTDEV_SP_USB = (1 << 9), /* support usb passthrough */ VIR_HOSTDEV_SP_SCSI = (1 << 10), /* support scsi passthrough */ + VIR_HOSTDEV_SP_SECURE = (1 << 11), /* support secure dev passthrough */ } virHostdevFlag; diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 7ba5575037..892676c020 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -7507,6 +7507,9 @@ qemuProcessPrepareHost(virQEMUDriver *driver, hostdev_flags |= VIR_HOSTDEV_STRICT_ACS_CHECK; if (flags & VIR_QEMU_PROCESS_START_NEW) hostdev_flags |= VIR_HOSTDEV_COLD_BOOT; + if (vm->def->sec && vm->def->sec->sectype == VIR_DOMAIN_LAUNCH_SECURITY_CVM) { + hostdev_flags |= VIR_HOSTDEV_SP_SECURE; + } if (qemuHostdevPrepareDomainDevices(driver, vm->def, hostdev_flags) < 0) return -1; diff --git a/src/util/virpci.c b/src/util/virpci.c index baacde4c14..c5ae10956f 100644 --- a/src/util/virpci.c +++ b/src/util/virpci.c @@ -94,6 +94,9 @@ struct _virPCIDevice { bool unbind_from_stub; bool remove_slot; bool reprobe; + + /* used by virtcca CoDA feature*/ + bool secure; }; struct _virPCIDeviceList { @@ -1377,6 +1380,56 @@ virPCIDeviceDetach(virPCIDevice *dev, return 0; } +int +virtccaVirPCIDeviceDetach(virPCIDevice *_dev) +{ + int ret = 0; + virPCIDevice *dev = NULL; + size_t i, j; + + /* Given bus number, there are 32 devices and 8 functions */ + for (i = 0; i < 32; i++) { + for (j = 0; j < 8; j++) { + virPCIDeviceAddress devAddr = {.domain = _dev->address.domain, + .bus = _dev->address.bus, + .slot = i, .function = j}; + g_autofree char *name = virPCIDeviceAddressAsString(&devAddr); + g_autofree char *path = g_strdup_printf(PCI_SYSFS "devices/%s/config", name); + + if (!virFileExists(path)) + continue; + + if (!(dev = virPCIDeviceNew(&devAddr))) + continue; + + virPCIDeviceSetStubDriverType(dev, VIR_PCI_STUB_DRIVER_VFIO); + + if (virPCIDeviceBindToStub(dev) < 0) { + ret = -1; + goto cleanup; + } + virPCIDeviceFree(dev); + } + } + return ret; + +cleanup: + virPCIDeviceFree(dev); + return ret; +} + +bool +virtccaVirPCIDeviceGetSecure(virPCIDevice *dev) +{ + return dev->secure; +} + +void +virtccaVirPCIDeviceSetSecure(virPCIDevice *dev, bool secure) +{ + dev->secure = secure; +} + /* * Pre-condition: inactivePCIHostdevs & activePCIHostdevs * are locked diff --git a/src/util/virpci.h b/src/util/virpci.h index faca6cf6f9..7cc754f4af 100644 --- a/src/util/virpci.h +++ b/src/util/virpci.h @@ -302,6 +302,9 @@ void virPCIEDeviceInfoFree(virPCIEDeviceInfo *dev); void virPCIDeviceAddressFree(virPCIDeviceAddress *address); +int virtccaVirPCIDeviceDetach(virPCIDevice *dev); +bool virtccaVirPCIDeviceGetSecure(virPCIDevice *dev); +void virtccaVirPCIDeviceSetSecure(virPCIDevice *dev, bool secure); G_DEFINE_AUTOPTR_CLEANUP_FUNC(virPCIDevice, virPCIDeviceFree); G_DEFINE_AUTOPTR_CLEANUP_FUNC(virPCIDeviceAddress, virPCIDeviceAddressFree); G_DEFINE_AUTOPTR_CLEANUP_FUNC(virPCIEDeviceInfo, virPCIEDeviceInfoFree); -- 2.41.0.windows.1