qemu: build vhost-user GPU devices

For each vhost-user GPUs,
- build a socket chardev, and pass the vhost-user socket to it
- build a vhost-user video device and associate it with the chardev

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Cole Robinson <crobinso@redhat.com>
This commit is contained in:
Marc-André Lureau 2019-09-23 14:44:42 +04:00 committed by Cole Robinson
parent dc7de8b963
commit e2b709f92e
2 changed files with 52 additions and 8 deletions

View File

@ -4513,16 +4513,23 @@ qemuBuildDeviceVideoStr(const virDomainDef *def,
virQEMUCapsPtr qemuCaps)
{
VIR_AUTOCLEAN(virBuffer) buf = VIR_BUFFER_INITIALIZER;
const char *model;
const char *model = NULL;
/* We try to chose the best model for primary video device by preferring
* model with VGA compatibility mode. For some video devices on some
* architectures there might not be such model so fallback to one
* without VGA compatibility mode. */
if (video->primary && qemuDomainSupportsVideoVga(video, qemuCaps))
model = qemuDeviceVideoTypeToString(video->type);
else
model = qemuDeviceVideoSecondaryTypeToString(video->type);
if (video->backend == VIR_DOMAIN_VIDEO_BACKEND_TYPE_VHOSTUSER) {
if (video->primary && qemuDomainSupportsVideoVga(video, qemuCaps))
model = "vhost-user-vga";
else
model = "vhost-user-gpu";
} else {
if (video->primary && qemuDomainSupportsVideoVga(video, qemuCaps))
model = qemuDeviceVideoTypeToString(video->type);
else
model = qemuDeviceVideoSecondaryTypeToString(video->type);
}
if (!model || STREQ(model, "")) {
virReportError(VIR_ERR_INTERNAL_ERROR,
@ -4531,8 +4538,8 @@ qemuBuildDeviceVideoStr(const virDomainDef *def,
return NULL;
}
if (STREQ(model, "virtio-gpu")) {
if (qemuBuildVirtioDevStr(&buf, "virtio-gpu", qemuCaps,
if (STREQ(model, "virtio-gpu") || STREQ(model, "vhost-user-gpu")) {
if (qemuBuildVirtioDevStr(&buf, model, qemuCaps,
VIR_DOMAIN_DEVICE_VIDEO, video) < 0) {
return NULL;
}
@ -4575,6 +4582,10 @@ qemuBuildDeviceVideoStr(const virDomainDef *def,
if (video->heads)
virBufferAsprintf(&buf, ",max_outputs=%u", video->heads);
}
} else if (video->backend == VIR_DOMAIN_VIDEO_BACKEND_TYPE_VHOSTUSER) {
if (video->heads)
virBufferAsprintf(&buf, ",max_outputs=%u", video->heads);
virBufferAsprintf(&buf, ",chardev=chr-vu-%s", video->info.alias);
} else if (video->type == VIR_DOMAIN_VIDEO_TYPE_VIRTIO) {
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_GPU_MAX_OUTPUTS)) {
if (video->heads)
@ -4686,6 +4697,23 @@ qemuBuildVgaVideoCommand(virCommandPtr cmd,
}
static char *
qemuBuildVhostUserChardevStr(const char *alias,
int *fd,
virCommandPtr cmd)
{
char *chardev = NULL;
if (virAsprintf(&chardev, "socket,id=chr-vu-%s,fd=%d", alias, *fd) < 0)
return NULL;
virCommandPassFD(cmd, *fd, VIR_COMMAND_PASS_FD_CLOSE_PARENT);
*fd = -1;
return chardev;
}
static int
qemuBuildVideoCommandLine(virCommandPtr cmd,
const virDomainDef *def,
@ -4693,6 +4721,20 @@ qemuBuildVideoCommandLine(virCommandPtr cmd,
{
size_t i;
for (i = 0; i < def->nvideos; i++) {
VIR_AUTOFREE(char *) chardev = NULL;
virDomainVideoDefPtr video = def->videos[i];
if (video->backend == VIR_DOMAIN_VIDEO_BACKEND_TYPE_VHOSTUSER) {
if (!(chardev = qemuBuildVhostUserChardevStr(video->info.alias,
&QEMU_DOMAIN_VIDEO_PRIVATE(video)->vhost_user_fd,
cmd)))
return -1;
virCommandAddArgList(cmd, "-chardev", chardev, NULL);
}
}
for (i = 0; i < def->nvideos; i++) {
VIR_AUTOFREE(char *) str = NULL;
virDomainVideoDefPtr video = def->videos[i];

View File

@ -49,7 +49,9 @@ ats=on \
ats=on \
-device virtio-input-host-pci,id=input3,evdev=/dev/input/event1234,bus=pci.0,\
addr=0x12,iommu_platform=on,ats=on \
-device virtio-gpu-pci,id=video0,bus=pci.0,addr=0x2,iommu_platform=on,ats=on \
-chardev socket,id=chr-vu-video0,fd=0 \
-device vhost-user-gpu-pci,id=video0,max_outputs=1,chardev=chr-vu-video0,\
bus=pci.0,addr=0x2,iommu_platform=on,ats=on \
-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0xc,iommu_platform=on,\
ats=on \
-object rng-random,id=objrng0,filename=/dev/random \