conf: add XML for input device passthrough

Add xml for the new virtio-input-host-pci device:
<input type='passthrough' bus='virtio'>
  <source evdev='/dev/input/event1234'/>
</input>

https://bugzilla.redhat.com/show_bug.cgi?id=1231114
This commit is contained in:
Ján Tomko 2015-11-16 09:36:12 +01:00
parent e9d7550ac2
commit 1a538a07c7
7 changed files with 98 additions and 22 deletions

View File

@ -4804,14 +4804,18 @@ qemu-kvm -net nic,model=? /dev/null
&lt;input type='mouse' bus='virtio'/&gt; &lt;input type='mouse' bus='virtio'/&gt;
&lt;input type='keyboard' bus='virtio'/&gt; &lt;input type='keyboard' bus='virtio'/&gt;
&lt;input type='tablet' bus='virtio'/&gt; &lt;input type='tablet' bus='virtio'/&gt;
&lt;input type='passthrough' bus='virtio'&gt;
&lt;source evdev='/dev/input/event1/&gt;
&lt;/input&gt;
&lt;/devices&gt; &lt;/devices&gt;
...</pre> ...</pre>
<dl> <dl>
<dt><code>input</code></dt> <dt><code>input</code></dt>
<dd>The <code>input</code> element has one mandatory attribute, <dd>The <code>input</code> element has one mandatory attribute,
the <code>type</code> whose value can be 'mouse', 'tablet' or the <code>type</code> whose value can be 'mouse', 'tablet',
(<span class="since">since 1.2.2</span>) 'keyboard'. (<span class="since">since 1.2.2</span>) 'keyboard' or
(<span class="since">since 1.3.0</span>) 'passthrough'.
The tablet provides absolute cursor movement, The tablet provides absolute cursor movement,
while the mouse uses relative movement. The optional while the mouse uses relative movement. The optional
<code>bus</code> attribute can be used to refine the exact device type. <code>bus</code> attribute can be used to refine the exact device type.
@ -4824,6 +4828,10 @@ qemu-kvm -net nic,model=? /dev/null
sub-element <code>&lt;address&gt;</code> which can tie the sub-element <code>&lt;address&gt;</code> which can tie the
device to a particular PCI device to a particular PCI
slot, <a href="#elementsAddress">documented above</a>. slot, <a href="#elementsAddress">documented above</a>.
For type <code>passthrough</code>, the mandatory sub-element <code>source</code>
must have an <code>evdev</code> attribute containing the absolute path to the
event device passed through to guests. (KVM only)
</p> </p>
<h4><a name="elementsHub">Hub devices</a></h4> <h4><a name="elementsHub">Hub devices</a></h4>

View File

@ -3579,23 +3579,40 @@
<define name="input"> <define name="input">
<element name="input"> <element name="input">
<attribute name="type"> <choice>
<choice> <group>
<value>tablet</value> <attribute name="type">
<value>mouse</value> <choice>
<value>keyboard</value> <value>tablet</value>
</choice> <value>mouse</value>
</attribute> <value>keyboard</value>
<optional> </choice>
<attribute name="bus"> </attribute>
<choice> <optional>
<value>ps2</value> <attribute name="bus">
<value>usb</value> <choice>
<value>xen</value> <value>ps2</value>
<value>usb</value>
<value>xen</value>
<value>virtio</value>
</choice>
</attribute>
</optional>
</group>
<group>
<attribute name="type">
<value>passthrough</value>
</attribute>
<attribute name="bus">
<value>virtio</value> <value>virtio</value>
</choice> </attribute>
</attribute> <element name="source">
</optional> <attribute name="evdev">
<ref name="absFilePath"/>
</attribute>
</element>
</group>
</choice>
<optional> <optional>
<ref name="alias"/> <ref name="alias"/>
</optional> </optional>

View File

