|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [RFC PATCH v4 5/6] libxl: Allow PCI device passthrough using -device Qemu command line
This change makes use of the new option 'hotplug' for host PCI devices
passthrough'd to the guest. If hotplug=0 is used in the pci device
configuration table, the device will be attached to the guest using the
Qemu command line as '-device xen-pci-passthrough,hostaddr=...'
The host device configuration is passed to the -device option as a json
array, just like it's done for hotplug using QMP. The json array is
created by using libxl__device_pci_get_qapi_json() introduced by the
previous patch.
Then, instead of sending the 'device_add' command, the device_add
callback is called to perform the 'query-pci' check to make sure the
passthrough'd device is present.
In the same way at shutdown, the device is not removed using QMP and
only the pci_remove_done() function is called.
As with QMP, the use of the 'hotplug=0' option honors the 'seize' option
by adding the PCI device to the assignable list if needed. This mimics
what is done in libxl__device_pci_add() with regards to seize option and
the assignable PCI device list. This allows to display a proper error
message if the device is not assignable before Qemu starts.
Signed-off-by: Thierry Escande <thierry.escande@xxxxxxxxxx>
---
Changes in v2:
- Add support for YAJL json parser
Changes in v3:
- Move code block for device command line parameters creation to a
correct place.
- Better handling of PCI device assignation check to display the correct
error message if the device is not assignable.
Changes in v4:
- Move function refactoring parts into their own patches
- Use libxl__json_object_to_json() that can now return plain json strings
---
tools/libs/light/libxl_dm.c | 33 +++++++++++++++++++++++++++++++++
tools/libs/light/libxl_pci.c | 13 ++++++++++++-
2 files changed, 45 insertions(+), 1 deletion(-)
diff --git a/tools/libs/light/libxl_dm.c b/tools/libs/light/libxl_dm.c
index 511ec76a65..fb0aeea640 100644
--- a/tools/libs/light/libxl_dm.c
+++ b/tools/libs/light/libxl_dm.c
@@ -1798,6 +1798,39 @@ static int libxl__build_device_model_args_new(libxl__gc
*gc,
break;
}
+ if (guest_config->num_pcidevs) {
+ libxl_device_pci *pci;
+ libxl__json_object *qmp_json;
+ char *json_str;
+
+ for (i = 0; i < guest_config->num_pcidevs; i++) {
+ pci = &guest_config->pcidevs[i];
+
+ if (pci->hotplug)
+ continue;
+
+ if (pci->seize && !libxl__pciback_dev_is_assigned(gc, pci)) {
+ rc = libxl__device_pci_assignable_add(gc, pci, 1);
+ if (rc)
+ return rc;
+ }
+
+ if (!libxl_device_pci_assignable(libxl__gc_owner(gc), pci)) {
+ LOGD(ERROR, guest_domid, "PCI device %x:%x:%x.%x is not
assignable",
+ pci->domain, pci->bus, pci->dev, pci->func);
+ return ERROR_FAIL;
+ }
+
+ qmp_json = libxl__device_pci_get_qapi_json(gc, pci);
+
+ json_str = libxl__json_object_to_json(gc, qmp_json, false);
+ if (!json_str)
+ return ERROR_NOMEM;
+
+ flexarray_vappend(dm_args, "-device", json_str, NULL);
+ }
+ }
+
if (state->dm_runas) {
if (qemu_opts->have_runwith_user) {
flexarray_append_pair(dm_args, "-run-with",
diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c
index 5004ca47d9..f5216f6b33 100644
--- a/tools/libs/light/libxl_pci.c
+++ b/tools/libs/light/libxl_pci.c
@@ -1148,7 +1148,10 @@ static void pci_add_qmp_device_add(libxl__egc *egc,
pci_add_state *pas)
qmp->domid = domid;
qmp->payload_fd = -1;
qmp->callback = pci_add_qmp_device_add_cb;
- rc = libxl__ev_qmp_send(egc, qmp, "device_add", args);
+ if (pci->hotplug)
+ rc = libxl__ev_qmp_send(egc, qmp, "device_add", args);
+ else
+ pci_add_qmp_device_add_cb(egc, qmp, NULL, 0);
if (rc) goto out;
return;
@@ -1830,6 +1833,14 @@ static void do_pci_remove(libxl__egc *egc,
pci_remove_state *prs)
libxl_domain_type type = libxl__domain_type(gc, domid);
libxl_device_pci *pci = &prs->pci;
int rc, num;
+
+ /* Passthrough'd device has been passed to Qemu command line so there is
+ * no need to remove it via QMP */
+ if (!pci->hotplug) {
+ pci_remove_done(egc, prs, 0);
+ return;
+ }
+
pcis = libxl_device_pci_list(ctx, domid, &num);
if (!pcis) {
rc = ERROR_FAIL;
--
2.53.0
--
Thierry Escande | Vates XCP-ng Developer
XCP-ng & Xen Orchestra - Vates solutions
web: https://vates.tech
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |