152 lines
5.3 KiB
Diff
152 lines
5.3 KiB
Diff
|
|
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
|
||
|
|
|