* Alex Williamson (alex.williamson(a)redhat.com) wrote:
@@ -1378,6 +1420,9 @@ int qemudExtractVersionInfo(const char *qemu,
&version, &is_kvm, &kvm_version) == -1)
goto cleanup2;
+ if (flags & QEMUD_CMD_FLAG_DEVICE)
+ qemudParsePCIDeviceStrs(qemu, &flags);
+
looks like this is called early enough for both cmdline and monitor
interface
if (retversion)
*retversion = version;
if (retflags)
@@ -2887,8 +2932,29 @@ error:
}
+int
+qemudOpenPCIConfig(virDomainHostdevDefPtr dev)
+{
+ char *path = NULL;
+ int configfd = -1;
+
+ /* XXX don't hard code segment */
You don't need to, just...
+ if (virAsprintf(&path,
"/sys/bus/pci/devices/0000:%02x:%02x.%01x/config",
/
s/0000/%04x/ --------------------------------------
+ dev->source.subsys.u.pci.bus,
dev->source.subsys.u.pci.slot,
and add dev->source.subsys.u.pci.domain
+ dev->source.subsys.u.pci.function) < 0) {
+ virReportOOMError();
+ return -1;
+ }
+
+ configfd = open(path, O_RDWR, 0);
Should probably report an open failure to aid debugging.
+ VIR_FREE(path);
+
+ return configfd;
+}
+
char *
-qemuBuildPCIHostdevDevStr(virDomainHostdevDefPtr dev)
+qemuBuildPCIHostdevDevStr(virDomainHostdevDefPtr dev, int configfd)
{
virBuffer buf = VIR_BUFFER_INITIALIZER;
@@ -2898,6 +2964,8 @@ qemuBuildPCIHostdevDevStr(virDomainHostdevDefPtr dev)
dev->source.subsys.u.pci.slot,
dev->source.subsys.u.pci.function);
virBufferVSprintf(&buf, ",id=%s", dev->info.alias);
+ if (configfd >= 0)
+ virBufferVSprintf(&buf, ",configfd=%d", configfd);
if (qemuBuildDeviceAddressStr(&buf, &dev->info) < 0)
goto error;
@@ -4600,8 +4668,21 @@ int qemudBuildCommandLine(virConnectPtr conn,
if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) {
+ int configfd = -1;
+ if (qemuCmdFlags & QEMUD_CMD_FLAG_PCI_CONFIGFD) {
+ configfd = qemudOpenPCIConfig(hostdev);
+
+ if (configfd >= 0) {
+ if (VIR_REALLOC_N(*vmfds, (*nvmfds)+1) < 0) {
+ close(configfd);
+ goto no_memory;
+ }
+
+ (*vmfds)[(*nvmfds)++] = configfd;
+ }
+ }
ADD_ARG_LIT("-device");
- if (!(devstr = qemuBuildPCIHostdevDevStr(hostdev)))
+ if (!(devstr = qemuBuildPCIHostdevDevStr(hostdev, configfd)))
goto error;
ADD_ARG(devstr);
} else if (qemuCmdFlags & QEMUD_CMD_FLAG_PCIDEVICE) {
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index a101e47..64fab60 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -88,6 +88,7 @@ enum qemud_cmd_flags {
QEMUD_CMD_FLAG_NO_HPET = (1LL << 33), /* -no-hpet flag is supported */
QEMUD_CMD_FLAG_NO_KVM_PIT = (1LL << 34), /* -no-kvm-pit-reinjection
supported */
QEMUD_CMD_FLAG_TDF = (1LL << 35), /* -tdf flag (user-mode pit
catchup) */
+ QEMUD_CMD_FLAG_PCI_CONFIGFD = (1LL << 36), /* pci-assign.configfd */
};
/* Main driver state */
@@ -190,6 +191,9 @@ int qemudParseHelpStr (const char *qemu,
unsigned int *is_kvm,
unsigned int *kvm_version);
+void qemudParsePCIDeviceStrs (const char *qemu,
+ unsigned long long *qemuCmdFlags);
+
int qemudBuildCommandLine (virConnectPtr conn,
struct qemud_driver *driver,
virDomainDefPtr def,
@@ -242,7 +246,9 @@ char * qemuBuildSoundDevStr(virDomainSoundDefPtr sound);
/* Legacy, pre device support */
char * qemuBuildPCIHostdevPCIDevStr(virDomainHostdevDefPtr dev);
/* Current, best practice */
-char * qemuBuildPCIHostdevDevStr(virDomainHostdevDefPtr dev);
+char * qemuBuildPCIHostdevDevStr(virDomainHostdevDefPtr dev, int configfd);
+
+int qemudOpenPCIConfig(virDomainHostdevDefPtr dev);
/* Current, best practice */
char * qemuBuildChrChardevStr(virDomainChrDefPtr dev);
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index dd5bd24..219a973 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -7567,7 +7567,7 @@ static int qemudDomainAttachHostPciDevice(struct qemud_driver
*driver,
if (qemuDomainPCIAddressEnsureAddr(priv->pciaddrs, &hostdev->info)
< 0)
goto error;
- if (!(devstr = qemuBuildPCIHostdevDevStr(hostdev)))
+ if (!(devstr = qemuBuildPCIHostdevDevStr(hostdev, -1)))
Looks like this is dynamically assigning host PCI device to running guest,
we should still be able to pass fd here. That will complicate the qemu
side to be able to accept the fd.
thanks,
-chris