@ -544,7 +544,8 @@ VIR_ENUM_IMPL(virDomainVideo, VIR_DOMAIN_VIDEO_TYPE_LAST,
VIR_ENUM_IMPL(virDomainInput, VIR_DOMAIN_INPUT_TYPE_LAST, VIR_ENUM_IMPL(virDomainInput, VIR_DOMAIN_INPUT_TYPE_LAST,
"mouse", "mouse",
"tablet", "tablet",
"keyboard") "keyboard",
"passthrough")
VIR_ENUM_IMPL(virDomainInputBus, VIR_DOMAIN_INPUT_BUS_LAST, VIR_ENUM_IMPL(virDomainInputBus, VIR_DOMAIN_INPUT_BUS_LAST,
"ps2", "ps2",
@ -1416,6 +1417,7 @@ void virDomainInputDefFree(virDomainInputDefPtr def)
return; return;
virDomainDeviceInfoClear(&def->info); virDomainDeviceInfoClear(&def->info);
VIR_FREE(def->source.evdev);
VIR_FREE(def); VIR_FREE(def);
} }
@ -10262,15 +10264,20 @@ virDomainPanicDefParseXML(xmlNodePtr node)
static virDomainInputDefPtr static virDomainInputDefPtr
virDomainInputDefParseXML(const virDomainDef *dom, virDomainInputDefParseXML(const virDomainDef *dom,
xmlNodePtr node, xmlNodePtr node,
xmlXPathContextPtr ctxt,
unsigned int flags) unsigned int flags)
{ {
xmlNodePtr save = ctxt->node;
virDomainInputDefPtr def; virDomainInputDefPtr def;
char *evdev = NULL;
char *type = NULL; char *type = NULL;
char *bus = NULL; char *bus = NULL;
if (VIR_ALLOC(def) < 0) if (VIR_ALLOC(def) < 0)
return NULL; return NULL;
ctxt->node = node;
type = virXMLPropString(node, "type"); type = virXMLPropString(node, "type");
bus = virXMLPropString(node, "bus"); bus = virXMLPropString(node, "bus");
@ -10377,10 +10384,20 @@ virDomainInputDefParseXML(const virDomainDef *dom,
goto error; goto error;
} }
if ((evdev = virXPathString("string(./source/@evdev)", ctxt)))
def->source.evdev = virFileSanitizePath(evdev);
if (def->type == VIR_DOMAIN_INPUT_TYPE_PASSTHROUGH && !def->source.evdev) {
virReportError(VIR_ERR_XML_ERROR, "%s",
_("Missing evdev path for input device passthrough"));
goto error;
}
cleanup: cleanup:
VIR_FREE(evdev);
VIR_FREE(type); VIR_FREE(type);
VIR_FREE(bus); VIR_FREE(bus);
ctxt->node = save;
return def; return def;
error: error:
@ -12737,8 +12754,8 @@ virDomainDeviceDefParse(const char *xmlStr,
goto error; goto error;
break; break;
case VIR_DOMAIN_DEVICE_INPUT: case VIR_DOMAIN_DEVICE_INPUT:
if (!(dev->data.input = virDomainInputDefParseXML(def, if (!(dev->data.input = virDomainInputDefParseXML(def, node,
node, flags))) ctxt, flags)))
goto error; goto error;
break; break;
case VIR_DOMAIN_DEVICE_SOUND: case VIR_DOMAIN_DEVICE_SOUND:
@ -16115,6 +16132,7 @@ virDomainDefParseXML(xmlDocPtr xml,
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
virDomainInputDefPtr input = virDomainInputDefParseXML(def, virDomainInputDefPtr input = virDomainInputDefParseXML(def,
nodes[i], nodes[i],
ctxt,
flags); flags);
if (!input) if (!input)
goto error; goto error;
@ -20961,9 +20979,11 @@ virDomainInputDefFormat(virBufferPtr buf,
virBufferAsprintf(buf, "<input type='%s' bus='%s'", virBufferAsprintf(buf, "<input type='%s' bus='%s'",
type, bus); type, bus);
if (virDomainDeviceInfoNeedsFormat(&def->info, flags)) { if (virDomainDeviceInfoNeedsFormat(&def->info, flags) ||
def->type == VIR_DOMAIN_INPUT_TYPE_PASSTHROUGH) {
virBufferAddLit(buf, ">\n"); virBufferAddLit(buf, ">\n");
virBufferAdjustIndent(buf, 2); virBufferAdjustIndent(buf, 2);
virBufferEscapeString(buf, "<source evdev='%s'/>\n", def->source.evdev);
if (virDomainDeviceInfoFormat(buf, &def->info, flags) < 0) if (virDomainDeviceInfoFormat(buf, &def->info, flags) < 0)
return -1; return -1;
virBufferAdjustIndent(buf, -2); virBufferAdjustIndent(buf, -2);

View File

@ -1288,6 +1288,7 @@ typedef enum {
VIR_DOMAIN_INPUT_TYPE_MOUSE, VIR_DOMAIN_INPUT_TYPE_MOUSE,
VIR_DOMAIN_INPUT_TYPE_TABLET, VIR_DOMAIN_INPUT_TYPE_TABLET,
VIR_DOMAIN_INPUT_TYPE_KBD, VIR_DOMAIN_INPUT_TYPE_KBD,
VIR_DOMAIN_INPUT_TYPE_PASSTHROUGH,
VIR_DOMAIN_INPUT_TYPE_LAST VIR_DOMAIN_INPUT_TYPE_LAST
} virDomainInputType; } virDomainInputType;
@ -1305,6 +1306,9 @@ typedef enum {
struct _virDomainInputDef { struct _virDomainInputDef {
int type; int type;
int bus; int bus;
struct {
char *evdev;
} source;
virDomainDeviceInfo info; virDomainDeviceInfo info;
}; };

View File

@ -5777,6 +5777,8 @@ qemuBuildVirtioInputDevStr(virDomainDefPtr def,
} }
virBufferAsprintf(&buf, "virtio-keyboard%s,id=%s", suffix, dev->info.alias); virBufferAsprintf(&buf, "virtio-keyboard%s,id=%s", suffix, dev->info.alias);
break; break;
case VIR_DOMAIN_INPUT_TYPE_PASSTHROUGH:
/* TBD */
case VIR_DOMAIN_INPUT_TYPE_LAST: case VIR_DOMAIN_INPUT_TYPE_LAST:
break; break;
} }

View File

@ -0,0 +1,24 @@
<domain type='qemu'>
<name>QEMUGuest1</name>
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
<memory unit='KiB'>219100</memory>
<currentMemory unit='KiB'>219100</currentMemory>
<vcpu placement='static'>1</vcpu>
<os>
<type arch='i686' machine='pc'>hvm</type>
<boot dev='hd'/>
</os>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<emulator>/usr/bin/qemu</emulator>
<controller type='usb' index='0'/>
<controller type='pci' index='0' model='pci-root'/>
<input type='passthrough' bus='virtio'>
<source evdev='/dev/input/event1234'/>
</input>
<memballoon model='virtio'/>
</devices>
</domain>

View File

@ -633,6 +633,7 @@ mymain(void)
DO_TEST("video-virtio-gpu-device"); DO_TEST("video-virtio-gpu-device");
DO_TEST("video-virtio-gpu-virgl"); DO_TEST("video-virtio-gpu-virgl");
DO_TEST("virtio-input"); DO_TEST("virtio-input");
DO_TEST("virtio-input-passthrough");
qemuTestDriverFree(&driver); qemuTestDriverFree(&driver);