libvirt/Automatically-unbind-all-devices-driver-under-same-r.patch

152 lines
5.3 KiB
Diff
Raw Permalink Normal View History

From f81b9542f0d172c06cb38efb61b472786533ae3f Mon Sep 17 00:00:00 2001
From: yangxiangkai <yangxiangkai@huawei.com>
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