[PATCH] qemu: fix qemu command for pci hostdevs and ramfb='off'

2024-05-16 Thread Jonathon Jongsma
There was no test for this and we mistakenly used 'B' rather than 'T'
when constructing the json value for this parameter. Thus, a value of
'off' was VIR_TRISTATE_SWITCH_OFF=2, which was translated to a boolean
value of 'true'.

Signed-off-by: Jonathon Jongsma 
---
 src/qemu/qemu_command.c | 2 +-
 .../hostdev-pci-display-ramfb.x86_64-latest.args| 1 +
 .../hostdev-pci-display-ramfb.x86_64-latest.xml | 6 ++
 tests/qemuxmlconfdata/hostdev-pci-display-ramfb.xml | 5 +
 4 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 63bfeb790e..2d0eddc79e 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -4798,7 +4798,7 @@ qemuBuildPCIHostdevDevProps(const virDomainDef *def,
   "p:bootindex", dev->info->effectiveBootIndex,
   "S:failover_pair_id", failover_pair_id,
   "S:display", qemuOnOffAuto(pcisrc->display),
-  "B:ramfb", pcisrc->ramfb,
+  "T:ramfb", pcisrc->ramfb,
   NULL) < 0)
 return NULL;
 
diff --git a/tests/qemuxmlconfdata/hostdev-pci-display-ramfb.x86_64-latest.args 
b/tests/qemuxmlconfdata/hostdev-pci-display-ramfb.x86_64-latest.args
index 6a3bfbe6fb..e6e538ef1c 100644
--- a/tests/qemuxmlconfdata/hostdev-pci-display-ramfb.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/hostdev-pci-display-ramfb.x86_64-latest.args
@@ -29,5 +29,6 @@ 
XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest2/.config \
 -audiodev '{"id":"audio1","driver":"none"}' \
 -vnc 127.0.0.1:0,audiodev=audio1 \
 -device 
'{"driver":"vfio-pci-nohotplug","host":":06:12.5","id":"hostdev0","display":"on","ramfb":true,"bus":"pci.0","addr":"0x2"}'
 \
+-device 
'{"driver":"vfio-pci","host":":06:13.6","id":"hostdev1","display":"off","ramfb":false,"bus":"pci.0","addr":"0x3"}'
 \
 -sandbox 
on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
 -msg timestamp=on
diff --git a/tests/qemuxmlconfdata/hostdev-pci-display-ramfb.x86_64-latest.xml 
b/tests/qemuxmlconfdata/hostdev-pci-display-ramfb.x86_64-latest.xml
index 16e8a1dee2..18b9bfb5bf 100644
--- a/tests/qemuxmlconfdata/hostdev-pci-display-ramfb.x86_64-latest.xml
+++ b/tests/qemuxmlconfdata/hostdev-pci-display-ramfb.x86_64-latest.xml
@@ -39,6 +39,12 @@
   
   
 
+
+  
+
+  
+  
+
 
   
 
diff --git a/tests/qemuxmlconfdata/hostdev-pci-display-ramfb.xml 
b/tests/qemuxmlconfdata/hostdev-pci-display-ramfb.xml
index 39c84da7e1..d263342b1d 100644
--- a/tests/qemuxmlconfdata/hostdev-pci-display-ramfb.xml
+++ b/tests/qemuxmlconfdata/hostdev-pci-display-ramfb.xml
@@ -25,6 +25,11 @@
 
   
 
+
+  
+
+  
+
 
   
 
-- 
2.45.0


Re: [PATCH v1 20/20] node_device_udev: Pass the `udevEventData` via parameter and use refcounting

2024-04-19 Thread Jonathon Jongsma

On 4/19/24 9:49 AM, Marc Hartmayer wrote:

Instead of accessing the global `driver` object pass the `udevEventData` as
parameter to the thread handler and watch callback. This has the advantage that:
1. proper refcounting
2. easier to read and test

Signed-off-by: Marc Hartmayer 
---
  src/node_device/node_device_udev.c | 14 +++---
  1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/src/node_device/node_device_udev.c 
b/src/node_device/node_device_udev.c
index cc8700fc4117..07cbdfa3bdeb 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -1856,7 +1856,7 @@ udevEventMonitorSanityCheck(udevEventData *priv,
  
  /**

   * udevEventHandleThread
- * @opaque: unused
+ * @opaque: udevEventData
   *
   * Thread to handle the udevEventHandleCallback processing when udev
   * tells us there's a device change for us (add, modify, delete, etc).
@@ -1875,9 +1875,9 @@ udevEventMonitorSanityCheck(udevEventData *priv,
   * would still come into play.
   */
  static void
-udevEventHandleThread(void *opaque G_GNUC_UNUSED)
+udevEventHandleThread(void *opaque)
  {
-udevEventData *priv = driver->privateData;
+g_autoptr(udevEventData) priv = opaque;
  struct udev_device *device = NULL;
  
  /* continue rather than break from the loop on non-fatal errors */

@@ -1943,9 +1943,9 @@ static void
  udevEventHandleCallback(int watch G_GNUC_UNUSED,
  int fd,
  int events G_GNUC_UNUSED,
-void *data G_GNUC_UNUSED)
+void *data)
  {
-udevEventData *priv = driver->privateData;
+udevEventData *priv = data;
  VIR_LOCK_GUARD lock = virObjectLockGuard(priv);
  
  if (!udevEventMonitorSanityCheck(priv, fd))

@@ -2485,7 +2485,7 @@ nodeStateInitialize(bool privileged,
  
  priv->udevThread = g_new0(virThread, 1);

  if (virThreadCreateFull(priv->udevThread, true, udevEventHandleThread,
-"udev-event", false, NULL) < 0) {
+"udev-event", false, virObjectRef(priv)) < 0) {
  virReportSystemError(errno, "%s",
   _("failed to create udev handler thread"));
  goto unlock;
@@ -2501,7 +2501,7 @@ nodeStateInitialize(bool privileged,
   * that appear while the enumeration is taking place.  */
  priv->watch = virEventAddHandle(udev_monitor_get_fd(priv->udev_monitor),
  VIR_EVENT_HANDLE_READABLE,
-udevEventHandleCallback, NULL, NULL);
+udevEventHandleCallback, 
virObjectRef(priv), virObjectUnref);
  if (priv->watch == -1)
  goto unlock;
  



Reviewed-by: Jonathon Jongsma 
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [PATCH v1 19/20] node_device_udev: Add support for `g_autoptr` to `udevEventData`

2024-04-19 Thread Jonathon Jongsma

On 4/19/24 9:49 AM, Marc Hartmayer wrote:

Use this feature in `udevEventDataNew`.

Signed-off-by: Marc Hartmayer 
---
  src/node_device/node_device_udev.c | 13 +
  1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/src/node_device/node_device_udev.c 
b/src/node_device/node_device_udev.c
index 0b255952a9f9..cc8700fc4117 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -78,6 +78,7 @@ struct _udevEventData {
  /* Immutable pointer, self-locking APIs */
  virThreadPool *workerPool;
  };
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(udevEventData, virObjectUnref);
  
  static virClass *udevEventDataClass;
  
@@ -121,7 +122,7 @@ VIR_ONCE_GLOBAL_INIT(udevEventData);

  static udevEventData *
  udevEventDataNew(void)
  {
-udevEventData *ret = NULL;
+g_autoptr(udevEventData) ret = NULL;
  
  if (udevEventDataInitialize() < 0)

  return NULL;
@@ -129,19 +130,15 @@ udevEventDataNew(void)
  if (!(ret = virObjectLockableNew(udevEventDataClass)))
  return NULL;
  
-if (virCondInit(>udevThreadCond) < 0) {

-virObjectUnref(ret);
+if (virCondInit(>udevThreadCond) < 0)
  return NULL;
-}
  
-if (virMutexInit(>mdevctlLock) < 0) {

-virObjectUnref(ret);
+if (virMutexInit(>mdevctlLock) < 0)
  return NULL;
-}
  
  ret->mdevctlTimeout = -1;

  ret->watch = -1;
-return ret;
+return g_steal_pointer();
  }
  
  typedef enum {



Reviewed-by: Jonathon Jongsma 
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [PATCH v1 18/20] node_device_udev: Make the code easier to read

2024-04-19 Thread Jonathon Jongsma

On 4/19/24 9:49 AM, Marc Hartmayer wrote:

There is only one case where force is true, therefore let's inline that case.

Signed-off-by: Marc Hartmayer 
---
  src/node_device/node_device_udev.c | 25 +++--
  1 file changed, 11 insertions(+), 14 deletions(-)

diff --git a/src/node_device/node_device_udev.c 
b/src/node_device/node_device_udev.c
index 25571ebf708f..0b255952a9f9 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -2202,21 +2202,14 @@ mdevctlEnableMonitor(udevEventData *priv)
  
  /* Schedules an mdevctl update for 100ms in the future, canceling any existing

   * timeout that may have been set. In this way, multiple update requests in
- * quick succession can be collapsed into a single update. if @force is true,
- * the worker job is submitted immediately. */
+ * quick succession can be collapsed into a single update. */
  static void
-scheduleMdevctlUpdate(udevEventData *data,
-  bool force)
+scheduleMdevctlUpdate(udevEventData *data)
  {
-if (!force) {
-if (data->mdevctlTimeout != -1)
-virEventRemoveTimeout(data->mdevctlTimeout);
-data->mdevctlTimeout = virEventAddTimeout(100, submitMdevctlUpdate,
-  data, NULL);
-return;
-}
-
-submitMdevctlUpdate(-1, data);
+if (data->mdevctlTimeout != -1)
+virEventRemoveTimeout(data->mdevctlTimeout);
+data->mdevctlTimeout = virEventAddTimeout(100, submitMdevctlUpdate,
+  data, NULL);
  }
  
  
@@ -2251,7 +2244,11 @@ mdevctlEventHandleCallback(GFileMonitor *monitor G_GNUC_UNUSED,

   * CHANGES_DONE_HINT event. As a fallback,  add a timeout to trigger the
   * signal if that event never comes */
  VIR_WITH_OBJECT_LOCK_GUARD(priv) {
-scheduleMdevctlUpdate(priv, (event_type == 
G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT));
+if (event_type == G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT) {
+submitMdevctlUpdate(-1, priv);
+} else {
+scheduleMdevctlUpdate(priv);
+}
  }
  }
  



I don't mind either way
Reviewed-by: Jonathon Jongsma 
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [PATCH v1 17/20] node_device_udev: Call `nodeDeviceUpdateMediatedDevices` directly

2024-04-19 Thread Jonathon Jongsma

On 4/19/24 9:49 AM, Marc Hartmayer wrote:

When an udev event occurs the mdev active config data requires an update via
mdevctl as the udev does not contain all config data. This update needs to occur
immediate and to be finished before the libvirt nodedev event is issued to keep
the API usage reliable.


This commit message is almost the same as patch 3 (except the 
'immediate' was not changed to 'immediately' ;)  This patch is just 
handling the 'remove' and 'adding a parent device that supports mdevs' 
use cases where patch 3 handled the 'add a new mdev device' case. Should 
we just squash patch 3 with this patch and handle all cases at the same 
time?




The only case where a direct `nodeDeviceUpdateMediatedDevices` is not wished is
`mdevctlEventHandleCallback` - see commit 2c57b28191b9 ("nodedev: Refresh mdev
devices when changes are detected") for details, but for this case there are no
nodedev events created so the problem described above does not exist.

`udevAddOneDevice` and `udevRemoveOneDeviceSysPath` are only called by the
worker pool threads therefore it's possible to call the
`nodeDeviceUpdateMediatedDevices` directly without blocking the udev thread.


These function names no longer exist as of the previous patch, so we 
should probably update the commit log.


I should also note that there is a comment in node_device_driver.c that 
refers to the udevAddOneDevice() function which is now also out of date.




Signed-off-by: Marc Hartmayer 
---
  src/node_device/node_device_udev.c | 16 +++-
  1 file changed, 3 insertions(+), 13 deletions(-)

diff --git a/src/node_device/node_device_udev.c 
b/src/node_device/node_device_udev.c
index 67a8b5cd7132..25571ebf708f 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -1504,9 +1504,6 @@ udevGetDeviceDetails(virNodeDeviceDriverState 
*driver_state, struct udev_device
  }
  
  
-static void scheduleMdevctlUpdate(udevEventData *data, bool force);

-
-
  static int
  processNodeDeviceRemoveEvent(virNodeDeviceDriverState *driver_state, const 
char *path)
  {
@@ -1540,9 +1537,8 @@ processNodeDeviceRemoveEvent(virNodeDeviceDriverState 
*driver_state, const char
  virNodeDeviceObjEndAPI();
  
  /* cannot check for mdev_types since they have already been removed */

-VIR_WITH_OBJECT_LOCK_GUARD(driver->privateData) {
-scheduleMdevctlUpdate(driver_state->privateData, false);
-}
+if (nodeDeviceUpdateMediatedDevices(driver_state) < 0)
+VIR_WARN("mdevctl failed to update mediated devices");
  
  virObjectEventStateQueue(driver_state->nodeDeviceEventState, event);

  return 0;
@@ -1666,16 +1662,10 @@ 
processNodeDeviceAddAndChangeEvent(virNodeDeviceDriverState *driver_state, struc
  has_mdev_types = virNodeDeviceObjHasCap(obj, VIR_NODE_DEV_CAP_MDEV_TYPES);
  virNodeDeviceObjEndAPI();
  
-if (has_mdev_types) {

-VIR_WITH_OBJECT_LOCK_GUARD(driver_state->privateData) {
-scheduleMdevctlUpdate(driver_state->privateData, false);
-}
-}
-
  /* The added mdev needs an immediate active config update before the event
   * is issued so that full device information is available at the time that
   * the 'created' event is emitted. */
-if (is_mdev && (nodeDeviceUpdateMediatedDevices(driver_state) < 0)) {
+if ((has_mdev_types || is_mdev) && 
(nodeDeviceUpdateMediatedDevices(driver_state) < 0)) {
  VIR_WARN("Update of mediated device %s failed",
       NULLSTR_EMPTY(sysfs_path));
  }


Reviewed-by: Jonathon Jongsma 
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [PATCH v1 16/20] node_device_udev: Use a worker pool for processing events and emitting nodedev event

2024-04-19 Thread Jonathon Jongsma

On 4/19/24 11:04 AM, Marc Hartmayer wrote:

On Fri, Apr 19, 2024 at 04:49 PM +0200, Marc Hartmayer  
wrote:

Use a worker pool for processing the events (e.g. udev, mdevctl config changes)
and the initialization instead of a separate initThread and a mdevctl-thread.
This has the large advantage that we can leverage the job API and now this
thread pool is responsible to do all the "costly-work" and emitting the libvirt
nodedev events.

Signed-off-by: Marc Hartmayer 
---
  src/node_device/node_device_udev.c | 244 +
  1 file changed, 179 insertions(+), 65 deletions(-)

diff --git a/src/node_device/node_device_udev.c 
b/src/node_device/node_device_udev.c
index e4b1532dc385..67a8b5cd7132 100644


[…snip…]


  }
  
@@ -2278,11 +2380,19 @@ nodeStateShutdownWait(void)

  return 0;
  
  VIR_WITH_OBJECT_LOCK_GUARD(priv) {

-if (priv->initThread)
-virThreadJoin(priv->initThread);
-if (priv->udevThread)
-virThreadJoin(priv->udevThread);



+if (priv->mdevctlTimeout != -1) {
+virEventRemoveTimeout(priv->mdevctlTimeout);
+priv->mdevctlTimeout = -1;
+}
+
+if (priv->watch) {
+virEventRemoveHandle(priv->watch);
+priv->watch = -1;
+}


Too many rebases… the diff should read as follows:

@@ -2278,11 +2380,12 @@ nodeStateShutdownWait(void)
  return 0;

  VIR_WITH_OBJECT_LOCK_GUARD(priv) {
-if (priv->initThread)
-virThreadJoin(priv->initThread);
  if (priv->udevThread)
  virThreadJoin(priv->udevThread);
  }
+
+if (priv->workerPool)
+virThreadPoolDrain(priv->workerPool);
  return 0;
  }

[…snip]





Reviewed-by: Jonathon Jongsma 
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [PATCH v1 15/20] node_device_udev: Pass the driver state as parameter in preparation for the next commit

2024-04-19 Thread Jonathon Jongsma
entry);

+udevProcessDeviceListEntry(driver_state, udev, list_entry);
  }
  
  ret = 0;

@@ -1756,12 +1756,12 @@ udevHandleOneDevice(struct udev_device *device)
  VIR_DEBUG("udev action: '%s': %s", action, 
udev_device_get_syspath(device));
  
  if (STREQ(action, "add") || STREQ(action, "change"))

-return udevAddOneDevice(device);
+return udevAddOneDevice(driver, device);
  
  if (STREQ(action, "remove")) {

  const char *path = udev_device_get_syspath(device);
  
-return udevRemoveOneDeviceSysPath(path);

+return udevRemoveOneDeviceSysPath(driver, path);
  }
  
  if (STREQ(action, "move")) {

@@ -1770,10 +1770,10 @@ udevHandleOneDevice(struct udev_device *device)
  if (devpath_old) {
  g_autofree char *devpath_old_fixed = g_strdup_printf("/sys%s", 
devpath_old);
  
-udevRemoveOneDeviceSysPath(devpath_old_fixed);

+udevRemoveOneDeviceSysPath(driver, devpath_old_fixed);
  }
  
-return udevAddOneDevice(device);

+return udevAddOneDevice(driver, device);
  }
  
  return 0;

@@ -1995,15 +1995,15 @@ udevSetupSystemDev(void)
  static void
  nodeStateInitializeEnumerate(void *opaque)
  {
-struct udev *udev = opaque;
  udevEventData *priv = driver->privateData;
+struct udev *udev = opaque;


unnecessary change?

  
  /* Populate with known devices */

-if (udevEnumerateDevices(udev) != 0)
+if (udevEnumerateDevices(driver, udev) != 0)
  goto error;
  /* Load persistent mdevs (which might not be activated yet) and additional
   * information about active mediated devices from mdevctl */
-if (nodeDeviceUpdateMediatedDevices() != 0)
+if (nodeDeviceUpdateMediatedDevices(driver) != 0)
  goto error;
  
   cleanup:

@@ -2051,9 +2051,11 @@ udevPCITranslateInit(bool privileged G_GNUC_UNUSED)
  
  
  static void

-mdevctlUpdateThreadFunc(void *opaque G_GNUC_UNUSED)
+mdevctlUpdateThreadFunc(void *opaque)
  {
-if (nodeDeviceUpdateMediatedDevices() < 0)
+virNodeDeviceDriverState *driver_state = opaque;
+
+if (nodeDeviceUpdateMediatedDevices(driver_state) < 0)
  VIR_WARN("mdevctl failed to update mediated devices");
  }
  
@@ -2070,7 +2072,7 @@ launchMdevctlUpdateThread(int timer G_GNUC_UNUSED, void *opaque)

  }
  
  if (virThreadCreateFull(, false, mdevctlUpdateThreadFunc,

-        "mdevctl-thread", false, NULL) < 0) {
+"mdevctl-thread", false, driver) < 0) {
  virReportSystemError(errno, "%s",
   _("failed to create mdevctl thread"));
  }




Reviewed-by: Jonathon Jongsma 
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [PATCH v1 14/20] node_device_udev: nodeStateShutdownPrepare: Disconnect the signals explicitly

2024-04-19 Thread Jonathon Jongsma

On 4/19/24 9:49 AM, Marc Hartmayer wrote:

The documentation of gobject signals reads:

"If you are connecting handlers to signals and using a GObject instance as your
signal handler user data, you should remember to pair calls to
g_signal_connect() with calls to g_signal_handler_disconnect() or
g_signal_handlers_disconnect_by_func(). While signal handlers are automatically
disconnected when the object emitting the signal is finalised..." [1]

This means that the signal handlers are automatically disconnected as soon as
the `priv->mdevCtlMonitors` are finalised/released by `udevEventDataDispose`.
But this also means that it's possible that new work is tried to be scheduled
for the workerpool by the `mdevctlEventHandleCallback` (main thread context)
even if the workerpool has already been stopped by `nodeStateShutdownWait`. To
fully understand this, it's important to know that the main loop of the main
thread is still running for some time even after `nodeStateShutdownPrepare` has
been called. Let's avoid this situation by explicitly disconnect the signals
during `nodeStateShutdownPrepare`, which is called in the main thread, so that
no new work is attempted to be scheduled for the worker pool.

[1] 
https://docs.gtk.org/gobject/signals.html#memory-management-of-signal-handlers

Signed-off-by: Marc Hartmayer 
---
  src/node_device/node_device_udev.c | 6 ++
  1 file changed, 6 insertions(+)

diff --git a/src/node_device/node_device_udev.c 
b/src/node_device/node_device_udev.c
index a3006433e842..38740033a66e 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -2236,6 +2236,12 @@ nodeStateShutdownPrepare(void)
  if (!priv)
  return 0;
  
+VIR_WITH_MUTEX_LOCK_GUARD(>mdevctlLock) {

+GList *tmp;
+for (tmp = priv->mdevctlMonitors; tmp; tmp = tmp->next)
+g_signal_handlers_disconnect_by_data(tmp->data, priv);
+}
+
  VIR_WITH_OBJECT_LOCK_GUARD(priv) {
  if (priv->mdevctlTimeout != -1) {
  virEventRemoveTimeout(priv->mdevctlTimeout);



Reviewed-by: Jonathon Jongsma 
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [PATCH v1 13/20] node_device_udev: Introduce and use `stateShutdownPrepare` and `stateShutdownWait`

2024-04-19 Thread Jonathon Jongsma

On 4/19/24 9:49 AM, Marc Hartmayer wrote:

Introduce and use the driver functions for the node state shutdown preparation
and wait. As they're also called in the error/cleanup path of
`nodeStateInitialize`, they must be written in a way, that they can safely be
executed even if not everything is initialized.

In the next commit, these functions will be extended.

Signed-off-by: Marc Hartmayer 
---
  src/node_device/node_device_udev.c | 84 ++
  1 file changed, 63 insertions(+), 21 deletions(-)

diff --git a/src/node_device/node_device_udev.c 
b/src/node_device/node_device_udev.c
index 1638a7196709..a3006433e842 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -92,12 +92,6 @@ udevEventDataDispose(void *obj)
  g_list_free_full(g_steal_pointer(>mdevctlMonitors), 
g_object_unref);
  }
  
-if (priv->watch != -1)

-virEventRemoveHandle(priv->watch);
-
-if (priv->mdevctlTimeout != -1)
-virEventRemoveTimeout(priv->mdevctlTimeout);
-
  g_clear_pointer(>udevThread, g_free);
  
  if (priv->udev_monitor) {

@@ -1733,24 +1727,10 @@ udevPCITranslateDeinit(void)
  static int
  nodeStateCleanup(void)
  {
-udevEventData *priv = NULL;
-
  if (!driver)
  return -1;
  
-priv = driver->privateData;

-if (priv) {
-VIR_WITH_OBJECT_LOCK_GUARD(priv) {
-priv->udevThreadQuit = true;
-virCondSignal(>udevThreadCond);
-}
-if (priv->initThread)
-virThreadJoin(priv->initThread);
-if (priv->udevThread)
-virThreadJoin(priv->udevThread);
-}
-
-virObjectUnref(priv);
+virObjectUnref(driver->privateData);
  virObjectUnref(driver->nodeDeviceEventState);
  
  virNodeDeviceObjListFree(driver->devs);

@@ -2241,6 +2221,64 @@ mdevctlEventHandleCallback(GFileMonitor *monitor 
G_GNUC_UNUSED,
  }
  
  
+/* Note: It must be safe to call this function even if the driver was not

+ *   successfully initialized. This must be considered when changing this
+ *   function. */
+static int
+nodeStateShutdownPrepare(void)
+{
+udevEventData *priv = NULL;
+
+if (!driver)
+return 0;
+
+priv = driver->privateData;
+if (!priv)
+return 0;
+
+VIR_WITH_OBJECT_LOCK_GUARD(priv) {
+if (priv->mdevctlTimeout != -1) {
+virEventRemoveTimeout(priv->mdevctlTimeout);
+priv->mdevctlTimeout = -1;
+}
+
+if (priv->watch) {
+virEventRemoveHandle(priv->watch);
+priv->watch = -1;
+}
+
+priv->udevThreadQuit = true;
+virCondSignal(>udevThreadCond);
+}
+return 0;
+}
+
+
+/* Note: It must be safe to call this function even if the driver was not
+ *   successfully initialized. This must be considered when changing this
+ *   function. */
+static int
+nodeStateShutdownWait(void)
+{
+udevEventData *priv = NULL;
+
+if (!driver)
+return 0;
+
+priv = driver->privateData;
+if (!priv)
+return 0;
+
+VIR_WITH_OBJECT_LOCK_GUARD(priv) {
+if (priv->initThread)
+virThreadJoin(priv->initThread);
+if (priv->udevThread)
+virThreadJoin(priv->udevThread);
+}
+return 0;
+}
+
+
  static int
  nodeStateInitialize(bool privileged,
  const char *root,
@@ -2375,6 +2413,8 @@ nodeStateInitialize(bool privileged,
  return VIR_DRV_STATE_INIT_COMPLETE;
  
   cleanup:

+nodeStateShutdownPrepare();
+nodeStateShutdownWait();
  nodeStateCleanup();
  return VIR_DRV_STATE_INIT_ERROR;
  
@@ -2440,6 +2480,8 @@ static virStateDriver udevStateDriver = {

  .stateInitialize = nodeStateInitialize, /* 0.7.3 */
  .stateCleanup = nodeStateCleanup, /* 0.7.3 */
  .stateReload = nodeStateReload, /* 0.7.3 */
+.stateShutdownPrepare = nodeStateShutdownPrepare, /* 10.3.0 */
+    .stateShutdownWait = nodeStateShutdownWait, /* 10.3.0 */
  };
  
  



Reviewed-by: Jonathon Jongsma 
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [PATCH v1 12/20] node_device_udev: Fix leak of mdevctlLock, udevThreadCond, and mdevCtlMonitors

2024-04-19 Thread Jonathon Jongsma

On 4/19/24 9:49 AM, Marc Hartmayer wrote:

Even if `priv->udev_monitor` was never initialized, the mdevctlLock, udevThread
were. Therefore let's match the order of releasing the resources the order of
allocating the resources in `nodeStateInitialize`.

In addition, use `g_steal_pointer` in `g_list_free_full`.

Signed-off-by: Marc Hartmayer 
---
  src/node_device/node_device_udev.c | 18 +-
  1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/src/node_device/node_device_udev.c 
b/src/node_device/node_device_udev.c
index 7f233652b461..1638a7196709 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -88,6 +88,10 @@ udevEventDataDispose(void *obj)
  
  g_clear_pointer(>initThread, g_free);
  
+VIR_WITH_MUTEX_LOCK_GUARD(>mdevctlLock) {

+g_list_free_full(g_steal_pointer(>mdevctlMonitors), 
g_object_unref);
+}
+
  if (priv->watch != -1)
  virEventRemoveHandle(priv->watch);
  
@@ -96,16 +100,12 @@ udevEventDataDispose(void *obj)
  
  g_clear_pointer(>udevThread, g_free);
  
-if (!priv->udev_monitor)

-return;
-
-udev = udev_monitor_get_udev(priv->udev_monitor);
-udev_monitor_unref(priv->udev_monitor);
-udev_unref(udev);
-
-VIR_WITH_MUTEX_LOCK_GUARD(>mdevctlLock) {
-g_list_free_full(priv->mdevctlMonitors, g_object_unref);
+if (priv->udev_monitor) {
+udev = udev_monitor_get_udev(priv->udev_monitor);
+udev_monitor_unref(priv->udev_monitor);
+udev_unref(udev);
  }
+
  virMutexDestroy(>mdevctlLock);
  
  virCondDestroy(>udevThreadCond);



Reviewed-by: Jonathon Jongsma 
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [PATCH v1 11/20] node_device_udev: Move responsibility to release `(init|udev)Thread` to `udevEventDataDispose`

2024-04-19 Thread Jonathon Jongsma

On 4/19/24 9:49 AM, Marc Hartmayer wrote:

Everything is released in `udevEventDataDispose` except for the threads, change
this as this makes the code easier to read as it can be simplified a little.

Signed-off-by: Marc Hartmayer 
---
  src/node_device/node_device_udev.c | 14 ++
  1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/src/node_device/node_device_udev.c 
b/src/node_device/node_device_udev.c
index 1c8832ebd990..7f233652b461 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -86,12 +86,16 @@ udevEventDataDispose(void *obj)
  struct udev *udev = NULL;
  udevEventData *priv = obj;
  
+g_clear_pointer(>initThread, g_free);

+
  if (priv->watch != -1)
  virEventRemoveHandle(priv->watch);
  
  if (priv->mdevctlTimeout != -1)

  virEventRemoveTimeout(priv->mdevctlTimeout);
  
+g_clear_pointer(>udevThread, g_free);

+
  if (!priv->udev_monitor)
  return;
  
@@ -1740,14 +1744,10 @@ nodeStateCleanup(void)

  priv->udevThreadQuit = true;
  virCondSignal(>udevThreadCond);
  }
-if (priv->initThread) {
+if (priv->initThread)
  virThreadJoin(priv->initThread);
-g_clear_pointer(>initThread, g_free);
-}
-if (priv->udevThread) {
+if (priv->udevThread)
  virThreadJoin(priv->udevThread);
-g_clear_pointer(>udevThread, g_free);
-}
  }
  
  virObjectUnref(priv);

@@ -2338,7 +2338,6 @@ nodeStateInitialize(bool privileged,
  "udev-event", false, NULL) < 0) {
  virReportSystemError(errno, "%s",
   _("failed to create udev handler thread"));
-g_clear_pointer(>udevThread, g_free);
  goto unlock;
  }
  
@@ -2370,7 +2369,6 @@ nodeStateInitialize(bool privileged,

  "nodedev-init", false, udev) < 0) {
  virReportSystemError(errno, "%s",
   _("failed to create udev enumerate thread"));
-g_clear_pointer(>initThread, g_free);
  goto cleanup;
  }
  


Reviewed-by: Jonathon Jongsma 
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [PATCH v1 07/20] node_device_udev: Don't take `mdevctlLock` for `mdevctl list` and add comments about locking

2024-04-19 Thread Jonathon Jongsma

On 4/19/24 9:49 AM, Marc Hartmayer wrote:

Commit a99d876a0f58 ("node_device: Use automatic mutex management") replaced the
locking mechanism and accidentally removed the comment with the reason why the
lock is taken. The reason was to "ensure only a single thread can query mdevctl
at a time", but this reason is no longer valid or maybe it never was. Therefore,
let's remove this lock and add a comment to `mdevCtl` what it protects.

Signed-off-by: Marc Hartmayer 
---
  src/node_device/node_device_udev.c | 6 ++
  1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/src/node_device/node_device_udev.c 
b/src/node_device/node_device_udev.c
index 049501c62870..757febffa2f8 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -72,8 +72,9 @@ struct _udevEventData {
  /* init thread */
  virThread *initThread;
  
-GList *mdevctlMonitors;

+/* Protects @mdevctlMonitors */
  virMutex mdevctlLock;
+GList *mdevctlMonitors;
  int mdevctlTimeout;
  };
  
@@ -2074,9 +2075,6 @@ udevPCITranslateInit(bool privileged G_GNUC_UNUSED)

  static void
  mdevctlUpdateThreadFunc(void *opaque G_GNUC_UNUSED)
  {
-udevEventData *priv = driver->privateData;
-VIR_LOCK_GUARD lock = virLockGuardLock(>mdevctlLock);
-
  if (nodeDeviceUpdateMediatedDevices() < 0)
  VIR_WARN("mdevctl failed to update mediated devices");
  }


Reviewed-by: Jonathon Jongsma 
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [RFC PATCH v1 12/15] node_device_udev: Use a worker pool for processing the udev events

2024-04-18 Thread Jonathon Jongsma

On 4/12/24 8:36 AM, Marc Hartmayer wrote:

Use a worker pool for processing the udev events and the initialization instead
of a separate initThread and a mdevctl-thread. This has the large advantage that
we can leverage the job API and now this thread pool is responsible to do all
the "costly-work" and the libvirt nodedev event creation.

TODOs:
+ IMO, it's better practice for all functions called by the virThreadPool's
   worker thread to pass the driver via parameter and not global variables. 
Easier
   to test and cleaner.


I'm not opposed, but I think it should be a separate commit since it 
introduces a lot of churn that is unrelated to the thread pool.



+ how many worker threads should we have at maximum?
+ there are still TODO's in the code
+ improve error reporting
+ improve naming - e.g. rename more udevXXX functions?

Signed-off-by: Marc Hartmayer 
---
  src/node_device/node_device_driver.h |   2 +-
  src/node_device/node_device_driver.c |   6 +-
  src/node_device/node_device_udev.c   | 295 +++
  3 files changed, 209 insertions(+), 94 deletions(-)

diff --git a/src/node_device/node_device_driver.h 
b/src/node_device/node_device_driver.h
index f195cfef9d49..2781ad136d68 100644
--- a/src/node_device/node_device_driver.h
+++ b/src/node_device/node_device_driver.h
@@ -147,7 +147,7 @@ nodeDeviceParseMdevctlJSON(const char *jsonstring,
 bool defined);
  
  int

-nodeDeviceUpdateMediatedDevices(void);
+nodeDeviceUpdateMediatedDevices(virNodeDeviceDriverState *driver);
  
  void

  nodeDeviceGenerateName(virNodeDeviceDef *def,
diff --git a/src/node_device/node_device_driver.c 
b/src/node_device/node_device_driver.c
index f623339dc973..59c5f9b417a4 100644
--- a/src/node_device/node_device_driver.c
+++ b/src/node_device/node_device_driver.c
@@ -1887,7 +1887,7 @@ removeMissingPersistentMdev(virNodeDeviceObj *obj,
  
  
  int

-nodeDeviceUpdateMediatedDevices(void)
+nodeDeviceUpdateMediatedDevices(virNodeDeviceDriverState *node_driver)
  {
  g_autofree virNodeDeviceDef **defs = NULL;
  g_autofree virNodeDeviceDef **act_defs = NULL;
@@ -1911,7 +1911,7 @@ nodeDeviceUpdateMediatedDevices(void)
  /* Any mdevs that were previously defined but were not returned in the
   * latest mdevctl query should be removed from the device list */
  data.defs = defs;
-virNodeDeviceObjListForEachRemove(driver->devs,
+virNodeDeviceObjListForEachRemove(node_driver->devs,
removeMissingPersistentMdev, );
  
  for (i = 0; i < data.ndefs; i++)

@@ -2374,7 +2374,7 @@ nodeDeviceUpdate(virNodeDevice *device,
   cleanup:
  virNodeDeviceObjEndAPI();
  if (updated)
-nodeDeviceUpdateMediatedDevices();
+nodeDeviceUpdateMediatedDevices(driver);
  
  return ret;

  }


So far, all of the changes have only been related to the change of the 
global driver variable.




diff --git a/src/node_device/node_device_udev.c 
b/src/node_device/node_device_udev.c
index cec7d837c43e..2a252d8fe62b 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -43,6 +43,7 @@
  #include "virnetdev.h"
  #include "virmdev.h"
  #include "virutil.h"
+#include "virthreadpool.h"
  
  #include "configmake.h"
  
@@ -69,14 +70,14 @@ struct _udevEventData {

  bool udevThreadQuit;
  bool udevDataReady;
  
-/* init thread */

-virThread *initThread;
-
  /* Protects @mdevctlMonitors and must be taken when `mdevctl` command is
   * called to make sure only one thread can query mdevctl at a time. */
  virMutex mdevctlLock;
  GList *mdevctlMonitors;
  int mdevctlTimeout;
+
+/* Immutable pointer, self-locking APIs */
+virThreadPool *workerPool;
  };
  
  static virClass *udevEventDataClass;

@@ -146,6 +147,79 @@ udevEventDataNew(void)
  return ret;
  }
  
+typedef enum {

+  NODE_DEVICE_EVENT_INIT = 0,
+  NODE_DEVICE_EVENT_ADD,
+  NODE_DEVICE_EVENT_REMOVE,
+  NODE_DEVICE_EVENT_CHANGE,
+  NODE_DEVICE_EVENT_MOVE,


These events are from the udev subsystem, so I think it would be nicer 
to name them such. NODE_DEVICE_EVENT_UDEV_ADD, etc.



+  NODE_DEVICE_EVENT_UPDATE,


And this isn't really an event -- it's a description of what you want to 
do in response to the event. It might make more sense to be named 
something like:


NODE_DEVICE_EVENT_MDEVCTL_CONFIG_CHANGED

I don't mind too much either way.


+
+  NODE_DEVICE_EVENT_LAST
+} nodeDeviceEventType;
+
+struct _nodeDeviceEvent {
+nodeDeviceEventType eventType;
+void *data;
+};


I think it might be nicer to have the caller decide how the data should 
be freed by passing a free function like so:


struct _nodeDeviceEvent {
nodeDeviceEventType eventType;
void *data;
virFreeCallback dataFree;
};
typedef struct _nodeDeviceEvent nodeDeviceEvent;

static nodeDeviceEvent*
nodeDeviceEventNew(nodeDeviceEventType event_type, gpointer data, 
virFreeCallback dataFree)

{

Re: [RFC PATCH v1 11/15] node_device_udev: Use `stateShutdownPrepare` and `stateShutdownWait`

2024-04-18 Thread Jonathon Jongsma

On 4/12/24 8:36 AM, Marc Hartmayer wrote:

Use the proper driver functions for the node state shutdown preparation and
wait. In the next patch, these functions will be extended.

Signed-off-by: Marc Hartmayer 
---
  src/node_device/node_device_udev.c | 54 +++---
  1 file changed, 42 insertions(+), 12 deletions(-)

diff --git a/src/node_device/node_device_udev.c 
b/src/node_device/node_device_udev.c
index 672da8f5a19f..cec7d837c43e 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -1736,18 +1736,8 @@ nodeStateCleanup(void)
  
  priv = driver->privateData;

  if (priv) {
-VIR_WITH_OBJECT_LOCK_GUARD(priv) {
-priv->udevThreadQuit = true;
-virCondSignal(>udevThreadCond);
-}
-if (priv->initThread) {
-virThreadJoin(priv->initThread);
-g_clear_pointer(>initThread, g_free);
-}
-if (priv->udevThread) {
-virThreadJoin(priv->udevThread);
-g_clear_pointer(>udevThread, g_free);
-}
+g_clear_pointer(>initThread, g_free);
+g_clear_pointer(>udevThread, g_free);
  }
  
  virObjectUnref(priv);

@@ -2440,12 +2430,52 @@ static virConnectDriver udevConnectDriver = {
  .nodeDeviceDriver = ,
  };
  
+static int

+nodeStateShutdownPrepare(void)
+{
+udevEventData *priv = NULL;
+
+if (!driver)
+return 0;
+
+priv = driver->privateData;
+if (!priv)
+return 0;
+
+VIR_WITH_OBJECT_LOCK_GUARD(priv) {
+priv->udevThreadQuit = true;
+virCondSignal(>udevThreadCond);
+}
+return 0;
+}
+
+static int
+nodeStateShutdownWait(void)
+{
+udevEventData *priv = NULL;
+
+if (!driver)
+return 0;
+
+priv = driver->privateData;
+if (!priv)
+return 0;
+
+if (priv->initThread)
+  virThreadJoin(priv->initThread);
+
+if (priv->udevThread)
+  virThreadJoin(priv->udevThread);
+return 0;
+}
  
  static virStateDriver udevStateDriver = {

  .name = "udev",
  .stateInitialize = nodeStateInitialize, /* 0.7.3 */
  .stateCleanup = nodeStateCleanup, /* 0.7.3 */
  .stateReload = nodeStateReload, /* 0.7.3 */
+.stateShutdownPrepare = nodeStateShutdownPrepare,
+.stateShutdownWait = nodeStateShutdownWait,
  };
  
  



Reviewed-by: Jonathon Jongsma 
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [RFC PATCH v1 10/15] node_device_udev: Inline `udevRemoveOneDevice`

2024-04-18 Thread Jonathon Jongsma

On 4/12/24 8:36 AM, Marc Hartmayer wrote:

Inline `udevRemoveOneDevice` as it's used only once.

Signed-off-by: Marc Hartmayer 
---
  src/node_device/node_device_udev.c | 17 +
  1 file changed, 5 insertions(+), 12 deletions(-)

diff --git a/src/node_device/node_device_udev.c 
b/src/node_device/node_device_udev.c
index a121ad99a676..672da8f5a19f 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -1490,16 +1490,6 @@ udevRemoveOneDeviceSysPath(const char *path)
  return 0;
  }
  
-

-static int
-udevRemoveOneDevice(struct udev_device *device)
-{
-const char *path = udev_device_get_syspath(device);
-
-return udevRemoveOneDeviceSysPath(path);
-}
-
-
  static int
  udevSetParent(struct udev_device *device,
virNodeDeviceDef *def)
@@ -1788,8 +1778,11 @@ udevHandleOneDevice(struct udev_device *device)
  if (STREQ(action, "add") || STREQ(action, "change"))
  return udevAddOneDevice(device);
  
-if (STREQ(action, "remove"))

-return udevRemoveOneDevice(device);
+if (STREQ(action, "remove")) {
+const char *path = udev_device_get_syspath(device);
+
+return udevRemoveOneDeviceSysPath(path);
+}
  
  if (STREQ(action, "move")) {

  const char *devpath_old = udevGetDeviceProperty(device, 
"DEVPATH_OLD");


Fine

Reviewed-by: Jonathon Jongsma 
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [RFC PATCH v1 09/15] node_device_udev: Add prefix `udev` for udev related data

2024-04-18 Thread Jonathon Jongsma

On 4/12/24 8:36 AM, Marc Hartmayer wrote:

The new names make it easier to understand the purpose of the data.

Reviewed-by: Boris Fiuczynski 
Signed-off-by: Marc Hartmayer 
---
  src/node_device/node_device_udev.c | 48 +++---
  1 file changed, 24 insertions(+), 24 deletions(-)

diff --git a/src/node_device/node_device_udev.c 
b/src/node_device/node_device_udev.c
index 0c393b6233a4..a121ad99a676 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -63,11 +63,11 @@ struct _udevEventData {
  struct udev_monitor *udev_monitor;
  int watch;
  
-/* Thread data */

-virThread *th;
-virCond threadCond;
-bool threadQuit;
-bool dataReady;
+/* Udev thread data */
+virThread *udevThread;
+virCond udevThreadCond;
+bool udevThreadQuit;
+bool udevDataReady;
  
  /* init thread */

  virThread *initThread;
@@ -105,7 +105,7 @@ udevEventDataDispose(void *obj)
  }
  virMutexDestroy(>mdevctlLock);
  
-virCondDestroy(>threadCond);

+virCondDestroy(>udevThreadCond);
  }
  
  
@@ -131,7 +131,7 @@ udevEventDataNew(void)

  if (!(ret = virObjectLockableNew(udevEventDataClass)))
  return NULL;
  
-if (virCondInit(>threadCond) < 0) {

+if (virCondInit(>udevThreadCond) < 0) {
  virObjectUnref(ret);
  return NULL;
  }
@@ -1747,16 +1747,16 @@ nodeStateCleanup(void)
  priv = driver->privateData;
  if (priv) {
  VIR_WITH_OBJECT_LOCK_GUARD(priv) {
-priv->threadQuit = true;
-virCondSignal(>threadCond);
+priv->udevThreadQuit = true;
+virCondSignal(>udevThreadCond);
  }
  if (priv->initThread) {
  virThreadJoin(priv->initThread);
  g_clear_pointer(>initThread, g_free);
  }
-if (priv->th) {
-virThreadJoin(priv->th);
-g_clear_pointer(>th, g_free);
+if (priv->udevThread) {
+virThreadJoin(priv->udevThread);
+g_clear_pointer(>udevThread, g_free);
  }
  }
  
@@ -1865,15 +1865,15 @@ udevEventHandleThread(void *opaque G_GNUC_UNUSED)

  /* continue rather than break from the loop on non-fatal errors */
  while (1) {
  VIR_WITH_OBJECT_LOCK_GUARD(priv) {
-while (!priv->dataReady && !priv->threadQuit) {
-if (virCondWait(>threadCond, >parent.lock)) {
+while (!priv->udevDataReady && !priv->udevThreadQuit) {
+if (virCondWait(>udevThreadCond, >parent.lock)) {
  virReportSystemError(errno, "%s",
   _("handler failed to wait on 
condition"));
  return;
  }
  }
  
-if (priv->threadQuit)

+if (priv->udevThreadQuit)
  return;
  
  errno = 0;

@@ -1904,7 +1904,7 @@ udevEventHandleThread(void *opaque G_GNUC_UNUSED)
   * after the udev_monitor_receive_device wouldn't help much
   * due to event mgmt and scheduler timing. */
  VIR_WITH_OBJECT_LOCK_GUARD(priv) {
-priv->dataReady = false;
+priv->udevDataReady = false;
  }
  
  continue;

@@ -1931,11 +1931,11 @@ udevEventHandleCallback(int watch G_GNUC_UNUSED,
  VIR_LOCK_GUARD lock = virObjectLockGuard(priv);
  
  if (!udevEventMonitorSanityCheck(priv, fd))

-priv->threadQuit = true;
+priv->udevThreadQuit = true;
  else
-priv->dataReady = true;
+priv->udevDataReady = true;
  
-virCondSignal(>threadCond);

+virCondSignal(>udevThreadCond);
  }
  
  
@@ -2045,8 +2045,8 @@ nodeStateInitializeEnumerate(void *opaque)

  VIR_WITH_OBJECT_LOCK_GUARD(priv) {
  ignore_value(virEventRemoveHandle(priv->watch));
  priv->watch = -1;
-priv->threadQuit = true;
-virCondSignal(>threadCond);
+priv->udevThreadQuit = true;
+virCondSignal(>udevThreadCond);
  }
  
  goto cleanup;

@@ -2344,12 +2344,12 @@ nodeStateInitialize(bool privileged,
  udev_monitor_set_receive_buffer_size(priv->udev_monitor,
   128 * 1024 * 1024);
  
-priv->th = g_new0(virThread, 1);

-if (virThreadCreateFull(priv->th, true, udevEventHandleThread,
+priv->udevThread = g_new0(virThread, 1);
+if (virThreadCreateFull(priv->udevThread, true, udevEventHandleThread,
  "udev-event", false, NULL) < 0) {
  virReportSystemError(errno, "%s",
       _("failed to create udev handler thread"));
-g_clear_pointer(>th, g_free);
+g_cl

Re: [RFC PATCH v1 08/15] node_device_udev: Take lock if `driver->privateData` is modified

2024-04-18 Thread Jonathon Jongsma

On 4/12/24 8:36 AM, Marc Hartmayer wrote:

Since @driver->privateData is modified take the lock.

Reviewed-by: Boris Fiuczynski 
Signed-off-by: Marc Hartmayer 
---
  src/node_device/node_device_udev.c | 15 +++
  1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/src/node_device/node_device_udev.c 
b/src/node_device/node_device_udev.c
index 5d474acdc2e0..0c393b6233a4 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -1482,7 +1482,9 @@ udevRemoveOneDeviceSysPath(const char *path)
  virNodeDeviceObjEndAPI();
  
  /* cannot check for mdev_types since they have already been removed */

-scheduleMdevctlUpdate(driver->privateData, false);
+VIR_WITH_OBJECT_LOCK_GUARD(driver->privateData) {
+scheduleMdevctlUpdate(driver->privateData, false);
+}
  
  virObjectEventStateQueue(driver->nodeDeviceEventState, event);

  return 0;
@@ -1616,8 +1618,11 @@ udevAddOneDevice(struct udev_device *device)
  has_mdev_types = virNodeDeviceObjHasCap(obj, VIR_NODE_DEV_CAP_MDEV_TYPES);
  virNodeDeviceObjEndAPI();
  
-if (has_mdev_types)

-scheduleMdevctlUpdate(driver->privateData, false);
+if (has_mdev_types) {
+VIR_WITH_OBJECT_LOCK_GUARD(driver->privateData) {
+scheduleMdevctlUpdate(driver->privateData, false);
+}
+}
  
  /* The added mdev needs an immediate active config update before

   * the event is issued to allow sane API usage. */
@@ -2241,7 +2246,9 @@ mdevctlEventHandleCallback(GFileMonitor *monitor 
G_GNUC_UNUSED,
   * configuration change, try to coalesce these changes by waiting for the
   * CHANGES_DONE_HINT event. As a fallback,  add a timeout to trigger the
   * signal if that event never comes */
-scheduleMdevctlUpdate(priv, (event_type == 
G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT));
+VIR_WITH_OBJECT_LOCK_GUARD(priv) {
+scheduleMdevctlUpdate(priv, (event_type == 
G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT));
+}
  }
  
  


I don't see any cases where we would not want to take the lock (e.g. 
because it has already been taken), so maybe it would be better simply 
to lock the object within the scheduleMdevctlUpdate() function rather 
than requiring each caller to lock it?


Reviewed-by: Jonathon Jongsma 
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [RFC PATCH v1 07/15] node_device_udev: Add comments about locking

2024-04-18 Thread Jonathon Jongsma

On 4/12/24 8:36 AM, Marc Hartmayer wrote:

Commit a99d876a0f58 ("node_device: Use automatic mutex management") replaced the
locking mechanism and accidentally removed the comment with the reason why the
lock is taken. Restore this comment and add a new comment about the lock.

Reviewed-by: Boris Fiuczynski 
Signed-off-by: Marc Hartmayer 
---
  src/node_device/node_device_udev.c | 5 -
  1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/node_device/node_device_udev.c 
b/src/node_device/node_device_udev.c
index 469538a1395d..5d474acdc2e0 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -72,8 +72,10 @@ struct _udevEventData {
  /* init thread */
  virThread *initThread;
  
-GList *mdevctlMonitors;

+/* Protects @mdevctlMonitors and must be taken when `mdevctl` command is
+ * called to make sure only one thread can query mdevctl at a time. */
  virMutex mdevctlLock;
+GList *mdevctlMonitors;
  int mdevctlTimeout;
  };
  
@@ -2074,6 +2076,7 @@ static void

  mdevctlUpdateThreadFunc(void *opaque G_GNUC_UNUSED)
  {
  udevEventData *priv = driver->privateData;
+/* ensure only a single thread can query mdevctl at a time */
  VIR_LOCK_GUARD lock = virLockGuardLock(>mdevctlLock);
  
  if (nodeDeviceUpdateMediatedDevices() < 0)



Serializing mdevctl queries is not strictly necessary, and in fact is 
removed in a later patch in this series (14), so I think we can just 
drop this patch, tbh.


I'm not sure that this mdevctlLock is even necessary. The udevEventData 
struct is already a lockable object, so I think we could simply get rid 
of this lock and use the object lock to protect the mdevctlMonitors 
variable if we wanted.


Jonathon
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [RFC PATCH v1 06/15] node_device_udev: Test for mdevctlTimeout != -1

2024-04-18 Thread Jonathon Jongsma

On 4/12/24 8:36 AM, Marc Hartmayer wrote:

It is done a little differently everywhere in libvirt, but most common is to
test for != -1.

Reviewed-by: Boris Fiuczynski 
Signed-off-by: Marc Hartmayer 
---
  src/node_device/node_device_udev.c | 7 ---
  1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/node_device/node_device_udev.c 
b/src/node_device/node_device_udev.c
index 1d3be28f8f08..469538a1395d 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -88,7 +88,7 @@ udevEventDataDispose(void *obj)
  if (priv->watch != -1)
  virEventRemoveHandle(priv->watch);
  
-if (priv->mdevctlTimeout > 0)

+if (priv->mdevctlTimeout != -1)
  virEventRemoveTimeout(priv->mdevctlTimeout);
  
  if (!priv->udev_monitor)

@@ -139,6 +139,7 @@ udevEventDataNew(void)
  return NULL;
  }
  
+ret->mdevctlTimeout = -1;

  ret->watch = -1;
  return ret;
  }
@@ -2086,7 +2087,7 @@ launchMdevctlUpdateThread(int timer G_GNUC_UNUSED, void 
*opaque)
  udevEventData *priv = opaque;
  virThread thread;
  
-if (priv->mdevctlTimeout > 0) {

+if (priv->mdevctlTimeout != -1) {
  virEventRemoveTimeout(priv->mdevctlTimeout);
  priv->mdevctlTimeout = -1;
  }
@@ -2196,7 +2197,7 @@ scheduleMdevctlUpdate(udevEventData *data,
bool force)
  {
  if (!force) {
-if (data->mdevctlTimeout > 0)
+if (data->mdevctlTimeout != -1)
  virEventRemoveTimeout(data->mdevctlTimeout);
  data->mdevctlTimeout = virEventAddTimeout(100, 
launchMdevctlUpdateThread,
    data, NULL);



OK

Reviewed-by: Jonathon Jongsma 
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [RFC PATCH v1 05/15] node_device_udev: Remove the timeout if the data is disposed

2024-04-18 Thread Jonathon Jongsma

On 4/12/24 8:36 AM, Marc Hartmayer wrote:

Remove the timeout when the udevEventData is disposed, analogous to priv->watch.

Reviewed-by: Boris Fiuczynski 
Signed-off-by: Marc Hartmayer 
---
  src/node_device/node_device_udev.c | 3 +++
  1 file changed, 3 insertions(+)

diff --git a/src/node_device/node_device_udev.c 
b/src/node_device/node_device_udev.c
index 3297bdd8d7ef..1d3be28f8f08 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -88,6 +88,9 @@ udevEventDataDispose(void *obj)
  if (priv->watch != -1)
  virEventRemoveHandle(priv->watch);
  
+if (priv->mdevctlTimeout > 0)

+virEventRemoveTimeout(priv->mdevctlTimeout);
+
  if (!priv->udev_monitor)
  return;
  


Reviewed-by: Jonathon Jongsma 
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [RFC PATCH v1 04/15] nodedev: reset active config data on udev remove event

2024-04-18 Thread Jonathon Jongsma
onfig *config)
+{
+size_t i = 0;
+
+g_clear_pointer(>type, g_free);
+for (i = 0; i < config->nattributes; i++)
+virMediatedDeviceAttrFree(config->attributes[i]);
+config->nattributes = 0;
+g_clear_pointer(>attributes, g_free);
+}
+
  
  #define MDEV_BUS_DIR "/sys/class/mdev_bus"
  
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms

index 84e30b711c67..fd413949dae2 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2778,6 +2778,8 @@ virMacMapWriteFile;
  # util/virmdev.h
  virMediatedDeviceAttrFree;
  virMediatedDeviceAttrNew;
+virMediatedDeviceConfigClear;
+virMediatedDeviceConfigFree;
  virMediatedDeviceFree;
  virMediatedDeviceGetIOMMUGroupDev;
  virMediatedDeviceGetIOMMUGroupNum;



Reviewed-by: Jonathon Jongsma 
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [RFC PATCH v1 03/15] nodedev: immediate update of active config on udev add

2024-04-18 Thread Jonathon Jongsma

On 4/12/24 8:36 AM, Marc Hartmayer wrote:

From: Boris Fiuczynski 

When an udev add event occurs the mdev active config data requires an
update via mdevctl as the udev does not contain all config data.
This update needs to occur immediate and to be finished before the


s/immediate/immediately/


libvirt CREATE event is issued to keep the API usage reliable.

After this change, scheduleMdevctlUpdate call is already called in
`udevAddOneDevice` and can therefore be removed in `udevHandleOneDevice`.

Signed-off-by: Boris Fiuczynski 
Signed-off-by: Marc Hartmayer 
---
  src/node_device/node_device_udev.c | 22 +-
  1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/src/node_device/node_device_udev.c 
b/src/node_device/node_device_udev.c
index 6613528d0e37..03ef0c14371a 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -1535,6 +1535,7 @@ udevSetParent(struct udev_device *device,
  static int
  udevAddOneDevice(struct udev_device *device)
  {
+g_autofree char *sysfs_path = NULL;
  virNodeDeviceDef *def = NULL;
  virNodeDeviceObj *obj = NULL;
  virNodeDeviceDef *objdef;
@@ -1549,6 +1550,9 @@ udevAddOneDevice(struct udev_device *device)
  def = g_new0(virNodeDeviceDef, 1);
  
  def->sysfs_path = g_strdup(udev_device_get_syspath(device));

+/* Create a copy of sysfs_path so it can be safely accessed, even without
+ * holding the @obj lock during the VIR_WARN(...) call at the end. */
+sysfs_path = g_strdup(def->sysfs_path);
  
  udevGetStringProperty(device, "DRIVER", >driver);
  
@@ -1608,6 +1612,13 @@ udevAddOneDevice(struct udev_device *device)

  if (has_mdev_types)
  scheduleMdevctlUpdate(driver->privateData, false);
  
+/* The added mdev needs an immediate active config update before

+ * the event is issued to allow sane API usage. */


How about simply something like "so that full device information is 
available at the time that the 'created' event is emitted"



+if (is_mdev && (nodeDeviceUpdateMediatedDevices() < 0)) {
+VIR_WARN("Update of mediated device %s failed",
+ NULLSTR_EMPTY(sysfs_path));
+}
+ >   ret = 0;
  
   cleanup:

@@ -1758,19 +1769,12 @@ nodeStateCleanup(void)
  static int
  udevHandleOneDevice(struct udev_device *device)
  {
-virNodeDevCapType dev_cap_type;
  const char *action = udev_device_get_action(device);
  
  VIR_DEBUG("udev action: '%s': %s", action, udev_device_get_syspath(device));
  
-if (STREQ(action, "add") || STREQ(action, "change")) {

-int ret = udevAddOneDevice(device);
-if (ret == 0 &&
-udevGetDeviceType(device, _cap_type) == 0 &&
-dev_cap_type == VIR_NODE_DEV_CAP_MDEV)
-scheduleMdevctlUpdate(driver->privateData, false);
-return ret;
-}
+if (STREQ(action, "add") || STREQ(action, "change"))
+return udevAddOneDevice(device);
  
  if (STREQ(action, "remove"))

  return udevRemoveOneDevice(device);


Reviewed-by: Jonathon Jongsma 
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [PATCH v3 5/5] conf: nodedev: Fill active_config at XML parse time

2024-04-18 Thread Jonathon Jongsma

On 4/18/24 8:52 AM, Cole Robinson wrote:

On 4/17/24 10:12 AM, Daniel P. Berrangé wrote:

On Wed, Apr 17, 2024 at 09:58:10AM -0400, Cole Robinson wrote:

On 4/9/24 11:20 AM, Boris Fiuczynski wrote:

On 4/9/24 16:56, Cole Robinson wrote:

Commit v10.0.0-265-ge67bca23e4 added a `active_config` and
`defined_config` to nodedev mdev internal XML handling.
`defined_config` can be filled at XML parse time, but `active_config`
must be filled in by nodedev driver. This wasn't implemented for the
test driver however, which caused virt-manager test suite regressions.

Example before:

```
$ virsh --connect
test:///home/crobinso/src/virt-manager/tests/data/testdriver/testdriver.xml 
nodedev-dumpxml mdev_8e37ee90_2b51_45e3_9b25_bf8283c03110

    mdev_8e37ee90_2b51_45e3_9b25_bf8283c03110
   
/sys/devices/css0/0.0.0023/8e37ee90-2b51-45e3-9b25-bf8283c03110

    css_0_0_0023
    
  
  
    

```

Example after:

```
$ virsh --connect
test:///home/crobinso/src/virt-manager/tests/data/testdriver/testdriver.xml 
nodedev-dumpxml mdev_8e37ee90_2b51_45e3_9b25_bf8283c03110

    mdev_8e37ee90_2b51_45e3_9b25_bf8283c03110
   
/sys/devices/css0/0.0.0023/8e37ee90-2b51-45e3-9b25-bf8283c03110

    css_0_0_0023
    
  
    

```

Simplest solution is to fill in `active_config` at XML define time
as well. The real node_device driver already takes care to free any
`active_config` when it live updates this info, so we are safe there.


I do not think that it is a good idea to hack the general code which
creates in the real environments fake data.



I can't tell how this affects real environments. Is there a place in the
udev driver where XML is parsed, and then active_config isn't explicitly
updated?

If not, do you object to me pushing this with Michal's ACK? This is
causing some pain with virt-manager dev workflow


If your tests require active mdevs than the mocking code should set
these active and also do the config copy.



Obviously this can work but IMO it sets a bad precedent. If this
active/inactive_config structure is extended in the future, the test
driver syncing needs to be extended to match, or we need more plumbing
to share more of this


Personally I would have rather seen this implemented using ->newDef
pattern used by domain, network, storage. That's the closest thing to an
internal standard for handling differences between inactive config and
runtime config. ->def is copied to ->newDef at object startup time, and
the drivers change newDef as needed to reflect runtime state of the object.


Yes, if we need to store both active and inactive config information
then I would strongly prefer to have the normal def+newDef pattern,
so we can expose this difference in the APIs with an "INACTIVE" flag
and --inactive virsh opt.


That is already implemented in git, by Boris. But it's implemented
without the newDef pattern

- Cole


I can try to adapt the current implementation to use the def/newDef 
pattern. I didn't think to suggest this when the patch was originally 
submitted.


Jonathon
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [PATCH v1] node_device_conf: virNodeDeviceGetSCSITargetCaps: fix memory leak

2024-04-05 Thread Jonathon Jongsma

On 4/3/24 4:26 AM, Marc Hartmayer wrote:

Make sure the old value in `scsi_target->wwpn` is free'd before replacing it.

==9104== 38 bytes in 2 blocks are definitely lost in loss record 1,943 of 3,250
==9104==at 0x483B8C0: malloc (vg_replace_malloc.c:442)
==9104==by 0x4DFB69B: g_malloc (gmem.c:130)
==9104==by 0x4E1921D: g_strdup (gstrfuncs.c:363)
==9104==by 0x495D60B: g_strdup_inline (gstrfuncs.h:321)
==9104==by 0x495D60B: virFCReadRportValue (virfcp.c:62)
==9104==by 0x4A5F5CB: virNodeDeviceGetSCSITargetCaps 
(node_device_conf.c:2914)
==9104==by 0xBF62529: udevProcessSCSITarget (node_device_udev.c:657)
==9104==by 0xBF62529: udevGetDeviceDetails (node_device_udev.c:1406)
==9104==by 0xBF62529: udevAddOneDevice (node_device_udev.c:1563)
==9104==by 0xBF639B5: udevProcessDeviceListEntry (node_device_udev.c:1637)
==9104==by 0xBF639B5: udevEnumerateDevices (node_device_udev.c:1691)
==9104==by 0xBF639B5: nodeStateInitializeEnumerate (node_device_udev.c:2009)
==9104==by 0x49BDBFD: virThreadHelper (virthread.c:256)
==9104==by 0x5242069: start_thread (in /usr/lib64/libc.so.6)

Signed-off-by: Marc Hartmayer 
---
  src/conf/node_device_conf.c | 5 -
  1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c
index 32b69aae84f3..14504cbb9c1f 100644
--- a/src/conf/node_device_conf.c
+++ b/src/conf/node_device_conf.c
@@ -2897,6 +2897,7 @@ virNodeDeviceGetSCSITargetCaps(const char *sysfsPath,
  int ret = -1;
  g_autofree char *dir = NULL;
  g_autofree char *rport = NULL;
+g_autofree char *wwpn = NULL;
  
  VIR_DEBUG("Checking if '%s' is an FC remote port", scsi_target->name);
  
@@ -2912,11 +2913,13 @@ virNodeDeviceGetSCSITargetCaps(const char *sysfsPath,

  scsi_target->rport = g_steal_pointer();
  
  if (virFCReadRportValue(scsi_target->rport, "port_name",

-_target->wwpn) < 0) {
+) < 0) {
  VIR_WARN("Failed to read port_name for '%s'", scsi_target->rport);
  goto cleanup;
  }
  
+VIR_FREE(scsi_target->wwpn);

+scsi_target->wwpn = g_steal_pointer();
  scsi_target->flags |= VIR_NODE_DEV_CAP_FLAG_FC_RPORT;
  ret = 0;
  


base-commit: b902cfece0db71c3421b0bfe0e05d1dbe7890c31



Reviewed-by: Jonathon Jongsma 
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [PATCH 2/2] virDomainDeviceIsUSB: Handle all USB devices and simplify the code

2024-04-05 Thread Jonathon Jongsma

On 4/3/24 6:44 AM, Peter Krempa wrote:

Rework 'virDomainUSBDeviceDefForeach' to use virDomainDeviceInfoIterate
instead of open-coding all iterators. To achieve this
'virDomainDeviceIsUSB' needs to be fixed as it didn't properly handle
'sound', 'fs', 'chr', 'ccid', and 'net usb devices.


missing closing ' on the 'net' type.

Reviewed-by: Jonathon Jongsma 



Signed-off-by: Peter Krempa 
---
  src/conf/domain_conf.c | 228 +++--
  1 file changed, 106 insertions(+), 122 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 48c5d546da..457bee08b1 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -28262,28 +28262,117 @@ virDomainObjFormat(virDomainObj *obj,
  return virBufferContentAndReset();
  }

+
  static bool
-virDomainDeviceIsUSB(virDomainDeviceDef *dev)
-{
-int t = dev->type;
-if ((t == VIR_DOMAIN_DEVICE_DISK &&
- dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_USB) ||
-(t == VIR_DOMAIN_DEVICE_INPUT &&
- dev->data.input->bus == VIR_DOMAIN_INPUT_BUS_USB) ||
-(t == VIR_DOMAIN_DEVICE_HOSTDEV &&
- dev->data.hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
- dev->data.hostdev->source.subsys.type ==
- VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) ||
-(t == VIR_DOMAIN_DEVICE_HUB &&
- dev->data.hub->type == VIR_DOMAIN_HUB_TYPE_USB) ||
-(t == VIR_DOMAIN_DEVICE_REDIRDEV &&
- dev->data.redirdev->bus == VIR_DOMAIN_REDIRDEV_BUS_USB))
-return true;
+virDomainDeviceIsUSB(virDomainDeviceDef *dev,
+ bool skipHubs)
+{
+switch (dev->type) {
+case VIR_DOMAIN_DEVICE_HUB:
+if (skipHubs)
+return false;
+
+return dev->data.hub->type == VIR_DOMAIN_HUB_TYPE_USB;
+
+case VIR_DOMAIN_DEVICE_HOSTDEV:
+return dev->data.hostdev->source.subsys.type == 
VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB;
+
+case VIR_DOMAIN_DEVICE_DISK:
+return dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_USB;
+
+case VIR_DOMAIN_DEVICE_NET:
+return dev->data.net->model == VIR_DOMAIN_NET_MODEL_USB_NET;
+
+case VIR_DOMAIN_DEVICE_CONTROLLER:
+return dev->data.controller->type == VIR_DOMAIN_CONTROLLER_TYPE_CCID;
+
+case VIR_DOMAIN_DEVICE_INPUT:
+return dev->data.input->bus == VIR_DOMAIN_INPUT_BUS_USB;
+
+case VIR_DOMAIN_DEVICE_CHR:
+if (dev->data.chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL)
+return dev->data.chr->targetType == 
VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_USB;
+
+return false;
+
+case VIR_DOMAIN_DEVICE_SOUND:
+return dev->data.sound->model == VIR_DOMAIN_SOUND_MODEL_USB;
+
+case VIR_DOMAIN_DEVICE_REDIRDEV:
+return dev->data.redirdev->bus == VIR_DOMAIN_REDIRDEV_BUS_USB;
+
+case VIR_DOMAIN_DEVICE_FS:
+return dev->data.fs->fsdriver == VIR_DOMAIN_FS_DRIVER_TYPE_MTP;
+
+case VIR_DOMAIN_DEVICE_LEASE:
+case VIR_DOMAIN_DEVICE_VIDEO:
+case VIR_DOMAIN_DEVICE_WATCHDOG:
+case VIR_DOMAIN_DEVICE_GRAPHICS:
+case VIR_DOMAIN_DEVICE_NONE:
+case VIR_DOMAIN_DEVICE_SMARTCARD:
+case VIR_DOMAIN_DEVICE_MEMBALLOON:
+case VIR_DOMAIN_DEVICE_NVRAM:
+case VIR_DOMAIN_DEVICE_SHMEM:
+case VIR_DOMAIN_DEVICE_TPM:
+case VIR_DOMAIN_DEVICE_PANIC:
+case VIR_DOMAIN_DEVICE_LAST:
+case VIR_DOMAIN_DEVICE_RNG:
+case VIR_DOMAIN_DEVICE_MEMORY:
+case VIR_DOMAIN_DEVICE_IOMMU:
+case VIR_DOMAIN_DEVICE_VSOCK:
+case VIR_DOMAIN_DEVICE_AUDIO:
+case VIR_DOMAIN_DEVICE_CRYPTO:
+break;
+}

  return false;
  }


+struct virDomainUSBDeviceDefForeachIteratorData {
+virDomainUSBDeviceDefIterator iter;
+void *iterdata;
+bool skipHubs;
+};
+
+
+static int
+virDomainUSBDeviceDefForeachIterator(virDomainDef *def G_GNUC_UNUSED,
+ virDomainDeviceDef *device,
+ virDomainDeviceInfo *info,
+ void *opaque)
+{
+struct virDomainUSBDeviceDefForeachIteratorData *data = opaque;
+
+if (!virDomainDeviceIsUSB(device, data->skipHubs))
+return 0;
+
+if (data->iter(info, data->iterdata) < 0)
+return -1;
+
+return 0;
+}
+
+
+int
+virDomainUSBDeviceDefForeach(virDomainDef *def,
+ virDomainUSBDeviceDefIterator iter,
+ void *opaque,
+ bool skipHubs)
+{
+struct virDomainUSBDeviceDefForeachIteratorData data = {
+.iter = iter,
+.iterdata = opaque,
+.skipHubs = skipHubs,
+};
+
+return virDomainDeviceInfoIterate(def,
+  virDomainUSBDeviceDefForeachIterator,
+  );
+}
+
+
+
  typedef

Re: [PATCH 1/2] docs: Rewrite documentation for network device models

2024-04-05 Thread Jonathon Jongsma

On 4/3/24 6:44 AM, Peter Krempa wrote:

Since libvirt now tries to interpret network device models (unless an
unknow model is used) the documentation didn't make a good job
specifying what is supported.

Rewrite the docs to explicitly list the models which we do parse.

Signed-off-by: Peter Krempa 
---
  docs/formatdomain.rst | 29 -
  1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index e2f66b982c..a68d90c4a4 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -5592,23 +5592,26 @@ Setting the NIC model
 ...

  For hypervisors which support this, you can set the model of emulated network
-interface card.
+interface card via the ``model`` element.

-The values for ``type`` aren't defined specifically by libvirt, but by what the
-underlying hypervisor supports (if any). For QEMU and KVM you can get a list of
-supported models with these commands:
+While libvirt accepts any value as the ``type`` and passes it to the
+hypervisor to preserve compatibility, most devices nowadays have additional
+handling and address allocation which may not work properly unless the model
+is known by libvirt.

-::
+Libvirt supports natively the following network device models:
+``virtio``, ``virtio-transitional`` (:since:`Since 5.2.0`),
+``virtio-non-transitional`` (:since:`Since 5.2.0`),  ``e1000``, ``e1000e``,
+``igb`` (:since:`Since 9.3.0`), ``rtl8139``, ``netfront``,
+``usb-net`` (:since:`Since 10.3.0`), ``spapr-vlan``, ``lan9118``, 
``scm91c111``,
+``vlance``, ``vmxnet``, ``vmxnet2``, ``vmxnet3``, ``Am79C970A``, ``Am79C973``,
+``82540EM``, ``82545EM``, ``82543GC``.
+
+For QEMU you can get a list of supported models with this commands:


s/commands/command/



-   qemu -net nic,model=? /dev/null
-   qemu-kvm -net nic,model=? /dev/null
+::

-Typical values for QEMU and KVM include: ne2k_isa i82551 i82557b i82559er
-ne2k_pci pcnet rtl8139 e1000 virtio. :since:`Since 5.2.0`,
-``virtio-transitional`` and ``virtio-non-transitional`` values are supported.
-See `Virtio transitional devices`_ for more details.
-:since:`Since 9.3.0` igb is also supported.
-:since:`Since 10.3.0` usb-net is supported.
+   qemu-system-x86_64 -net nic,model=?

  Setting NIC driver-specific options
  ^^^


Reviewed-by: Jonathon Jongsma 
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [PATCH 2/3] nodedev: immediate update of active config on udev add

2024-03-28 Thread Jonathon Jongsma

On 3/27/24 1:14 PM, Marc Hartmayer wrote:

On Wed, Mar 27, 2024 at 10:53 AM -0500, Jonathon Jongsma  
wrote:

On 3/20/24 10:46 AM, Boris Fiuczynski wrote:

When an udev add event occurs the mdev active config data requires an
update via mdevctl as the udev does not contain all config data.
This update needs to occur immediate and to be finished before the
libvirt CREATE event is issued to keep the API usage reliable.


The problem that you're trying to solve isn't spelled out very
explicitly here. My understanding is that the issue occurs when you
start a mediated device that has attributes (and the device is supported
by callout scripts in mdevctl). With the current code, my assumption is
that we observe the following behavior:
- udev event is emitted
- libvirt handles the udev event and emits a
VIR_NODE_DEVICE_EVENT_CREATED event for the new mdev. At this point the
mdev only information that is provided by udev (such as uuid, mdev type)
and doesn't include any attributes, for example.
- we schedule a thread to query mdevctl for the full information for the
device. The mdev device gets update to include the full mdevctl data,
including attributes
- libvirt emits a VIR_NODE_DEVICE_EVENT_ID_UPDATE event to indicate that
the device information was updated

And you're trying to skip the last step and make sure that the
attributes are set at the time that the first CREATED event is
emitted.


Boris is currently on vacation so I cannot discuss this with him, but
that’s my understanding as well. For me, this assumption also makes
sense… because otherwise it’s awkward to use the libvirt events API for
mdev devices (wait for a CREATED event and then for an UPDATE event for
the same device - not a really good UX pattern IMO).

[…snip…]

   
+/* The added mdev needs an immediate active config update before

+ * the event is issues to allow sane API usage. */
+if (is_mdev && (nodeDeviceUpdateMediatedDevices() < 0))
+VIR_WARN("Update of mediated device %s failed",
+ def ? NULLSTR(def->sysfs_path) : "");
+
   ret = 0;
   
cleanup:

``

Right now libvirt has a dedicated thread for handling udev updates, and
we also spawn a separate thread to query mdevctl whenever we detect that
mdev state has changed. This patch makes it so that mdevctl is now
executed directly from the udev thread, which changes that separation of
responsibilities. It shouldn't cause any memory corruption since
nodeDeviceUpdateMediatedDevices() is already threadsafe, but it makes
the code harder to reason about. When we introduced mdevctl support to
libvirt, the first versions of my patch series did in fact query mdevctl
from the udev thread. But based on concerns during code review, it was
moved out to a separate thread. So I don't think that we should
necessarily reintroduce that here.


Yep.

Right now we already have in node_device_udev:
+ init thread for initialization
+ udev thread, which creates and then enqueues the libvirt events
+ mdevctl update thread, which calls `nodeDeviceUpdateMediateDevices()‘
   (executing 'mdevctl' and updating the internal data structures with
   the result)
+ main thread for the timeout mechanism to launch the mdevCtlUpdateThread
+ another thread (not sure if it’s the main thread): virNodeDeviceUpdate -> 
nodeDeviceUpdateMediateDevices()

How about:
+ instead of having a mdevctl update thread and an init thread we could
   have only one worker pool (similar to qemu_process.c)
+ one udev thread that dispatches the events and then submits jobs to
   the worker pool
+ main thread for the timeout mechanism to schedule the “mdev update worker 
pool job”
+ another thread (not sure if it’s the main thread):
   virNodeDeviceUpdate: -> nodeDeviceUpdateMediateDevices() <- maybe we
   can leave it as is.


This seems OK to me.

Jonathon
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [PATCH 2/3] nodedev: immediate update of active config on udev add

2024-03-27 Thread Jonathon Jongsma

On 3/20/24 10:46 AM, Boris Fiuczynski wrote:

When an udev add event occurs the mdev active config data requires an
update via mdevctl as the udev does not contain all config data.
This update needs to occur immediate and to be finished before the
libvirt CREATE event is issued to keep the API usage reliable.


The problem that you're trying to solve isn't spelled out very 
explicitly here. My understanding is that the issue occurs when you 
start a mediated device that has attributes (and the device is supported 
by callout scripts in mdevctl). With the current code, my assumption is 
that we observe the following behavior:

- udev event is emitted
- libvirt handles the udev event and emits a 
VIR_NODE_DEVICE_EVENT_CREATED event for the new mdev. At this point the 
mdev only information that is provided by udev (such as uuid, mdev type) 
and doesn't include any attributes, for example.
- we schedule a thread to query mdevctl for the full information for the 
device. The mdev device gets update to include the full mdevctl data, 
including attributes
- libvirt emits a VIR_NODE_DEVICE_EVENT_ID_UPDATE event to indicate that 
the device information was updated


And you're trying to skip the last step and make sure that the 
attributes are set at the time that the first CREATED event is emitted. 
Correct? Or is the behavior you're seeing different than what I've 
described?




Signed-off-by: Boris Fiuczynski 
---
  src/node_device/node_device_udev.c | 6 ++
  1 file changed, 6 insertions(+)

diff --git a/src/node_device/node_device_udev.c 
b/src/node_device/node_device_udev.c
index 4730a5b986..0f335df950 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -1606,6 +1606,12 @@ udevAddOneDevice(struct udev_device *device)
  if (has_mdev_types)
  scheduleMdevctlUpdate(driver->privateData, false);
  
+/* The added mdev needs an immediate active config update before

+ * the event is issues to allow sane API usage. */
+if (is_mdev && (nodeDeviceUpdateMediatedDevices() < 0))
+VIR_WARN("Update of mediated device %s failed",
+ def ? NULLSTR(def->sysfs_path) : "");
+
  ret = 0;
  
   cleanup:

``

Right now libvirt has a dedicated thread for handling udev updates, and 
we also spawn a separate thread to query mdevctl whenever we detect that 
mdev state has changed. This patch makes it so that mdevctl is now 
executed directly from the udev thread, which changes that separation of 
responsibilities. It shouldn't cause any memory corruption since 
nodeDeviceUpdateMediatedDevices() is already threadsafe, but it makes 
the code harder to reason about. When we introduced mdevctl support to 
libvirt, the first versions of my patch series did in fact query mdevctl 
from the udev thread. But based on concerns during code review, it was 
moved out to a separate thread. So I don't think that we should 
necessarily reintroduce that here.


In addition, I notice that udevHandleOneDevice() already schedules an 
mdevctl update thread to be run after this function (udevAddOneDevice()) 
is called for a mediated device. So after this patch, a new udev event 
for a mediated device would result in the udev thread querying mdevctl 
immediately and then also spawning a new thread to query mdevctl.


Jonathon
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [PATCH 1/3] nodedev: fix mdev add udev event data handling

2024-03-21 Thread Jonathon Jongsma

On 3/20/24 10:46 AM, Boris Fiuczynski wrote:

Two situations will trigger an udev add event:
  1) the mdev is created when started (transient) or
  2) the mdev was defined and is started
In case 1 there is no node object existing and no config data is copied.
In case 2 copying the active config data of an existing node object will
only copy invalid data. Instead copying the defined config data will
store valid data into the newly added node object.

Signed-off-by: Boris Fiuczynski 
---
  src/node_device/node_device_udev.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/node_device/node_device_udev.c 
b/src/node_device/node_device_udev.c
index f1e402f8f7..4730a5b986 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -1572,7 +1572,7 @@ udevAddOneDevice(struct udev_device *device)
  objdef = virNodeDeviceObjGetDef(obj);
  
  if (is_mdev)

-nodeDeviceDefCopyFromMdevctl(def, objdef, false);
+nodeDeviceDefCopyFromMdevctl(def, objdef, true);
  
  persistent = virNodeDeviceObjIsPersistent(obj);

  autostart = virNodeDeviceObjIsAutostart(obj);



Reviewed-by: Jonathon Jongsma 
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [PATCH 3/3] nodedev: reset active config data on udev remove event

2024-03-21 Thread Jonathon Jongsma

On 3/20/24 10:46 AM, Boris Fiuczynski wrote:

When a mdev device is destroyed or stopped the udev remove event
handling needs to reset the active config data of the node object
representing a persisted mdev.

Signed-off-by: Boris Fiuczynski 
---
  src/node_device/node_device_driver.c | 22 ++
  src/node_device/node_device_driver.h |  3 +++
  src/node_device/node_device_udev.c   |  1 +
  3 files changed, 26 insertions(+)

diff --git a/src/node_device/node_device_driver.c 
b/src/node_device/node_device_driver.c
index d99b48138e..1d93106e29 100644
--- a/src/node_device/node_device_driver.c
+++ b/src/node_device/node_device_driver.c
@@ -2018,6 +2018,28 @@ nodeDeviceDefCopyFromMdevctl(virNodeDeviceDef *dst,
  }
  
  
+/* A mediated device definition contains data from mdevctl about the active

+ * device. When the device is deactivated the active configuration data needs
+ * to be removed. */
+void
+nodeDeviceDefResetMdevActiveConfig(virNodeDeviceDef *def)
+{
+size_t i = 0;
+virMediatedDeviceConfig *active_config;
+
+if (def->caps->data.type != VIR_NODE_DEV_CAP_MDEV)
+return;
+
+active_config = >caps->data.mdev.active_config;
+
+g_clear_pointer(_config->type, g_free);
+for (i = 0; i < active_config->nattributes; i++)
+virMediatedDeviceAttrFree(active_config->attributes[i]);
+g_clear_pointer(_config->attributes, g_free);
+active_config->nattributes = 0;
+}
+
+


A good portion of this function is duplicating code that exists in 
virNodeDevCapsDefFree(). Let's just factor that code out into a 
virMediatedDeviceConfigClear() function and then use it from both locations.




  int
  nodeDeviceSetAutostart(virNodeDevice *device,
 int autostart)
diff --git a/src/node_device/node_device_driver.h 
b/src/node_device/node_device_driver.h
index b3bc4b2e96..f195cfef9d 100644
--- a/src/node_device/node_device_driver.h
+++ b/src/node_device/node_device_driver.h
@@ -197,3 +197,6 @@ int
  nodeDeviceUpdate(virNodeDevice *dev,
   const char *xmlDesc,
   unsigned int flags);
+
+void
+nodeDeviceDefResetMdevActiveConfig(virNodeDeviceDef *def);
diff --git a/src/node_device/node_device_udev.c 
b/src/node_device/node_device_udev.c
index 0f335df950..93d0dcedbc 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -1467,6 +1467,7 @@ udevRemoveOneDeviceSysPath(const char *path)
  if (virNodeDeviceObjIsPersistent(obj)) {
  VIR_FREE(def->sysfs_path);
  virNodeDeviceObjSetActive(obj, false);
+nodeDeviceDefResetMdevActiveConfig(def);
  } else {
  VIR_DEBUG("Removing device '%s' with sysfs path '%s'",
def->name, path);

___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [PATCH v3 01/12] cpu_map: update script to handle versioned CPUs

2024-03-20 Thread Jonathon Jongsma

On 3/4/24 11:35 AM, Jim Fehlig wrote:

On 3/1/24 10:13, Daniel P. Berrangé wrote:

On Fri, Mar 01, 2024 at 10:36:12AM -0600, Jonathon Jongsma wrote:

On 3/1/24 10:13 AM, Daniel P. Berrangé wrote:

On Tue, Feb 20, 2024 at 05:08:02PM -0700, Jim Fehlig wrote:

On 12/15/23 15:11, Jonathon Jongsma wrote:

Previously, the script only generated the parent CPU and any versions
that had a defined alias. The script now generates all CPU 
versions. Any

version that had a defined alias will continue to use that alias, but
those without aliases will use the generated name $BASECPUNAME-vN.

The reason for this change is two-fold. First, we need to add new 
models

that support new features (such as SEV-SNP). To deal with this, the
script now generates model definitions for all versions.

But we also need to ensure that our CPU definitions are 
migration-safe.

To deal with this issue we need to make sure we're always using the
canonical versioned names for CPUs.


Related to migration safety, do we need to be concerned with the 
expansion
of 'host-model' CPU? E.g. is it possible 'host-model' expands to 
EPYC before
introducing the new models, and EPYC-v4 afterwards? If so, what are 
the

ramifications of that?


Yes, I see that happening on my laptop in domcapabilities:

Currently libvirt reports:

  
    Snowridge
    Intel
    
    
    
   ...snip...


and after this series it reports:

  
    Snowridge-v4
    Intel
    
    
    
   ...snip...


That's not wrong per-se, becasue Snowrigde-v4 has a smaller
delta against my host CPU.

The problem is that libvirt updates the *live* XML for the
guest with this expansion.  IIUC, if we now attempt to
live migrate to a compatible machine running older libvirt
the migrate will fail as old libvirt doesn't know the -v4
CPU.


Downstream, we (SUSE) don't really support migrating from new -> old. Is 
this something we aim to support upstream?


I don't know the answer to this question.





I'm not sure how to address this ?


But don't we have this issue any time we add a new CPU model to libvirt?
Anytime there's a new model, it has the potential to be a closer 
match to

the host CPU than an existing model definition was. As I mentioned in my
previous reply, when e.g. the -noTSX CPU variants were added, didn't the
same sort of thing (potentially) happen? Or am I doing something
meaningfully different in this patch set than what happens in those
scenarios?


I think it probably /did/ happen, but that doesn't make it acceptable.
The noTSX stuff was the cause of massive amounts of compatibility pain
for mgmt apps, so the incompatibility in libvirt might have been glossed
over. We're adding alot of new versions here, so the possibly increasing
the visibility/impact of this libvirt change.


It can happen when we introduce an entirely new CPU model too. E.g. on a 
Genoa machine, prior to commit bfe53e9145c, host model expanded to


  
     EPYC-Milan
     AMD
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
   

After commit bfe53e9145c


     EPYC-Genoa
     AMD
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
   

Regards,
Jim


Does anybody have a response to this point from Jim? I can't really 
think of a way forward if it's not acceptable for the host model 
expansion to change between different versions of libvirt.


Jonathon
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [PATCH 1/2] conf: allow display and ramfb for vfio pci hostdevs

2024-03-20 Thread Jonathon Jongsma

On 3/20/24 3:08 AM, Daniel P. Berrangé wrote:

On Tue, Mar 19, 2024 at 05:25:54PM -0500, Jonathon Jongsma wrote:

We already allow the user to specify display="on" and ramfb="on" for
mdev host devices. But newer GPU models will no longer use the mdev
framework, so we should enable this same functionality for other
non-mdev passthrough PCI devices.

Resolves: https://issues.redhat.com/browse/RHEL-28808


This bug is private, so please describe the background more fully


With regards,
Daniel




Apologies. The context is that we currently support enabling display and 
ramfb support for hostdev vGPUs, but only for those using the mdev 
subsystem. However, going forward, some graphics cards will no longer 
use mdev for their vGPUs. In order to maintain the same capability for 
these devices, we can also enable it for other PCI passthrough devices. 
Apparently this is something that's used heavily by layered products 
like OSP.


Cheers,
Jonathon
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


[PATCH 1/2] conf: allow display and ramfb for vfio pci hostdevs

2024-03-19 Thread Jonathon Jongsma
We already allow the user to specify display="on" and ramfb="on" for
mdev host devices. But newer GPU models will no longer use the mdev
framework, so we should enable this same functionality for other
non-mdev passthrough PCI devices.

Resolves: https://issues.redhat.com/browse/RHEL-28808

Signed-off-by: Jonathon Jongsma 
---
 docs/formatdomain.rst |  8 
 src/conf/domain_conf.c| 20 +++-
 src/conf/domain_conf.h|  2 ++
 src/conf/domain_validate.c| 21 +
 src/conf/schemas/domaincommon.rng | 25 +++--
 5 files changed, 57 insertions(+), 19 deletions(-)

diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index 2adc2ff968..ab44ed58a6 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -4390,6 +4390,14 @@ or:
   starting the guest or hot-plugging the device and
   ``virNodeDeviceReAttach`` (or ``virsh nodedev-reattach``) after 
hot-unplug
   or stopping the guest.
+  :since:`Since 10.2.0` an optional ``display`` attribute may be used to
+  enable using a vgpu device as a display device for the guest. Supported
+  values are either ``on`` or ``off`` (default). There is also an optional
+  ``ramfb`` attribute with values of either ``on`` or ``off`` (default).
+  When enabled, the ``ramfb`` attribute provides a memory framebuffer 
device
+  to the guest. This framebuffer allows the vgpu to be used as a boot 
display
+  before the gpu driver is loaded within the guest. ``ramfb`` requires the
+  ``display`` attribute to be set to ``on``.
``scsi``
   For SCSI devices, user is responsible to make sure the device is not used
   by host. If supported by the hypervisor and OS, the optional ``sgio`` (
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 770b5fbbff..11a0b0ecda 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -6306,6 +6306,16 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node,
  VIR_XML_PROP_NONE,
  >ramfb) < 0)
 return -1;
+} else if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
+if (virXMLPropTristateSwitch(node, "display",
+ VIR_XML_PROP_NONE,
+ >display) < 0)
+return -1;
+
+if (virXMLPropTristateSwitch(node, "ramfb",
+ VIR_XML_PROP_NONE,
+ >ramfb) < 0)
+return -1;
 }
 
 switch (def->source.subsys.type) {
@@ -26251,6 +26261,7 @@ virDomainHostdevDefFormat(virBuffer *buf,
 const char *mode = virDomainHostdevModeTypeToString(def->mode);
 virDomainHostdevSubsysSCSI *scsisrc = >source.subsys.u.scsi;
 virDomainHostdevSubsysMediatedDev *mdevsrc = >source.subsys.u.mdev;
+virDomainHostdevSubsysPCI *pcisrc = >source.subsys.u.pci;
 virDomainHostdevSubsysSCSIVHost *scsihostsrc = 
>source.subsys.u.scsi_host;
 const char *type;
 
@@ -26319,7 +26330,14 @@ virDomainHostdevDefFormat(virBuffer *buf,
 virBufferAsprintf(buf, " ramfb='%s'",
   
virTristateSwitchTypeToString(mdevsrc->ramfb));
 }
-
+if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
+if (pcisrc->display != VIR_TRISTATE_SWITCH_ABSENT)
+virBufferAsprintf(buf, " display='%s'",
+  
virTristateSwitchTypeToString(pcisrc->display));
+if (pcisrc->ramfb != VIR_TRISTATE_SWITCH_ABSENT)
+virBufferAsprintf(buf, " ramfb='%s'",
+  
virTristateSwitchTypeToString(pcisrc->ramfb));
+}
 }
 virBufferAddLit(buf, ">\n");
 virBufferAdjustIndent(buf, 2);
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 76251938b8..5925faaf1a 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -236,6 +236,8 @@ struct _virDomainHostdevSubsysUSB {
 struct _virDomainHostdevSubsysPCI {
 virPCIDeviceAddress addr; /* host address */
 virDeviceHostdevPCIDriverInfo driver;
+virTristateSwitch display;
+virTristateSwitch ramfb;
 
 virBitmap *origstates;
 };
diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c
index faa7659f07..395e036e8f 100644
--- a/src/conf/domain_validate.c
+++ b/src/conf/domain_validate.c
@@ -1291,15 +1291,20 @@ virDomainDefHostdevValidate(const virDomainDef *def)
 }
 }
 
-if (dev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
-dev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV &&
-dev->source.subsys.u.mdev.ramfb == VIR_TRISTATE_SWITCH_ON) {
-

[PATCH 2/2] qemu: enable display/ramfb for vfio pci hostdevs

2024-03-19 Thread Jonathon Jongsma
Implement display="on" and ramfb="on" for vfio PCI host devices in qemu.
This enables passthrough PCI devices for display just like we did for
mdevs.

Resolves: https://issues.redhat.com/browse/RHEL-28808

Signed-off-by: Jonathon Jongsma 
---
 src/qemu/qemu_command.c   | 10 -
 src/qemu/qemu_validate.c  |  8 
 ...stdev-pci-display-ramfb.x86_64-latest.args | 33 ++
 ...ostdev-pci-display-ramfb.x86_64-latest.xml | 44 +++
 .../hostdev-pci-display-ramfb.xml | 33 ++
 tests/qemuxmlconftest.c   |  1 +
 6 files changed, 128 insertions(+), 1 deletion(-)
 create mode 100644 
tests/qemuxmlconfdata/hostdev-pci-display-ramfb.x86_64-latest.args
 create mode 100644 
tests/qemuxmlconfdata/hostdev-pci-display-ramfb.x86_64-latest.xml
 create mode 100644 tests/qemuxmlconfdata/hostdev-pci-display-ramfb.xml

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 2bb1b6a0e7..62df609884 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -4735,10 +4735,16 @@ qemuBuildPCIHostdevDevProps(const virDomainDef *def,
 virDomainNetTeamingInfo *teaming;
 g_autofree char *host = virPCIDeviceAddressAsString(>addr);
 const char *failover_pair_id = NULL;
+const char *driver = NULL;
 
 /* caller has to assign proper passthrough driver name */
 switch (pcisrc->driver.name) {
 case VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO:
+/* ramfb support requires the nohotplug variant */
+if (pcisrc->ramfb == VIR_TRISTATE_SWITCH_ON)
+driver = "vfio-pci-nohotplug";
+else
+driver = "vfio-pci";
 break;
 
 case VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_KVM:
@@ -4762,11 +4768,13 @@ qemuBuildPCIHostdevDevProps(const virDomainDef *def,
 failover_pair_id = teaming->persistent;
 
 if (virJSONValueObjectAdd(,
-  "s:driver", "vfio-pci",
+  "s:driver", driver,
   "s:host", host,
   "s:id", dev->info->alias,
   "p:bootindex", dev->info->effectiveBootIndex,
   "S:failover_pair_id", failover_pair_id,
+  "S:display", qemuOnOffAuto(pcisrc->display),
+  "B:ramfb", pcisrc->ramfb,
   NULL) < 0)
 return NULL;
 
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index 6a73d02050..edc7169a30 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -2477,6 +2477,14 @@ qemuValidateDomainDeviceDefHostdev(const 
virDomainHostdevDef *hostdev,
_("Write filtering of PCI device configuration 
space is not supported by qemu"));
 return -1;
 }
+
+if (hostdev->source.subsys.u.pci.display == 
VIR_TRISTATE_SWITCH_ON) {
+if (def->ngraphics == 0) {
+virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+   _("graphics device is needed for attribute 
value 'display=on' in "));
+return -1;
+}
+}
 break;
 
 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
diff --git a/tests/qemuxmlconfdata/hostdev-pci-display-ramfb.x86_64-latest.args 
b/tests/qemuxmlconfdata/hostdev-pci-display-ramfb.x86_64-latest.args
new file mode 100644
index 00..6a3bfbe6fb
--- /dev/null
+++ b/tests/qemuxmlconfdata/hostdev-pci-display-ramfb.x86_64-latest.args
@@ -0,0 +1,33 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest2 \
+USER=test \
+LOGNAME=test \
+XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest2/.local/share \
+XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest2/.cache \
+XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest2/.config \
+/usr/bin/qemu-system-x86_64 \
+-name guest=QEMUGuest2,debug-threads=on \
+-S \
+-object 
'{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest2/master-key.aes"}'
 \
+-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
+-accel tcg \
+-cpu qemu64 \
+-m size=219136k \
+-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
+-overcommit mem-lock=off \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-s

[PATCH 0/2] Add 'display' and 'ramfb' option for pci hostdevs

2024-03-19 Thread Jonathon Jongsma
see https://issues.redhat.com/browse/RHEL-28808

Jonathon Jongsma (2):
  conf: allow display and ramfb for vfio pci hostdevs
  qemu: enable display/ramfb for vfio pci hostdevs

 docs/formatdomain.rst |  8 
 src/conf/domain_conf.c| 20 -
 src/conf/domain_conf.h|  2 +
 src/conf/domain_validate.c| 21 +
 src/conf/schemas/domaincommon.rng | 25 ++-
 src/qemu/qemu_command.c   | 10 -
 src/qemu/qemu_validate.c  |  8 
 ...stdev-pci-display-ramfb.x86_64-latest.args | 33 ++
 ...ostdev-pci-display-ramfb.x86_64-latest.xml | 44 +++
 .../hostdev-pci-display-ramfb.xml | 33 ++
 tests/qemuxmlconftest.c   |  1 +
 11 files changed, 185 insertions(+), 20 deletions(-)
 create mode 100644 
tests/qemuxmlconfdata/hostdev-pci-display-ramfb.x86_64-latest.args
 create mode 100644 
tests/qemuxmlconfdata/hostdev-pci-display-ramfb.x86_64-latest.xml
 create mode 100644 tests/qemuxmlconfdata/hostdev-pci-display-ramfb.xml

-- 
2.44.0
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [PATCH v3 01/12] cpu_map: update script to handle versioned CPUs

2024-03-01 Thread Jonathon Jongsma

On 3/1/24 10:13 AM, Daniel P. Berrangé wrote:

On Tue, Feb 20, 2024 at 05:08:02PM -0700, Jim Fehlig wrote:

On 12/15/23 15:11, Jonathon Jongsma wrote:

Previously, the script only generated the parent CPU and any versions
that had a defined alias. The script now generates all CPU versions. Any
version that had a defined alias will continue to use that alias, but
those without aliases will use the generated name $BASECPUNAME-vN.

The reason for this change is two-fold. First, we need to add new models
that support new features (such as SEV-SNP). To deal with this, the
script now generates model definitions for all versions.

But we also need to ensure that our CPU definitions are migration-safe.
To deal with this issue we need to make sure we're always using the
canonical versioned names for CPUs.


Related to migration safety, do we need to be concerned with the expansion
of 'host-model' CPU? E.g. is it possible 'host-model' expands to EPYC before
introducing the new models, and EPYC-v4 afterwards? If so, what are the
ramifications of that?


Yes, I see that happening on my laptop in domcapabilities:

Currently libvirt reports:

 
   Snowridge
   Intel
   
   
   
  ...snip...


and after this series it reports:

 
   Snowridge-v4
   Intel
   
   
   
  ...snip...


That's not wrong per-se, becasue Snowrigde-v4 has a smaller
delta against my host CPU.

The problem is that libvirt updates the *live* XML for the
guest with this expansion.  IIUC, if we now attempt to
live migrate to a compatible machine running older libvirt
the migrate will fail as old libvirt doesn't know the -v4
CPU.

I'm not sure how to address this ?


But don't we have this issue any time we add a new CPU model to libvirt? 
Anytime there's a new model, it has the potential to be a closer match 
to the host CPU than an existing model definition was. As I mentioned in 
my previous reply, when e.g. the -noTSX CPU variants were added, didn't 
the same sort of thing (potentially) happen? Or am I doing something 
meaningfully different in this patch set than what happens in those 
scenarios?


Jonathon
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [PATCH v5 00/12] nodedev state and update

2024-02-22 Thread Jonathon Jongsma
It looks OK to me, but I'd personally like to see a second ACK on at 
least the API-related changes.


Reviewed-by: Jonathon Jongsma 



On 2/22/24 7:01 AM, Boris Fiuczynski wrote:

The series adds a dual state to the mdev node devices as these objects
can be active and defined at the same time. These two states can
become different. To be able to also introspect the persistent and
transient nodedevs filtering is added. To be able to also dump the XML
of an inactive state while the node device is active a new option is
added.

The last four patches add the capability to update a mdev node device.
This can be done on the persistent configuration, on the active
configuration or on both. To support this v1.3.0 of mdevctl is required.
nodeDeviceDefineXML() does now support modifying a persistent configuration.

Changes since v4:
* reworked findPersistentMdevNodeDevice()
* changed the way the split into the modify path and the cleanup/unlocking is
   done in nodeDeviceDefineXML()

Changes since v3:
* replaced in all patches occurrences of persisted with persistent

Changes since v2:
* made error messages in virNodeDeviceObjUpdateModificationImpact() device
   type agnostic
* renamed virNodeDeviceUpdateXML* into virNodeDeviceUpdate*
* renamed nodeDeviceDefCompareMdevs() into nodeDeviceDefValidateUpdate()
* renamed multiple local variable names
* removed method for config cloning by commenting cross config compare in
   nodeDeviceDefValidateUpdate()
* changed nodeDeviceDefineXML() to modify an existing persistent configuration

Changes since v1:
* replaced spec file requirement for v1.3.0 of mdevctl by a dynamic
   support check and an unsupported message if not available
* renamed persisted and persist into persistent
* removed persistent precheck in virsh
* addressed all other review comments made on v1
* added NEWS

Boris Fiuczynski (12):
   virmdev: prepare type and attributes for dual state
   node_device: refactor mdev attributes handling
   node_device: remove unnecessary checks in virNodeDeviceDefFormat
   nodedev: add an active config to mdev
   tools: add option inactive to nodedev-dumpxml
   nodedev: add persistent and transient filter on list
   tools: add switches persistent and transient to nodedev-list
   virsh: doc fix on nodedev-list
   api: add virNodeDeviceUpdate()
   nodedev: Implement virNodeDeviceUpdate
   virsh: add nodedev-update
   nodedev: allow modify on define of a persistent node device

  NEWS.rst  |  12 +
  docs/drvnodedev.rst   |   4 +-
  docs/manpages/virsh.rst   |  36 +-
  include/libvirt/libvirt-nodedev.h |  31 ++
  libvirt.spec.in   |   1 +
  src/access/viraccessperm.c|   1 +
  src/access/viraccessperm.h|   6 +
  src/conf/node_device_conf.c   |  76 +--
  src/conf/node_device_conf.h   |  14 +-
  src/conf/virnodedeviceobj.c   |  50 ++
  src/conf/virnodedeviceobj.h   |   3 +
  src/driver-nodedev.h  |   6 +
  src/libvirt-nodedev.c |  51 +-
  src/libvirt_private.syms  |   1 +
  src/libvirt_public.syms   |   5 +
  src/node_device/node_device_driver.c  | 474 ++
  src/node_device/node_device_driver.h  |  17 +-
  src/node_device/node_device_udev.c|   5 +-
  src/remote/remote_driver.c|   1 +
  src/remote/remote_protocol.x  |  17 +-
  src/remote_protocol-structs   |   6 +
  src/test/test_driver.c|   6 +-
  src/util/virmdev.h|   6 +
  ...60c_c60c_c60c_c60c_c60cc60cc60c_update.xml |  16 +
  tests/nodedevmdevctldata/mdevctl-modify.argv  |  25 +
  tests/nodedevmdevctldata/mdevctl-modify.json  |   4 +
  tests/nodedevmdevctltest.c|  94 +++-
  ...v_c60cc60c_c60c_c60c_c60c_c60cc60cc60c.xml |  14 +
  ...d_b7f0_4fea_b468_f1da537d301b_inactive.xml |   1 +
  ...v_c60cc60c_c60c_c60c_c60c_c60cc60cc60c.xml |  10 +
  ...c_c60c_c60c_c60c_c60cc60cc60c_inactive.xml |   9 +
  ...9_36ea_4111_8f0a_8c9a70e21366_inactive.xml |   1 +
  ...9_495e_4243_ad9f_beb3f14c23d9_inactive.xml |   1 +
  ...4_f554_4dc1_809d_b2a01e8e48ad_inactive.xml |   8 +
  ...6_1ca8_49ac_b176_871d16c13076_inactive.xml |   1 +
  tests/nodedevxml2xmltest.c|  59 ++-
  tools/virsh-nodedev.c | 140 +-
  37 files changed, 1057 insertions(+), 155 deletions(-)
  create mode 100644 
tests/nodedevmdevctldata/mdev_c60cc60c_c60c_c60c_c60c_c60cc60cc60c_update.xml
  create mode 100644 tests/nodedevmdevctldata/mdevctl-modify.argv
  create mode 100644 tests/nodedevmdevctldata/mdevctl-modify.json
  create mode 100644 
tests/nodedevschemadata/mdev_c60cc60c_c60c_c60c_c60c_c60cc60cc60c.xml
  create mode 12 
tests/nodedevxml2xmlout

Re: [PATCH v3 05/12] cpu_map: Add versioned EPYC CPUs

2024-02-21 Thread Jonathon Jongsma

On 2/20/24 6:28 PM, Jim Fehlig wrote:

On 12/15/23 15:12, Jonathon Jongsma wrote:

Signed-off-by: Jonathon Jongsma 
---
  src/cpu_map/index.xml |   6 +
  src/cpu_map/meson.build   |   6 +
  src/cpu_map/x86_EPYC-Milan-v2.xml | 108 ++
  src/cpu_map/x86_EPYC-Rome-v2.xml  |  93 +++
  src/cpu_map/x86_EPYC-Rome-v3.xml  |  95 +++
  src/cpu_map/x86_EPYC-Rome-v4.xml  |  94 +++
  src/cpu_map/x86_EPYC-v3.xml   |  87 ++
  src/cpu_map/x86_EPYC-v4.xml   |  88 ++
  .../x86_64-cpuid-EPYC-7502-32-Core-host.xml   |   5 +-
  .../x86_64-cpuid-EPYC-7601-32-Core-guest.xml  |   9 +-
  ...6_64-cpuid-EPYC-7601-32-Core-ibpb-host.xml |   8 +-
  ...4-cpuid-Ryzen-7-1800X-Eight-Core-guest.xml |   9 +-
  .../domaincapsdata/qemu_5.0.0-q35.x86_64.xml  |   1 +
  .../domaincapsdata/qemu_5.0.0-tcg.x86_64.xml  |   1 +
  tests/domaincapsdata/qemu_5.0.0.x86_64.xml    |   1 +
  .../domaincapsdata/qemu_5.1.0-q35.x86_64.xml  |   1 +
  .../domaincapsdata/qemu_5.1.0-tcg.x86_64.xml  |   1 +
  tests/domaincapsdata/qemu_5.1.0.x86_64.xml    |   1 +
  .../domaincapsdata/qemu_5.2.0-q35.x86_64.xml  |   1 +
  .../domaincapsdata/qemu_5.2.0-tcg.x86_64.xml  |   1 +
  tests/domaincapsdata/qemu_5.2.0.x86_64.xml    |   1 +
  .../domaincapsdata/qemu_6.0.0-q35.x86_64.xml  |   2 +
  .../domaincapsdata/qemu_6.0.0-tcg.x86_64.xml  |   2 +
  tests/domaincapsdata/qemu_6.0.0.x86_64.xml    |   2 +
  .../domaincapsdata/qemu_6.1.0-q35.x86_64.xml  |   2 +
  .../domaincapsdata/qemu_6.1.0-tcg.x86_64.xml  |   2 +
  tests/domaincapsdata/qemu_6.1.0.x86_64.xml    |   2 +
  .../domaincapsdata/qemu_6.2.0-q35.x86_64.xml  |   2 +
  .../domaincapsdata/qemu_6.2.0-tcg.x86_64.xml  |   2 +
  tests/domaincapsdata/qemu_6.2.0.x86_64.xml    |   2 +
  .../domaincapsdata/qemu_7.0.0-q35.x86_64.xml  |   2 +
  .../domaincapsdata/qemu_7.0.0-tcg.x86_64.xml  |   2 +
  tests/domaincapsdata/qemu_7.0.0.x86_64.xml    |   2 +
  .../domaincapsdata/qemu_7.1.0-q35.x86_64.xml  |   2 +
  .../domaincapsdata/qemu_7.1.0-tcg.x86_64.xml  |   2 +
  tests/domaincapsdata/qemu_7.1.0.x86_64.xml    |   2 +
  .../domaincapsdata/qemu_7.2.0-q35.x86_64.xml  |   2 +
  .../qemu_7.2.0-tcg.x86_64+hvf.xml |   2 +
  .../domaincapsdata/qemu_7.2.0-tcg.x86_64.xml  |   2 +
  tests/domaincapsdata/qemu_7.2.0.x86_64.xml    |   2 +
  .../domaincapsdata/qemu_8.0.0-q35.x86_64.xml  |   2 +
  .../domaincapsdata/qemu_8.0.0-tcg.x86_64.xml  |   2 +
  tests/domaincapsdata/qemu_8.0.0.x86_64.xml    |   2 +
  .../domaincapsdata/qemu_8.1.0-q35.x86_64.xml  |  11 +-
  .../domaincapsdata/qemu_8.1.0-tcg.x86_64.xml  |   6 +
  tests/domaincapsdata/qemu_8.1.0.x86_64.xml    |  11 +-
  .../domaincapsdata/qemu_8.2.0-q35.x86_64.xml  |  11 +-
  .../domaincapsdata/qemu_8.2.0-tcg.x86_64.xml  |   6 +
  tests/domaincapsdata/qemu_8.2.0.x86_64.xml    |  11 +-
  ...-host-model-fallback-kvm.x86_64-8.1.0.args |   2 +-
  ...host-model-fallback-kvm.x86_64-latest.args |   2 +-
  .../cpu-host-model-kvm.x86_64-8.1.0.args  |   2 +-
  .../cpu-host-model-kvm.x86_64-latest.args |   2 +-
  ...ost-model-nofallback-kvm.x86_64-8.1.0.args |   2 +-
  ...st-model-nofallback-kvm.x86_64-latest.args |   2 +-
  55 files changed, 686 insertions(+), 43 deletions(-)
  create mode 100644 src/cpu_map/x86_EPYC-Milan-v2.xml
  create mode 100644 src/cpu_map/x86_EPYC-Rome-v2.xml
  create mode 100644 src/cpu_map/x86_EPYC-Rome-v3.xml
  create mode 100644 src/cpu_map/x86_EPYC-Rome-v4.xml
  create mode 100644 src/cpu_map/x86_EPYC-v3.xml
  create mode 100644 src/cpu_map/x86_EPYC-v4.xml

diff --git a/src/cpu_map/index.xml b/src/cpu_map/index.xml
index d2c5af5797..861edc3bb7 100644
--- a/src/cpu_map/index.xml
+++ b/src/cpu_map/index.xml
@@ -67,9 +67,15 @@
  
  
  
+    
+    
  
  
+    
+    
+    
  
+    
  
  
diff --git a/src/cpu_map/meson.build b/src/cpu_map/meson.build
index ae5293e85f..68e093e041 100644
--- a/src/cpu_map/meson.build
+++ b/src/cpu_map/meson.build
@@ -39,8 +39,14 @@ cpumap_data = [
    'x86_Dhyana.xml',
    'x86_EPYC-IBPB.xml',
    'x86_EPYC.xml',
+  'x86_EPYC-v3.xml',
+  'x86_EPYC-v4.xml',
    'x86_EPYC-Genoa.xml',
+  'x86_EPYC-Milan-v2.xml',
    'x86_EPYC-Milan.xml',
+  'x86_EPYC-Rome-v2.xml',
+  'x86_EPYC-Rome-v3.xml',
+  'x86_EPYC-Rome-v4.xml',
    'x86_EPYC-Rome.xml',
    'x86_features.xml',
    'x86_Haswell-IBRS.xml',
diff --git a/src/cpu_map/x86_EPYC-Milan-v2.xml 
b/src/cpu_map/x86_EPYC-Milan-v2.xml

new file mode 100644
index 00..4cadba2325
--- /dev/null
+++ b/src/cpu_map/x86_EPYC-Milan-v2.xml
@@ -0,0 +1,108 @@
+


None of the existing files include this comment.


Yeah, I debated whether to leave them in or not. But I decided to 
include them and see what other people think. In general I find it nicer 
to not manually modify generated files if possible

Re: [PATCH v3 01/12] cpu_map: update script to handle versioned CPUs

2024-02-21 Thread Jonathon Jongsma

On 2/20/24 6:08 PM, Jim Fehlig wrote:

On 12/15/23 15:11, Jonathon Jongsma wrote:

Previously, the script only generated the parent CPU and any versions
that had a defined alias. The script now generates all CPU versions. Any
version that had a defined alias will continue to use that alias, but
those without aliases will use the generated name $BASECPUNAME-vN.

The reason for this change is two-fold. First, we need to add new models
that support new features (such as SEV-SNP). To deal with this, the
script now generates model definitions for all versions.

But we also need to ensure that our CPU definitions are migration-safe.
To deal with this issue we need to make sure we're always using the
canonical versioned names for CPUs.


Related to migration safety, do we need to be concerned with the 
expansion of 'host-model' CPU? E.g. is it possible 'host-model' expands 
to EPYC before introducing the new models, and EPYC-v4 afterwards? If 
so, what are the ramifications of that?


Indeed, that behavior is possible. In fact, you can see it happening in 
the test results for e.g. patch #5 ("Add versioned EPYC CPUs"). But I 
think that in general we should be fine, because we don't just expand to 
a plain model name, we expand to a model name plus a list of enabled or 
disabled feature flags.


For example, consider one test output file 
(tests/domaincapsdata/qemu_8.1.0-q35.x86_64.xml) that exhibits this 
behavior change. Before my patches the host CPU expanded to a model of 
'EPYC-ROME', with a number of feature flags which included (among others):


  
  

After my patches, the host model was expanded to 'EPYC-Rome-v4', with a 
slightly different set of feature flags. The main differences being that 
the 'amd-ssbd' and 'xsaves' features were no longer mentioned because 
they are now included in the -v4 definition. But it also adds a new 
feature flag to disable the 'ibrs' feature since this feature is 
included in the -v4 definition but not in the -v1 definition and is not 
provided by the host CPU:


  

So although the model name is changed, the definition of the host CPU as 
a whole should expand to the same set of CPU features.


I think that this sort of thing can happen every time a new CPU model is 
added (e.g. the -noTSX-IBRS variants), so I think it should work. But if 
anyone knows of any specific migration issues, please let me know.




Qemu documentation states that unversioned names for CPU models (e.g.
'EPYC') are actually aliases to a specific versioned CPU model (e.g.
'EPYC-v1'). The documentation further states that the specific version
targeted by the alias may change based on the machine type of the
domain. Management software such as libvirt is directed to translate
these aliases to a concrete version in order to make sure that the CPU
definition is safe when migrating between different qemu versions that
may make different choices for which underlying versioned model
represents the alias.


Do you have a link to the qemu documentation? Can it be added to the 
commit message?


Yes, I could certainly add a link to the commit message. It is mentioned 
here: 
https://www.qemu.org/docs/master/about/deprecated.html#runnability-guarantee-of-cpu-models-since-4-1





In practice, at the time of writing qemu always maps the unversioned
aliases to the -v1 model. And libvirt's CPU model definitions also
assume that this is the case. For example, the 'x86_EPYC.xml' file
contains the features that are defined for the EPYC-v1 inside of qemu.
But if qemu ever changes their alias mapping, libvirt's idea of what an
'EPYC' CPU means and qemu's idea of what an 'EPYC' CPU means will no
longer match. So when choosing a CPU model for a domain, we should
always pass the canonical versioned name to libvirt rather than the
unversioned alias. To enable this, the script will generate a new
'canonical_name' field to the CPU model xml definition.

Signed-off-by: Jonathon Jongsma 
---
  src/cpu_map/sync_qemu_models_i386.py | 42 ++--
  1 file changed, 34 insertions(+), 8 deletions(-)


The logic changes to the script LGTM.

Reviewed-by: Jim Fehlig 

Regards,
Jim



diff --git a/src/cpu_map/sync_qemu_models_i386.py 
b/src/cpu_map/sync_qemu_models_i386.py

index 1c6a2d4d27..7fd62eba4a 100755
--- a/src/cpu_map/sync_qemu_models_i386.py
+++ b/src/cpu_map/sync_qemu_models_i386.py
@@ -322,31 +322,55 @@ def expand_model(model):
  different fields and may have differing versions into several 
libvirt-

  friendly cpu models."""
-    result = {
-    "name": model.pop(".name"),
+    basename = model.pop(".name")
+    parent = {
+    "name": basename,
  "vendor": translate_vendor(model.pop(".vendor")),
  "features": set(),
  "extra": dict()}
  if ".family" in model and ".model" in model:
-    result["family"]

Re: [PATCH v3 12/12] nodedev: allow modify on define of a persistent node device

2024-02-21 Thread Jonathon Jongsma

On 2/16/24 8:52 AM, Boris Fiuczynski wrote:

Allow to modify a node device by using virNodeDeviceDefineXML() to align
its behavior with other drivers define methods.

Signed-off-by: Boris Fiuczynski 
---
  NEWS.rst |  5 +++
  src/libvirt-nodedev.c|  4 +-
  src/node_device/node_device_driver.c | 64 ++--
  tools/virsh-nodedev.c|  8 ++--
  4 files changed, 64 insertions(+), 17 deletions(-)

diff --git a/NEWS.rst b/NEWS.rst
index aa2fee3533..9b8b94dea4 100644
--- a/NEWS.rst
+++ b/NEWS.rst
@@ -32,6 +32,11 @@ v10.1.0 (unreleased)
  
  * **Improvements**
  
+* nodedev: Add ability to update persistent mediated devices by defining them

+
+Existing persistent mediated devices can now also be updated by
+``virNodeDeviceDefineXML()`` as long as parent and UUID remain unchanged.
+
  * **Bug fixes**
  
* qemu_process: Skip over non-virtio non-TAP NIC models when refreshing rx-filter

diff --git a/src/libvirt-nodedev.c b/src/libvirt-nodedev.c
index b97c199a3a..f242c0a8f6 100644
--- a/src/libvirt-nodedev.c
+++ b/src/libvirt-nodedev.c
@@ -780,7 +780,9 @@ virNodeDeviceDestroy(virNodeDevicePtr dev)
   * @xmlDesc: string containing an XML description of the device to be defined
   * @flags: bitwise-OR of supported virNodeDeviceDefineXMLFlags
   *
- * Define a new device on the VM host machine, for example, a mediated device
+ * Define a new inactive persistent device or modify an existing persistent
+ * one from the XML description on the VM host machine, for example, a mediated
+ * device.
   *
   * virNodeDeviceFree should be used to free the resources after the
   * node device object is no longer needed.
diff --git a/src/node_device/node_device_driver.c 
b/src/node_device/node_device_driver.c
index 11bc9af92e..66de46513d 100644
--- a/src/node_device/node_device_driver.c
+++ b/src/node_device/node_device_driver.c
@@ -1544,12 +1544,33 @@ nodeDeviceUpdateMediatedDevice(virNodeDeviceDef *def,
  }
  
  
+static virNodeDeviceObj*

+findPersistentMdevNodeDevice(virNodeDeviceDef *def)
+{
+virNodeDeviceObj *obj = NULL;
+
+if (!nodeDeviceHasCapability(def, VIR_NODE_DEV_CAP_MDEV) && !def->parent)
+return NULL;


These checks are duplicating checks that already exist in 
nodeDeviceDefineXML(). If we remove them, I'm not sure it's even worth 
factoring this out into a separate function.



+
+if (def->caps->data.mdev.uuid && def->caps->data.mdev.parent_addr) { > +   
 mdevGenerateDeviceName(def);


I don't like the fact that calling this function has the side-effect of 
(potentially) changing the name of the device definition by calling 
mdevGenerateDeviceName(). While you're only currently calling this 
function from one location where this won't cause any problems, I'd 
rather not make assumptions within the function. It'd be better to make 
sure that the name is set before calling this function (if you keep this 
as a separate function). Or better yet, just use 
virNodeDeviceObjListFindMediatedDeviceByUUID() so you don't even need to 
generate a name for lookup.




+if ((obj = nodeDeviceObjFindByName(def->name)) &&
+virNodeDeviceObjIsPersistent(obj))
+return obj;
+}
+
+return NULL;
+}
+
+
  virNodeDevice*
  nodeDeviceDefineXML(virConnect *conn,
  const char *xmlDesc,
  unsigned int flags)
  {
  g_autoptr(virNodeDeviceDef) def = NULL;
+virNodeDevicePtr new_nodedev = NULL;
+virNodeDeviceObj *persistent_obj = NULL;
  const char *virt_type = NULL;
  g_autofree char *uuid = NULL;
  g_autofree char *name = NULL;
@@ -1566,28 +1587,43 @@ nodeDeviceDefineXML(virConnect *conn,
>parserCallbacks, NULL, 
validate)))
  return NULL;
  
+persistent_obj = findPersistentMdevNodeDevice(def);

+
  if (virNodeDeviceDefineXMLEnsureACL(conn, def) < 0)
-return NULL;
+goto cleanup;
  
  if (!nodeDeviceHasCapability(def, VIR_NODE_DEV_CAP_MDEV)) {

  virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
 _("Unsupported device type"));
-return NULL;
+goto cleanup;
  }
  
  if (!def->parent) {

  virReportError(VIR_ERR_XML_ERROR, "%s",
 _("cannot define a mediated device without a parent"));
-return NULL;
+goto cleanup;
  }
  
-if (virMdevctlDefine(def, ) < 0) {

-return NULL;
-}
+if (persistent_obj) {
+// virNodeDeviceObjUpdateModificationImpact() is not required we will
+// modify the persitent config only.


typo: persitent -> persistent


+// nodeDeviceDefValidateUpdate() is not required as uuid and parent are
+// machting if def was found and changing the type in the persistent


typo: machting -> matching


+// config is allowed.
+VIR_DEBUG("Update node device '%s' with mdevctl", 

Re: [PATCH v3 07/12] tools: add switches persisted and transient to nodedev-list

2024-02-20 Thread Jonathon Jongsma
same as previous patch: commit subject says "persisted" instead of 
"persistent"


On 2/16/24 8:52 AM, Boris Fiuczynski wrote:

Now that we can filter persisted and transient node devices in
virConnectListAllNodeDevices(), add these switches also to the
virsh nodedev-list command.

Signed-off-by: Boris Fiuczynski 
Reviewed-by: Jonathon Jongsma 
---
  docs/manpages/virsh.rst |  8 ++--
  tools/virsh-nodedev.c   | 24 ++--
  2 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst
index 3a814dccd2..248807d0e9 100644
--- a/docs/manpages/virsh.rst
+++ b/docs/manpages/virsh.rst
@@ -5461,7 +5461,7 @@ nodedev-list
  
  ::
  
-   nodedev-list [--cap capability] [--tree] [--inactive | --all]

+   nodedev-list [--cap capability] [--tree] [--inactive | --all] [--persistent 
| --transient]
  
  List all of the devices available on the node that are known by libvirt.

  *cap* is used to filter the list by capability types, the types must be
@@ -5470,7 +5470,11 @@ separated by comma, e.g. --cap pci,scsi. Valid 
capability types include
  'scsi', 'storage', 'fc_host', 'vports', 'scsi_generic', 'drm', 'mdev',
  'mdev_types', 'ccw', 'css', 'ap_card', 'ap_queue', 'ap_matrix'. By default,
  only active devices are listed. *--inactive* is used to list only inactive
-devices, and *-all* is used to list both active and inactive devices.
+devices, and *--all* is used to list both active and inactive devices.
+*--persistent* is used to list only persistent devices, and *--transient* is
+used to list only transient devices. Not providing *--persistent* or
+*--transient* will list all devices unless filtered otherwise. *--transient*
+is mutually exclusive with *--persistent* and *--inactive*.
  If *--tree* is used, the output is formatted in a tree representing parents of
  each node.  *--tree* is mutually exclusive with all other options.
  
diff --git a/tools/virsh-nodedev.c b/tools/virsh-nodedev.c

index aeb3685aca..5942c43689 100644
--- a/tools/virsh-nodedev.c
+++ b/tools/virsh-nodedev.c
@@ -390,6 +390,14 @@ static const vshCmdOptDef opts_node_list_devices[] = {
   .type = VSH_OT_BOOL,
   .help = N_("list inactive & active devices")
  },
+{.name = "persistent",
+ .type = VSH_OT_BOOL,
+ .help = N_("list persistent devices")
+},
+{.name = "transient",
+ .type = VSH_OT_BOOL,
+ .help = N_("list transient devices")
+},
  {.name = NULL}
  };
  
@@ -407,6 +415,8 @@ cmdNodeListDevices(vshControl *ctl, const vshCmd *cmd G_GNUC_UNUSED)

  int cap_type = -1;
  bool inactive = vshCommandOptBool(cmd, "inactive");
  bool all = vshCommandOptBool(cmd, "all");
+bool persistent = vshCommandOptBool(cmd, "persistent");
+bool transient = vshCommandOptBool(cmd, "transient");
  
  ignore_value(vshCommandOptStringQuiet(ctl, cmd, "cap", _str));
  
@@ -420,8 +430,13 @@ cmdNodeListDevices(vshControl *ctl, const vshCmd *cmd G_GNUC_UNUSED)

  return false;
  }
  
-if (tree && (cap_str || inactive)) {

-vshError(ctl, "%s", _("Option --tree is incompatible with --cap and 
--inactive"));
+if (transient && (persistent || inactive)) {
+vshError(ctl, "%s", _("Option --transient is incompatible with --persistent 
and --inactive"));
+return false;
+}
+
+if (tree && (cap_str || inactive || persistent || transient)) {
+vshError(ctl, "%s", _("Option --tree is incompatible with --cap, 
--inactive, --persistent and --transient"));
  return false;
  }
  
@@ -509,6 +524,11 @@ cmdNodeListDevices(vshControl *ctl, const vshCmd *cmd G_GNUC_UNUSED)

  if (!inactive)
  flags |= VIR_CONNECT_LIST_NODE_DEVICES_ACTIVE;
  
+if (persistent)

+flags |= VIR_CONNECT_LIST_NODE_DEVICES_PERSISTENT;
+if (transient)
+flags |= VIR_CONNECT_LIST_NODE_DEVICES_TRANSIENT;
+
  if (!(list = virshNodeDeviceListCollect(ctl, caps, ncaps, flags))) {
  ret = false;
  goto cleanup;

___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [PATCH v3 06/12] nodedev: add persisted and transient filter on list

2024-02-20 Thread Jonathon Jongsma

Minor nit: the commit subject still says "persisted" instead of "persistent"

On 2/16/24 8:52 AM, Boris Fiuczynski wrote:

Allow to filter node devices based on their persisted or transient states.

Signed-off-by: Boris Fiuczynski 
Reviewed-by: Jonathon Jongsma 
---
  include/libvirt/libvirt-nodedev.h | 2 ++
  src/conf/node_device_conf.h   | 7 ++-
  src/conf/virnodedeviceobj.c   | 8 
  3 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/include/libvirt/libvirt-nodedev.h 
b/include/libvirt/libvirt-nodedev.h
index 53ffce6c69..f7ddbfa4ad 100644
--- a/include/libvirt/libvirt-nodedev.h
+++ b/include/libvirt/libvirt-nodedev.h
@@ -91,6 +91,8 @@ typedef enum {
  VIR_CONNECT_LIST_NODE_DEVICES_CAP_AP_MATRIX = 1 << 20, /* s390 AP 
Matrix (Since: 7.0.0) */
  VIR_CONNECT_LIST_NODE_DEVICES_CAP_VPD   = 1 << 21, /* Device with 
VPD (Since: 7.9.0) */
  
+VIR_CONNECT_LIST_NODE_DEVICES_PERSISTENT= 1 << 28, /* Persisted devices (Since: 10.1.0) */

+VIR_CONNECT_LIST_NODE_DEVICES_TRANSIENT = 1 << 29, /* Transient 
devices (Since: 10.1.0) */
  VIR_CONNECT_LIST_NODE_DEVICES_INACTIVE  = 1 << 30, /* Inactive 
devices (Since: 7.3.0) */
  VIR_CONNECT_LIST_NODE_DEVICES_ACTIVE= 1U << 31, /* Active 
devices (Since: 7.3.0) */
  } virConnectListAllNodeDeviceFlags;
diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h
index f59440dbb9..f0a5333881 100644
--- a/src/conf/node_device_conf.h
+++ b/src/conf/node_device_conf.h
@@ -432,9 +432,14 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(virNodeDevCapsDef, 
virNodeDevCapsDefFree);
  VIR_CONNECT_LIST_NODE_DEVICES_ACTIVE | \
  VIR_CONNECT_LIST_NODE_DEVICES_INACTIVE
  
+#define VIR_CONNECT_LIST_NODE_DEVICES_FILTERS_PERSISTENT \

+VIR_CONNECT_LIST_NODE_DEVICES_PERSISTENT | \
+VIR_CONNECT_LIST_NODE_DEVICES_TRANSIENT
+
  #define VIR_CONNECT_LIST_NODE_DEVICES_FILTERS_ALL \
  VIR_CONNECT_LIST_NODE_DEVICES_FILTERS_CAP | \
-VIR_CONNECT_LIST_NODE_DEVICES_FILTERS_ACTIVE
+VIR_CONNECT_LIST_NODE_DEVICES_FILTERS_ACTIVE | \
+VIR_CONNECT_LIST_NODE_DEVICES_FILTERS_PERSISTENT
  
  int

  virNodeDeviceGetSCSIHostCaps(virNodeDevCapSCSIHost *scsi_host);
diff --git a/src/conf/virnodedeviceobj.c b/src/conf/virnodedeviceobj.c
index cfef30d47e..31ec4249d8 100644
--- a/src/conf/virnodedeviceobj.c
+++ b/src/conf/virnodedeviceobj.c
@@ -911,6 +911,14 @@ virNodeDeviceObjMatch(virNodeDeviceObj *obj,
  return false;
  }
  
+if (flags & (VIR_CONNECT_LIST_NODE_DEVICES_FILTERS_PERSISTENT)) {

+if (!((MATCH(VIR_CONNECT_LIST_NODE_DEVICES_PERSISTENT) &&
+  virNodeDeviceObjIsPersistent(obj)) ||
+  (MATCH(VIR_CONNECT_LIST_NODE_DEVICES_TRANSIENT) &&
+   !virNodeDeviceObjIsPersistent(obj
+return false;
+}
+
  return true;
  }
  #undef MATCH

___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [PATCH v3 01/12] cpu_map: update script to handle versioned CPUs

2024-02-15 Thread Jonathon Jongsma

On 2/15/24 3:26 PM, Jim Fehlig wrote:

On 12/15/23 15:11, Jonathon Jongsma wrote:

Previously, the script only generated the parent CPU and any versions
that had a defined alias. The script now generates all CPU versions. Any
version that had a defined alias will continue to use that alias, but
those without aliases will use the generated name $BASECPUNAME-vN.

The reason for this change is two-fold. First, we need to add new models
that support new features (such as SEV-SNP). To deal with this, the
script now generates model definitions for all versions.

But we also need to ensure that our CPU definitions are migration-safe.
To deal with this issue we need to make sure we're always using the
canonical versioned names for CPUs.

Qemu documentation states that unversioned names for CPU models (e.g.
'EPYC') are actually aliases to a specific versioned CPU model (e.g.
'EPYC-v1'). The documentation further states that the specific version
targeted by the alias may change based on the machine type of the
domain. Management software such as libvirt is directed to translate
these aliases to a concrete version in order to make sure that the CPU
definition is safe when migrating between different qemu versions that
may make different choices for which underlying versioned model
represents the alias.

In practice, at the time of writing qemu always maps the unversioned
aliases to the -v1 model. And libvirt's CPU model definitions also
assume that this is the case. For example, the 'x86_EPYC.xml' file
contains the features that are defined for the EPYC-v1 inside of qemu.
But if qemu ever changes their alias mapping, libvirt's idea of what an
'EPYC' CPU means and qemu's idea of what an 'EPYC' CPU means will no
longer match. So when choosing a CPU model for a domain, we should
always pass the canonical versioned name to libvirt rather than the
unversioned alias. To enable this, the script will generate a new
'canonical_name' field to the CPU model xml definition.

Signed-off-by: Jonathon Jongsma 
---
  src/cpu_map/sync_qemu_models_i386.py | 42 ++--



I'm not familiar with this script and how to use it in practice. Same 
for it's companion sync_qemu_features_i386. How often are they run? Is 
it the developer's responsibility to sift through the results for 
commitable changes? I admit to not looking too hard, but couldn't find 
any documentation on how to use these tools.


Regards,
Jim



Yeah, there's not much documentation on this script. Here's the commit 
message from the initial commit of the script:


cpu_map: Add script to sync from QEMU i386 cpu models

This script is intended to help in synchronizing i386 QEMU cpu model
definitions with libvirt.

As the QEMU cpu model definitions are post processed by QEMU and not
meant to be consumed by third parties directly, parsing this
information is imperfect. Additionally, the libvirt models contain
information that cannot be generated from the QEMU data, preventing
fully automated usage. The output should nevertheless be helpful for
a human in determining potentially interesting changes.

So basically you just run
$ ./sync_qemu_models_i386.py /path/to/qemu/target/i386/cpu.c outdir

and it will spit out a bunch of generated cpu model definitions in 
outdir and you can compare them to what already exists.


Jonathon





  1 file changed, 34 insertions(+), 8 deletions(-)

diff --git a/src/cpu_map/sync_qemu_models_i386.py 
b/src/cpu_map/sync_qemu_models_i386.py

index 1c6a2d4d27..7fd62eba4a 100755
--- a/src/cpu_map/sync_qemu_models_i386.py
+++ b/src/cpu_map/sync_qemu_models_i386.py
@@ -322,31 +322,55 @@ def expand_model(model):
  different fields and may have differing versions into several 
libvirt-

  friendly cpu models."""
-    result = {
-    "name": model.pop(".name"),
+    basename = model.pop(".name")
+    parent = {
+    "name": basename,
  "vendor": translate_vendor(model.pop(".vendor")),
  "features": set(),
  "extra": dict()}
  if ".family" in model and ".model" in model:
-    result["family"] = model.pop(".family")
-    result["model"] = model.pop(".model")
+    parent["family"] = model.pop(".family")
+    parent["model"] = model.pop(".model")
  for k in [k for k in model if k.startswith(".features")]:
  v = model.pop(k)
  for feature in v.split():
  translated = translate_feature(feature)
  if translated:
-    result["features"].add(translated)
+    parent["features"].add(translated)
  versions = model.pop(".versions", [])
  for k, v in model.items():
-    result["extra"]["model" + k] = v
-    yield 

Re: [PATCH v3 00/12] Improve versioned CPU support in libvirt

2024-02-15 Thread Jonathon Jongsma

On 2/15/24 3:23 PM, Jim Fehlig wrote:

Hi Jonathon,

I don't have any expertise in this area of libvirt, but I have been 
experimenting with your patches and fairly recent snp-enabled 
kernel+ovmf+qemu referenced from AMD's AMDSEV repo


https://github.com/AMDESE/AMDSEV/blob/snp-latest/stable-commits

With your patches and 2 preliminarly SNP patches on top, I'm able to 
start SNP guests using



   EPYC-v4


A git branch containing the work on fairly recent libvirt.git master is 
here


https://gitlab.com/jfehlig/libvirt/-/tree/cpu-versions-plus-snp?ref_type=heads

I can take a closer look at the series when I return next week, but so 
far functional testing has been positive.


Regards,
Jim



Thanks for the feedback.

FYI, I do also have a WIP sev-snp branch for libvirt in my personal 
repository as well. I haven't posted any patches here yet because it's 
still in progress and because it builds on some qemu stuff that's not 
upstream yet (both the AMD repo and some coconut-svsm stuff). But it's 
here if you're interested:


https://gitlab.com/jjongsma/libvirt/-/tree/sev-snp?ref_type=heads

Jonathon





On 12/15/23 15:11, Jonathon Jongsma wrote:
For SEV-SNP support we will need to be able to specify versioned CPU 
models
that are not yet available in libvirt. Rather than just adding a 
versioned CPU

or two that would satisfy that immediate need, I decided to try to add
versioned CPUs in a more standard way. This series generates CPU 
definitions

for all cpu versions that are defined in upstream qemu (at least for
recent Intel and AMD CPUs).

libvirt already provides a select subset of these versions as 
configurable CPU
models. But we only include the ones that have defined aliases in 
qemu, such as
EPYC-IBPB. After this patchset, all verisioned cpu models supported by 
qemu

will be available in libvirt.

In addition to adding these new versioned models, based on feedback 
from Daniel
Berrange, I've also translated all CPU model aliases to a specific 
version when
specifying a CPU model to qemu. This means that we will no longer 
specify e.g.

'-cpu EPYC' to qemu, but will rather specify '-cpu EPYC-v1'

Changes in v3:
  - handle unversioned aliases

Changes in v2:
  - don't make any changes to existing CPU models
  - drop concept of aliases from libvirt and only provide new 
versioned models

    that aren't already available via their qemu alias.

Jonathon Jongsma (12):
   cpu_map: update script to handle versioned CPUs
   cpu_map: add canonical names to existing CPU models
   cpu: parse the canonical name from the cpu model
   qemu: use canonical name for CPU models
   cpu_map: Add versioned EPYC CPUs
   cpu_map: Add versioned Intel Skylake CPUs
   cpu_map: Add versioned Intel Cascadelake CPUs
   cpu_map: Add versioned Intel Icelake CPUs
   cpu_map: Add versioned Intel Cooperlake CPUs
   cpu_map: Add versioned Intel Snowridge CPUs
   cpu_map: Add versioned Intel SapphireRapids CPUs
   cpu_map: Add versioned Dhyana CPUs

  src/conf/cpu_conf.c   |   3 +
  src/conf/cpu_conf.h   |   1 +
  src/cpu/cpu_x86.c |  24 
  src/cpu_map/index.xml |  22 +++
  src/cpu_map/meson.build   |  22 +++
  src/cpu_map/sync_qemu_models_i386.py  |  42 --
  src/cpu_map/x86_Broadwell-IBRS.xml    |   1 +
  src/cpu_map/x86_Broadwell-noTSX-IBRS.xml  |   1 +
  src/cpu_map/x86_Broadwell-noTSX.xml   |   1 +
  src/cpu_map/x86_Broadwell.xml |   1 +
  src/cpu_map/x86_Cascadelake-Server-noTSX.xml  |   1 +
  src/cpu_map/x86_Cascadelake-Server-v2.xml |  93 +
  src/cpu_map/x86_Cascadelake-Server-v4.xml |  91 +
  src/cpu_map/x86_Cascadelake-Server-v5.xml |  92 +
  src/cpu_map/x86_Cascadelake-Server.xml    |   1 +
  src/cpu_map/x86_Cooperlake-v2.xml |  98 ++
  src/cpu_map/x86_Cooperlake.xml    |   1 +
  src/cpu_map/x86_Dhyana-v2.xml |  81 
  src/cpu_map/x86_Dhyana.xml    |   1 +
  src/cpu_map/x86_EPYC-IBPB.xml |   1 +
  src/cpu_map/x86_EPYC-Milan-v2.xml | 108 +++
  src/cpu_map/x86_EPYC-Milan.xml    |   1 +
  src/cpu_map/x86_EPYC-Rome-v2.xml  |  93 +
  src/cpu_map/x86_EPYC-Rome-v3.xml  |  95 +
  src/cpu_map/x86_EPYC-Rome-v4.xml  |  94 +
  src/cpu_map/x86_EPYC-Rome.xml |   1 +
  src/cpu_map/x86_EPYC-v3.xml   |  87 
  src/cpu_map/x86_EPYC-v4.xml   |  88 
  src/cpu_map/x86_EPYC.xml  |   1 +
  src/cpu_map/x86_Haswell-IBRS.xml  |   1 +
  src/cpu_map/x86_Haswell-noTSX-IBRS.xml    |   1 +
  src/cpu_map/x86_Haswell-noTSX.xml |   1 +
  src/cpu_map/x86_Haswell.xml   |   1 +
  src/cpu_map

Re: [PATCH v3 00/12] Improve versioned CPU support in libvirt

2024-02-15 Thread Jonathon Jongsma

Ping again.

On 1/11/24 3:02 PM, Jonathon Jongsma wrote:

polite ping


On 12/15/23 4:11 PM, Jonathon Jongsma wrote:
For SEV-SNP support we will need to be able to specify versioned CPU 
models
that are not yet available in libvirt. Rather than just adding a 
versioned CPU

or two that would satisfy that immediate need, I decided to try to add
versioned CPUs in a more standard way. This series generates CPU 
definitions

for all cpu versions that are defined in upstream qemu (at least for
recent Intel and AMD CPUs).

libvirt already provides a select subset of these versions as 
configurable CPU
models. But we only include the ones that have defined aliases in 
qemu, such as
EPYC-IBPB. After this patchset, all verisioned cpu models supported by 
qemu

will be available in libvirt.

In addition to adding these new versioned models, based on feedback 
from Daniel
Berrange, I've also translated all CPU model aliases to a specific 
version when
specifying a CPU model to qemu. This means that we will no longer 
specify e.g.

'-cpu EPYC' to qemu, but will rather specify '-cpu EPYC-v1'

Changes in v3:
  - handle unversioned aliases

Changes in v2:
  - don't make any changes to existing CPU models
  - drop concept of aliases from libvirt and only provide new 
versioned models

    that aren't already available via their qemu alias.

Jonathon Jongsma (12):
   cpu_map: update script to handle versioned CPUs
   cpu_map: add canonical names to existing CPU models
   cpu: parse the canonical name from the cpu model
   qemu: use canonical name for CPU models
   cpu_map: Add versioned EPYC CPUs
   cpu_map: Add versioned Intel Skylake CPUs
   cpu_map: Add versioned Intel Cascadelake CPUs
   cpu_map: Add versioned Intel Icelake CPUs
   cpu_map: Add versioned Intel Cooperlake CPUs
   cpu_map: Add versioned Intel Snowridge CPUs
   cpu_map: Add versioned Intel SapphireRapids CPUs
   cpu_map: Add versioned Dhyana CPUs

  src/conf/cpu_conf.c   |   3 +
  src/conf/cpu_conf.h   |   1 +
  src/cpu/cpu_x86.c |  24 
  src/cpu_map/index.xml |  22 +++
  src/cpu_map/meson.build   |  22 +++
  src/cpu_map/sync_qemu_models_i386.py  |  42 --
  src/cpu_map/x86_Broadwell-IBRS.xml    |   1 +
  src/cpu_map/x86_Broadwell-noTSX-IBRS.xml  |   1 +
  src/cpu_map/x86_Broadwell-noTSX.xml   |   1 +
  src/cpu_map/x86_Broadwell.xml |   1 +
  src/cpu_map/x86_Cascadelake-Server-noTSX.xml  |   1 +
  src/cpu_map/x86_Cascadelake-Server-v2.xml |  93 +
  src/cpu_map/x86_Cascadelake-Server-v4.xml |  91 +
  src/cpu_map/x86_Cascadelake-Server-v5.xml |  92 +
  src/cpu_map/x86_Cascadelake-Server.xml    |   1 +
  src/cpu_map/x86_Cooperlake-v2.xml |  98 ++
  src/cpu_map/x86_Cooperlake.xml    |   1 +
  src/cpu_map/x86_Dhyana-v2.xml |  81 
  src/cpu_map/x86_Dhyana.xml    |   1 +
  src/cpu_map/x86_EPYC-IBPB.xml |   1 +
  src/cpu_map/x86_EPYC-Milan-v2.xml | 108 +++
  src/cpu_map/x86_EPYC-Milan.xml    |   1 +
  src/cpu_map/x86_EPYC-Rome-v2.xml  |  93 +
  src/cpu_map/x86_EPYC-Rome-v3.xml  |  95 +
  src/cpu_map/x86_EPYC-Rome-v4.xml  |  94 +
  src/cpu_map/x86_EPYC-Rome.xml |   1 +
  src/cpu_map/x86_EPYC-v3.xml   |  87 
  src/cpu_map/x86_EPYC-v4.xml   |  88 
  src/cpu_map/x86_EPYC.xml  |   1 +
  src/cpu_map/x86_Haswell-IBRS.xml  |   1 +
  src/cpu_map/x86_Haswell-noTSX-IBRS.xml    |   1 +
  src/cpu_map/x86_Haswell-noTSX.xml |   1 +
  src/cpu_map/x86_Haswell.xml   |   1 +
  src/cpu_map/x86_Icelake-Server-noTSX.xml  |   1 +
  src/cpu_map/x86_Icelake-Server-v3.xml | 103 +++
  src/cpu_map/x86_Icelake-Server-v4.xml | 108 +++
  src/cpu_map/x86_Icelake-Server-v5.xml | 109 +++
  src/cpu_map/x86_Icelake-Server-v6.xml | 109 +++
  src/cpu_map/x86_Icelake-Server.xml    |   1 +
  src/cpu_map/x86_IvyBridge-IBRS.xml    |   1 +
  src/cpu_map/x86_IvyBridge.xml |   1 +
  src/cpu_map/x86_Nehalem-IBRS.xml  |   1 +
  src/cpu_map/x86_Nehalem.xml   |   1 +
  src/cpu_map/x86_SandyBridge-IBRS.xml  |   1 +
  src/cpu_map/x86_SandyBridge.xml   |   1 +
  src/cpu_map/x86_SapphireRapids-v2.xml | 125 ++
  src/cpu_map/x86_SapphireRapids.xml    |   1 +
  src/cpu_map/x86_Skylake-Client-IBRS.xml   |   1 +
  src/cpu_map/x86_Skylake-Client-noTSX-IBRS.xml |   1 +
  src/cpu_map/x86_Skylake-Client-v4.xml |  77 +++
  src/cpu_map/x86_Skylake-Client.xml

Re: [PATCH v2 09/11] api: add virNodeDeviceUpdate()

2024-02-15 Thread Jonathon Jongsma

On 2/15/24 3:29 AM, Boris Fiuczynski wrote:

On 2/14/24 19:00, Jonathon Jongsma wrote:

On 2/14/24 6:59 AM, Boris Fiuczynski wrote:

On 2/13/24 14:43, Boris Fiuczynski wrote:

Tangentially related:

Almost all of the other API objects can update their persistent 
definition from an XML file by calling the $(OBJECT)DefineXML 
command to replace the existing definition. The Node device API 
does not yet support doing that, maybe we should strive for a bit 
more API consistency here and implement that as well.


Clearly the DefineXML() API will only operate on a persistent 
definition, so if we want to provide a way to update a live device, 
we'll need a new API, which is presumably where this one comes in...


Correct.
I will take a look at how to align virNodeDeviceDefineXML


The current libvirt code does not prevent to define an existing mdev 
and does call mdevctl which reports that mdevctl cowardly refuses to 
overwrite the existing config as an internal error.


# virsh nodedev-define vfio-ccw-mdev-c60c_new-attr-set1.xml
error: Failed to define node device from 
'vfio-ccw-mdev-c60c_new-attr-set1.xml'
error: internal error: Unable to define mediated device: Error: 
Cowardly refusing to overwrite existing config for 
0.0.0008/c60cc60c-c60c-c60c-c60c-c60cc60cc60c


Instead of handling this in libvirt by detecting on define if a 
persistent config already exists and instead of calling 'mdevctl 
define' using 'mdevctl modify' for the update should mdevctl become 
brave by removing its refusal?




I don't think it would be a good idea to change the behavior of 
mdevctl at this point. But even if we did change mdevctl behavior, 
we'd still have to deal with older versions of mdevctl so we'd have to 
handle it in libvirt anyway.


Jonathon


What would have to change in libvirt to handle the current versions not 
allowing to overwrite the config?

The error above would remain for older medevctl versions.


You're right. If you don't care that older mdevctl versions don't work, 
you wouldn't need to do anything. But we should be able to very easily 
support the existing versions right now simply by checking whether the 
device is already defined and using 'modify' instead. And as I said, I 
don't currently intend to change mdevctl define behavior.


Jonathon
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [PATCH v2 10/11] nodedev: Implement virNodeDeviceUpdateXML

2024-02-14 Thread Jonathon Jongsma

On 2/13/24 3:04 AM, Boris Fiuczynski wrote:

On 2/9/24 23:45, Jonathon Jongsma wrote:

On 2/7/24 7:39 AM, Boris Fiuczynski wrote:

Implement the API functions in the node device driver by using
mdevctl modify with the options defined and live.
Instead of increasing the minimum mdevctl version to 1.3.0 in spec file
to ensure support exists in mdevctl the support is dynamically checked
before using mdevctl.

Signed-off-by: Boris Fiuczynski 
---
  NEWS.rst  |   7 +
  libvirt.spec.in   |   1 +
  src/node_device/node_device_driver.c  | 256 +-
  src/node_device/node_device_driver.h  |  11 +
  src/node_device/node_device_udev.c    |   1 +
  ...60c_c60c_c60c_c60c_c60cc60cc60c_update.xml |  16 ++
  tests/nodedevmdevctldata/mdevctl-modify.argv  |  25 ++
  tests/nodedevmdevctldata/mdevctl-modify.json  |   1 +
  tests/nodedevmdevctltest.c    |  90 +-
  9 files changed, 405 insertions(+), 3 deletions(-)
  create mode 100644 
tests/nodedevmdevctldata/mdev_c60cc60c_c60c_c60c_c60c_c60cc60cc60c_update.xml

  create mode 100644 tests/nodedevmdevctldata/mdevctl-modify.argv
  create mode 100644 tests/nodedevmdevctldata/mdevctl-modify.json

diff --git a/NEWS.rst b/NEWS.rst
index e2796fd8b2..aa2fee3533 100644
--- a/NEWS.rst
+++ b/NEWS.rst
@@ -17,6 +17,13 @@ v10.1.0 (unreleased)
  * **New features**
+  * nodedev: Support updating mdevs
+
+    The node device driver has been extended to allow updating 
mediated node
+    devices. Options are available to target the update against the 
persisted,

+    active or both configurations of an mediated device.
+    **Note:** The support is only available with at least mdevctl 
v1.3.0 installed.

+
    * qemu: Support clusters in CPU topology
  It is now possible to configure the guest CPU topology to use 
clusters.

diff --git a/libvirt.spec.in b/libvirt.spec.in
index 8413e3c19a..a8dff4a32e 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -613,6 +613,7 @@ Requires: libvirt-libs = %{version}-%{release}
  # needed for device enumeration
  Requires: systemd >= 185
  # For managing persistent mediated devices
+# Note: for nodedev-update support at least mdevctl v1.3.0 is required
  Requires: mdevctl
  # for modprobe of pci devices
  Requires: module-init-tools
diff --git a/src/node_device/node_device_driver.c 
b/src/node_device/node_device_driver.c

index baff49a0ae..5bece1a30a 100644
--- a/src/node_device/node_device_driver.c
+++ b/src/node_device/node_device_driver.c
@@ -54,7 +54,7 @@ virNodeDeviceDriverState *driver;
  VIR_ENUM_IMPL(virMdevctlCommand,
    MDEVCTL_CMD_LAST,
-  "start", "stop", "define", "undefine", "create"
+  "start", "stop", "define", "undefine", "create", "modify"
  );
@@ -754,6 +754,7 @@ nodeDeviceGetMdevctlCommand(virNodeDeviceDef *def,
  case MDEVCTL_CMD_START:
  case MDEVCTL_CMD_DEFINE:
  case MDEVCTL_CMD_UNDEFINE:
+    case MDEVCTL_CMD_MODIFY:
  cmd = virCommandNewArgList(MDEVCTL, subcommand, NULL);
  break;
  case MDEVCTL_CMD_LAST:
@@ -767,6 +768,7 @@ nodeDeviceGetMdevctlCommand(virNodeDeviceDef *def,
  switch (cmd_type) {
  case MDEVCTL_CMD_CREATE:
  case MDEVCTL_CMD_DEFINE:
+    case MDEVCTL_CMD_MODIFY:
  if (!def->caps->data.mdev.parent_addr) {
  virReportError(VIR_ERR_INTERNAL_ERROR,
 _("unable to find parent device 
'%1$s'"), def->parent);

@@ -783,7 +785,8 @@ nodeDeviceGetMdevctlCommand(virNodeDeviceDef *def,
  virCommandAddArgPair(cmd, "--jsonfile", "/dev/stdin");
  virCommandSetInputBuffer(cmd, inbuf);
-    virCommandSetOutputBuffer(cmd, outbuf);
+    if (outbuf)
+    virCommandSetOutputBuffer(cmd, outbuf);
  break;
  case MDEVCTL_CMD_UNDEFINE:
@@ -868,6 +871,100 @@ virMdevctlDefine(virNodeDeviceDef *def, char 
**uuid)

  }
+/* gets a virCommand object that executes a mdevctl command to modify a
+ * a device to an updated version
+ */
+virCommand*
+nodeDeviceGetMdevctlModifyCommand(virNodeDeviceDef *def,
+  bool defined,
+  bool live,
+  char **errmsg)
+{
+    virCommand *cmd = nodeDeviceGetMdevctlCommand(def,
+  MDEVCTL_CMD_MODIFY,
+  NULL, errmsg);
+
+    if (!cmd)
+    return NULL;
+
+    if (defined)
+    virCommandAddArg(cmd, "--defined");
+
+    if (live)
+    virCommandAddArg(cmd, "--live");
+
+    return cmd;
+}
+
+
+/* checks if mdevctl supports on the command modify the options 
live, defined

+ * and jsonfile
+ */
+static int
+nodeDeviceGetMdevctlModifySupportCheck(void)
+{

Re: [PATCH v2 09/11] api: add virNodeDeviceUpdate()

2024-02-14 Thread Jonathon Jongsma

On 2/14/24 6:59 AM, Boris Fiuczynski wrote:

On 2/13/24 14:43, Boris Fiuczynski wrote:

Tangentially related:

Almost all of the other API objects can update their persistent 
definition from an XML file by calling the $(OBJECT)DefineXML command 
to replace the existing definition. The Node device API does not yet 
support doing that, maybe we should strive for a bit more API 
consistency here and implement that as well.


Clearly the DefineXML() API will only operate on a persistent 
definition, so if we want to provide a way to update a live device, 
we'll need a new API, which is presumably where this one comes in...


Correct.
I will take a look at how to align virNodeDeviceDefineXML


The current libvirt code does not prevent to define an existing mdev and 
does call mdevctl which reports that mdevctl cowardly refuses to 
overwrite the existing config as an internal error.


# virsh nodedev-define vfio-ccw-mdev-c60c_new-attr-set1.xml
error: Failed to define node device from 
'vfio-ccw-mdev-c60c_new-attr-set1.xml'
error: internal error: Unable to define mediated device: Error: Cowardly 
refusing to overwrite existing config for 
0.0.0008/c60cc60c-c60c-c60c-c60c-c60cc60cc60c


Instead of handling this in libvirt by detecting on define if a 
persistent config already exists and instead of calling 'mdevctl define' 
using 'mdevctl modify' for the update should mdevctl become brave by 
removing its refusal?




I don't think it would be a good idea to change the behavior of mdevctl 
at this point. But even if we did change mdevctl behavior, we'd still 
have to deal with older versions of mdevctl so we'd have to handle it in 
libvirt anyway.


Jonathon
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [PATCH v2 10/11] nodedev: Implement virNodeDeviceUpdateXML

2024-02-09 Thread Jonathon Jongsma
ctlModifyCommand(def_update, true, true, 
)))
+goto cleanup;
+
+if (virCommandRun(bothcmd, NULL) < 0)
+goto cleanup;
+
+if (!(actualCmdline = virBufferCurrentContent()))
+goto cleanup;
+
+if (virTestCompareToFileFull(actualCmdline, cmdlinefile, false) < 0)
+goto cleanup;
+
+if (virTestCompareToFile(stdinbuf, jsonfile) < 0)
+goto cleanup;
+
+ret = 0;
+
+ cleanup:
+virBufferFreeAndReset();
+return ret;
+}
+
  static int
  testMdevctlListDefined(const void *data G_GNUC_UNUSED)
  {
@@ -457,6 +540,9 @@ mymain(void)
  #define DO_TEST_AUTOSTART() \
  DO_TEST_FULL("autostart mdevs", testMdevctlAutostart, NULL)
  
+#define DO_TEST_MODIFY() \

+DO_TEST_FULL("modify mdevs", testMdevctlModify, NULL)
+
  #define DO_TEST_PARSE_JSON(filename) \
  DO_TEST_FULL("parse mdevctl json " filename, testMdevctlParse, filename)
  
@@ -485,6 +571,8 @@ mymain(void)
  
  DO_TEST_AUTOSTART();
  
+DO_TEST_MODIFY();

+
   done:
  nodedevTestDriverFree(driver);
  


Reviewed-by: Jonathon Jongsma 
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [PATCH v2 09/11] api: add virNodeDeviceUpdate()

2024-02-09 Thread Jonathon Jongsma

On 2/7/24 7:39 AM, Boris Fiuczynski wrote:

This public API is implemented for almost all other objects that have
a concept of persistent definition and activatability. Node devices
(mdevs) that can be defined and inactive, it will be useful to be
able to update defined and active node devices as well.


It looks like my previous comment on this patch might not have been sent 
to the list, so I'll repeat it here:


In the commit summary, you talk about virNodeDeviceUpdate(), however, in 
the code you actually name the function virNodeDeviceUpdateXML(). There 
are no other public objects that provide a $(OBJECT)UpdateXML() 
function. The only other object that has a similar API is 
virNetworkUpdate(). That doesn't seem to match your claim that "this 
public API is implemented for almost all other objects...". What API 
were you referring to exactly? I think for API consistency, perhaps the 
Update() name is better than UpdateXML() to match virNetworkUpdate()? 
Regardless, the commit message should match the function name.


Tangentially related:

Almost all of the other API objects can update their persistent 
definition from an XML file by calling the $(OBJECT)DefineXML command to 
replace the existing definition. The Node device API does not yet 
support doing that, maybe we should strive for a bit more API 
consistency here and implement that as well.


Clearly the DefineXML() API will only operate on a persistent 
definition, so if we want to provide a way to update a live device, 
we'll need a new API, which is presumably where this one comes in...




Signed-off-by: Boris Fiuczynski 
---
  include/libvirt/libvirt-nodedev.h | 18 +
  src/access/viraccessperm.c|  1 +
  src/access/viraccessperm.h|  6 +
  src/conf/virnodedeviceobj.c   | 42 +
  src/conf/virnodedeviceobj.h   |  3 +++
  src/driver-nodedev.h  |  6 +
  src/libvirt-nodedev.c | 45 +++
  src/libvirt_private.syms  |  1 +
  src/libvirt_public.syms   |  5 
  src/remote/remote_driver.c|  1 +
  src/remote/remote_protocol.x  | 17 +++-
  src/remote_protocol-structs   |  6 +
  12 files changed, 150 insertions(+), 1 deletion(-)

diff --git a/include/libvirt/libvirt-nodedev.h 
b/include/libvirt/libvirt-nodedev.h
index f7ddbfa4ad..de1d5bcbc1 100644
--- a/include/libvirt/libvirt-nodedev.h
+++ b/include/libvirt/libvirt-nodedev.h
@@ -188,6 +188,24 @@ int virNodeDeviceIsPersistent(virNodeDevicePtr dev);
  
  int virNodeDeviceIsActive(virNodeDevicePtr dev);
  
+/**

+ * virNodeDeviceUpdateXMLFlags:
+ *
+ * Flags to control options for virNodeDeviceUpdateXML()
+ *
+ * Since: 10.1.0
+ */
+typedef enum {
+VIR_NODE_DEVICE_UPDATE_XML_AFFECT_CURRENT = 0,  /* affect live if node 
device is active,
+   config if it's not 
active (Since: 10.1.0) */
+VIR_NODE_DEVICE_UPDATE_XML_AFFECT_LIVE= 1 << 0, /* affect live state 
of node device only (Since: 10.1.0) */
+VIR_NODE_DEVICE_UPDATE_XML_AFFECT_CONFIG  = 1 << 1, /* affect persistent 
config only (Since: 10.1.0) */
+} virNodeDeviceUpdateXMLFlags;
+
+int virNodeDeviceUpdateXML(virNodeDevicePtr dev,
+   const char *xmlDesc,
+   unsigned int flags);
+
  /**
   * VIR_NODE_DEVICE_EVENT_CALLBACK:
   *
diff --git a/src/access/viraccessperm.c b/src/access/viraccessperm.c
index d4a0c98b9b..702bee761d 100644
--- a/src/access/viraccessperm.c
+++ b/src/access/viraccessperm.c
@@ -71,6 +71,7 @@ VIR_ENUM_IMPL(virAccessPermNodeDevice,
"getattr", "read", "write",
"start", "stop",
"detach", "delete",
+  "save",
  );
  
  VIR_ENUM_IMPL(virAccessPermNWFilter,

diff --git a/src/access/viraccessperm.h b/src/access/viraccessperm.h
index 2f04459ed9..6cc2140c67 100644
--- a/src/access/viraccessperm.h
+++ b/src/access/viraccessperm.h
@@ -507,6 +507,12 @@ typedef enum {
   */
  VIR_ACCESS_PERM_NODE_DEVICE_DELETE,
  
+/**

+ * @desc: Save node device
+ * @message: Saving node device driver requires authorization
+ */
+VIR_ACCESS_PERM_NODE_DEVICE_SAVE,
+
  VIR_ACCESS_PERM_NODE_DEVICE_LAST
  } virAccessPermNodeDevice;
  
diff --git a/src/conf/virnodedeviceobj.c b/src/conf/virnodedeviceobj.c

index 31ec4249d8..a8b1b625a7 100644
--- a/src/conf/virnodedeviceobj.c
+++ b/src/conf/virnodedeviceobj.c
@@ -1137,3 +1137,45 @@ virNodeDeviceObjListFind(virNodeDeviceObjList *devs,
virNodeDeviceObjListFindHelper,
);
  }
+
+
+/**
+ * virNodeDeviceObjUpdateModificationImpact:
+ * @obj: Pointer to node device object
+ * @flags: flags to update the modification impact on
+ *
+ * Resolves virNodeDeviceObjUpdateModificationImpact flags in @flags so that
+ * they correctly apply to the actual state of @obj. @flags 

Re: [PATCH 2/3] qemu: roll back if not all nbdkit backends are successful

2024-02-08 Thread Jonathon Jongsma

On 1/29/24 2:30 AM, Peter Krempa wrote:

On Thu, Jan 25, 2024 at 14:52:10 -0600, Jonathon Jongsma wrote:

When starting nbdkit processes for the backing store of a disk, we were
returning an error if any backing store failed, but we were not cleaning
up processes that succeeded higher in the chain. Make sure that if we
return a failure status from qemuNbdkitStartStorageSource() that we roll
back any processes that had been started.


qemuNbdkitStartStorageSource is called from:

src/qemu/qemu_extdevice.c=qemuExtDevicesStart(virQEMUDriver *driver,
src/qemu/qemu_extdevice.c:if (qemuNbdkitStartStorageSource(driver, vm, 
disk->src, true) < 0)
src/qemu/qemu_extdevice.c:if (qemuNbdkitStartStorageSource(driver, vm, 
def->os.loader->nvram, true) < 0)

The counterpart is qemuExtDevicesStop.

src/qemu/qemu_hotplug.c=qemuDomainAttachDeviceDiskLiveInternal(virQEMUDriver 
*driver,
src/qemu/qemu_hotplug.c:if (qemuNbdkitStartStorageSource(driver, vm, 
disk->src, true) < 0)

This has cleanup inline.

Thus I don't see a possibility where what you describe in the commit
message can happen.


Oops it seems that i never actually responded to this comment. Perhaps 
because I was waiting for a resolution on patch 3.


The motivation for this patch was actually in anticipation of patch 3. 
In that patch, I followed the existing pattern inside of 
qemuDomainStorageSourceAccessModify() where we only set a 'revoke_foo' 
variable if the initial 'allow' call succeeds. In other words, if a 
function like qemuDomainStorageSourceAccessModifyNVMe() fails, we assume 
that it has left things in a consistent state and doesn't need to be 
revoked in the error path. So I followed the same pattern for this function.


If you think it would be better, I could just squash this patch with 
patch 3?


Jonathon





Signed-off-by: Jonathon Jongsma 
---
  src/qemu/qemu_nbdkit.c | 5 -
  1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/qemu/qemu_nbdkit.c b/src/qemu/qemu_nbdkit.c
index 39f9c58a48..edbe2137d0 100644
--- a/src/qemu/qemu_nbdkit.c
+++ b/src/qemu/qemu_nbdkit.c
@@ -920,8 +920,11 @@ qemuNbdkitStartStorageSource(virQEMUDriver *driver,
  return qemuNbdkitStartStorageSourceOne(driver, vm, src);
  
  for (backing = src; backing != NULL; backing = backing->backingStore) {

-if (qemuNbdkitStartStorageSourceOne(driver, vm, backing) < 0)
+if (qemuNbdkitStartStorageSourceOne(driver, vm, backing) < 0) {
+/* roll back any previously-started sources */
+qemuNbdkitStopStorageSource(src, vm, true);
  return -1;
+}
  }
  
  return 0;

--
2.43.0
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org



___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [PATCH 10/11] nodedev: Implement virNodeDeviceUpdateXML

2024-02-01 Thread Jonathon Jongsma

On 2/1/24 11:07 AM, Boris Fiuczynski wrote:

On 1/31/24 22:41, Jonathon Jongsma wrote:

On 1/19/24 10:38 AM, Boris Fiuczynski wrote:

Implement the API functions in the node device driver by using
mdevctl modify with the options defined and live.
Increase the minimum mdevctl version to 1.3.0 in spec file to ensure
support exists in mdevctl.


mdevctl 1.3.0 was only released about 3 weeks ago, so I don't think we 
can add an unconditional dependency on it. I think we'll have to make 
sure that we can degrade gracefully when the required version isn't 
available.


What is your suggestion?
1) Adding a mdevctl version check to the runtime code, which in general 
can cause trouble interpreting the verion number with regard to distro 
backports.
2) Before really calling modify find out if mdevctl supports it by 
issuing e.g. "mdevctl modify --live --help". If live is support the RC 
is 0 if it is not supported the RC is 2.

3) Something else?



Hmm, I was thinking that we only needed the 1.3.0 version for the --live 
and --defined options, but I now realize that we also need the 
--jsonfile argument from 1.3.0. That makes it a bit harder to degrade 
gracefully.


However, even if 1.3.0 is installed, not all devices will be able to be 
live-updated. So we need to handle errors in command execution 
regardless. If the user has an older mdevctl, the command will return an 
error and the user will be unable to update an mdev via the new API, 
which is the same behavior as they had before this patch. If the user 
has a newer mdevctl, it will just work. Maybe that's good enough for now.


Jonathon








Signed-off-by: Boris Fiuczynski 
---
  libvirt.spec.in  |   2 +-
  src/node_device/node_device_driver.c | 181 ++-
  src/node_device/node_device_driver.h |  11 ++
  src/node_device/node_device_udev.c   |   1 +
  tests/nodedevmdevctldata/mdevctl-modify.argv |  19 ++
  tests/nodedevmdevctltest.c   |  64 +++
  6 files changed, 275 insertions(+), 3 deletions(-)
  create mode 100644 tests/nodedevmdevctldata/mdevctl-modify.argv

diff --git a/libvirt.spec.in b/libvirt.spec.in
index 8413e3c19a..3ed14fa63c 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -613,7 +613,7 @@ Requires: libvirt-libs = %{version}-%{release}
  # needed for device enumeration
  Requires: systemd >= 185
  # For managing persistent mediated devices
-Requires: mdevctl
+Requires: mdevctl >= 1.3.0
  # for modprobe of pci devices
  Requires: module-init-tools
diff --git a/src/node_device/node_device_driver.c 
b/src/node_device/node_device_driver.c

index d67c95d68d..dd57e9ca5b 100644
--- a/src/node_device/node_device_driver.c
+++ b/src/node_device/node_device_driver.c
@@ -54,7 +54,7 @@ virNodeDeviceDriverState *driver;
  VIR_ENUM_IMPL(virMdevctlCommand,
    MDEVCTL_CMD_LAST,
-  "start", "stop", "define", "undefine", "create"
+  "start", "stop", "define", "undefine", "create", "modify"
  );
@@ -754,6 +754,7 @@ nodeDeviceGetMdevctlCommand(virNodeDeviceDef *def,
  case MDEVCTL_CMD_START:
  case MDEVCTL_CMD_DEFINE:
  case MDEVCTL_CMD_UNDEFINE:
+    case MDEVCTL_CMD_MODIFY:
  cmd = virCommandNewArgList(MDEVCTL, subcommand, NULL);
  break;
  case MDEVCTL_CMD_LAST:
@@ -767,6 +768,7 @@ nodeDeviceGetMdevctlCommand(virNodeDeviceDef *def,
  switch (cmd_type) {
  case MDEVCTL_CMD_CREATE:
  case MDEVCTL_CMD_DEFINE:
+    case MDEVCTL_CMD_MODIFY:
  if (!def->caps->data.mdev.parent_addr) {
  virReportError(VIR_ERR_INTERNAL_ERROR,
 _("unable to find parent device 
'%1$s'"), def->parent);

@@ -783,7 +785,8 @@ nodeDeviceGetMdevctlCommand(virNodeDeviceDef *def,
  virCommandAddArgPair(cmd, "--jsonfile", "/dev/stdin");
  virCommandSetInputBuffer(cmd, inbuf);
-    virCommandSetOutputBuffer(cmd, outbuf);
+    if (outbuf)
+    virCommandSetOutputBuffer(cmd, outbuf);
  break;
  case MDEVCTL_CMD_UNDEFINE:
@@ -868,6 +871,61 @@ virMdevctlDefine(virNodeDeviceDef *def, char 
**uuid)

  }
+/* gets a virCommand object that executes a mdevctl command to modify a
+ * a device to an updated version
+ */
+virCommand*
+nodeDeviceGetMdevctlModifyCommand(virNodeDeviceDef *def,
+  bool defined,
+  bool live,
+  char **errmsg)
+{
+    virCommand *cmd = nodeDeviceGetMdevctlCommand(def,
+  MDEVCTL_CMD_MODIFY,
+  NULL, errmsg);
+
+    if (!cmd)
+    return NULL;
+
+    if (defined)
+    virCommandAddArg(cmd, "--defined");
+
+    if (live)
+    virCommandAddArg

Re: [PATCH 05/11] tools: add option inactive to nodedev-dumpxml

2024-02-01 Thread Jonathon Jongsma

On 2/1/24 8:35 AM, Boris Fiuczynski wrote:

On 1/31/24 22:34, Jonathon Jongsma wrote:

On 1/19/24 10:38 AM, Boris Fiuczynski wrote:

Allow to dump the XML of the persisted mdev when the mdev has been
started instead of the current state only.

Signed-off-by: Boris Fiuczynski 
---
  docs/manpages/virsh.rst |  7 +--
  tools/virsh-nodedev.c   | 15 ++-
  2 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst
index ed1027e133..3a814dccd2 100644
--- a/docs/manpages/virsh.rst
+++ b/docs/manpages/virsh.rst
@@ -5422,14 +5422,17 @@ nodedev-dumpxml
  ::
-   nodedev-dumpxml [--xpath EXPRESSION] [--wrap] device
+   nodedev-dumpxml [--inactive] [--xpath EXPRESSION] [--wrap] device
  Dump a  XML representation for the given node device, 
including

  such information as the device name, which bus owns the device, the
  vendor and product id, and any capabilities of the device usable by
  libvirt (such as whether device reset is supported). *device* can
  be either device name or wwn pair in "wwnn,wwpn" format (only works
-for HBA).
+for HBA). An additional option affecting the XML dump may be
+used. *--inactive* tells virsh to dump the node device configuration
+that will be used on next start of the node device as opposed to the
+current node device configuration.
  If the **--xpath** argument provides an XPath expression, it will be
  evaluated against the output XML and only those matching nodes will
diff --git a/tools/virsh-nodedev.c b/tools/virsh-nodedev.c
index fb38fd7fcc..54e192d619 100644
--- a/tools/virsh-nodedev.c
+++ b/tools/virsh-nodedev.c
@@ -575,6 +575,10 @@ static const vshCmdOptDef 
opts_node_device_dumpxml[] = {

   .help = N_("device name or wwn pair in 'wwnn,wwpn' format"),
   .completer = virshNodeDeviceNameCompleter,
  },
+    {.name = "inactive",
+ .type = VSH_OT_BOOL,
+ .help = N_("show inactive defined XML"),
+    },
  {.name = "xpath",
   .type = VSH_OT_STRING,
   .flags = VSH_OFLAG_REQ_OPT,
@@ -594,6 +598,7 @@ cmdNodeDeviceDumpXML(vshControl *ctl, const 
vshCmd *cmd)

  g_autoptr(virshNodeDevice) device = NULL;
  g_autofree char *xml = NULL;
  const char *device_value = NULL;
+    unsigned int flags = 0;
  bool wrap = vshCommandOptBool(cmd, "wrap");
  const char *xpath = NULL;
@@ -608,7 +613,15 @@ cmdNodeDeviceDumpXML(vshControl *ctl, const 
vshCmd *cmd)

  if (!device)
  return false;
-    if (!(xml = virNodeDeviceGetXMLDesc(device, 0)))
+    if (vshCommandOptBool(cmd, "inactive")) {
+    flags |= VIR_NODE_DEVICE_GET_XML_DESC_INACTIVE;
+    if (!virNodeDeviceIsPersistent(device)) {
+    vshError(ctl, _("Node device '%1$s' is not persistent"), 
device_value);

+    return false;
+    }


I believe you've already handled this within virNodeDeviceGetXMLDesc() 
in patch 4. There shouldn't be any need to duplicate that check here.




Without the check in the client the error message looks like this:
# virsh nodedev-dumpxml --inactive 
mdev_c60cc60c_c60c_c60c_c60c_c60cc60cc60c_0_0_0008
error: Requested operation is not valid: node device 
'mdev_c60cc60c_c60c_c60c_c60c_c60cc60cc60c_0_0_0008' is not persistent


I added the additional check in the virsh client to create a user 
friendlier message looking like this:
# virsh nodedev-dumpxml --inactive 
mdev_c60cc60c_c60c_c60c_c60c_c60cc60cc60c_0_0_0008
error: Node device 'mdev_c60cc60c_c60c_c60c_c60c_c60cc60cc60c_0_0_0008' 
is not persistent


Do you want it removed?


I think the first error message is fine, and it's more maintainable to 
not keep the precondition checks within the function itself.





+    }
+
+    if (!(xml = virNodeDeviceGetXMLDesc(device, flags)))
  return false;
  return virshDumpXML(ctl, xml, "node-device", xpath, wrap);


Reviewed-by: Jonathon Jongsma 


Thanks


___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org



___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [PATCH] virt-admin: Add warning when connection to default daemon fails

2024-02-01 Thread Jonathon Jongsma

On 2/1/24 9:35 AM, Peter Krempa wrote:

The admin connection defaults to the system-wide 'libvirtd' daemon to
manage (libvirtd:///system). As we've now switched to modular daemons
this will not work for most users out of the box:

  $ virt-admin version
  error: Failed to connect to the admin server
  error: no valid connection
  error: Failed to connect socket to 
'/run/user/1000/libvirt/libvirt-admin-sock': No such file or directory

As we don't want to assume which daemon the user wants to manage in the
modular topology there's no reasonable default to pick.

Give a hint to the users to use the '-c' if the connection to the
default URI fails:

  $ virt-admin version
  NOTE: Connecting to default daemon. Specify daemon using '-c' (e.g. 
virtqemud:///system)
  error: Failed to connect to the admin server
  error: no valid connection
  error: Failed to connect socket to 
'/run/user/1000/libvirt/libvirt-admin-sock': No such file or directory

Signed-off-by: Peter Krempa 
---
  tools/virt-admin.c | 3 +++
  1 file changed, 3 insertions(+)

diff --git a/tools/virt-admin.c b/tools/virt-admin.c
index fa9304c772..aaf6edb9a9 100644
--- a/tools/virt-admin.c
+++ b/tools/virt-admin.c
@@ -102,6 +102,9 @@ vshAdmConnect(vshControl *ctl, unsigned int flags)
  priv->conn = virAdmConnectOpen(ctl->connname, flags);

  if (!priv->conn) {
+if (!ctl->connname)
+vshPrintExtra(ctl, "%s", _("NOTE: Connecting to default daemon. Specify 
daemon using '-c' (e.g. virtqemud:///system)\n"));
+
  if (priv->wantReconnect)
  vshError(ctl, "%s", _("Failed to reconnect to the admin server"));
  else



Reviewed-by: Jonathon Jongsma 
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [PATCH 04/11] nodedev: add an active config to mdev

2024-02-01 Thread Jonathon Jongsma

On 2/1/24 6:17 AM, Boris Fiuczynski wrote:

On 1/31/24 22:30, Jonathon Jongsma wrote:

On 1/19/24 10:38 AM, Boris Fiuczynski wrote:

The configuration of a defined mdev can be modified after the mdev is
started. The defined configuration and the active configuration can
therefore run out of sync. Handle this by storing the modifiable data
which is the mdev type and attributes in two separate active and
defined configurations.  mdevctl supports with callout scripts to do an
attribute retrieval of started mdevs which is already implemented in
libvirt.

Signed-off-by: Boris Fiuczynski 
---
  include/libvirt/libvirt-nodedev.h | 11 
  src/conf/node_device_conf.c   | 53 ++--
  src/conf/node_device_conf.h   |  5 +-
  src/libvirt-nodedev.c |  2 +-
  src/node_device/node_device_driver.c  | 61 +--
  src/node_device/node_device_driver.h  |  6 +-
  src/node_device/node_device_udev.c    |  4 +-
  src/test/test_driver.c    |  6 +-
  tests/nodedevmdevctltest.c    |  4 +-
  ...v_c60cc60c_c60c_c60c_c60c_c60cc60cc60c.xml | 14 +
  ...d_b7f0_4fea_b468_f1da537d301b_inactive.xml |  1 +
  ...v_c60cc60c_c60c_c60c_c60c_c60cc60cc60c.xml | 10 +++
  ...c_c60c_c60c_c60c_c60cc60cc60c_inactive.xml |  9 +++
  ...9_36ea_4111_8f0a_8c9a70e21366_inactive.xml |  1 +
  ...9_495e_4243_ad9f_beb3f14c23d9_inactive.xml |  1 +
  ...4_f554_4dc1_809d_b2a01e8e48ad_inactive.xml |  8 +++
  ...6_1ca8_49ac_b176_871d16c13076_inactive.xml |  1 +
  tests/nodedevxml2xmltest.c    | 59 +++---
  18 files changed, 197 insertions(+), 59 deletions(-)
  create mode 100644 
tests/nodedevschemadata/mdev_c60cc60c_c60c_c60c_c60c_c60cc60cc60c.xml
  create mode 12 
tests/nodedevxml2xmlout/mdev_3627463d_b7f0_4fea_b468_f1da537d301b_inactive.xml
  create mode 100644 
tests/nodedevxml2xmlout/mdev_c60cc60c_c60c_c60c_c60c_c60cc60cc60c.xml
  create mode 100644 
tests/nodedevxml2xmlout/mdev_c60cc60c_c60c_c60c_c60c_c60cc60cc60c_inactive.xml
  create mode 12 
tests/nodedevxml2xmlout/mdev_d069d019_36ea_4111_8f0a_8c9a70e21366_inactive.xml
  create mode 12 
tests/nodedevxml2xmlout/mdev_d2441d39_495e_4243_ad9f_beb3f14c23d9_inactive.xml
  create mode 100644 
tests/nodedevxml2xmlout/mdev_ee0b88c4_f554_4dc1_809d_b2a01e8e48ad_inactive.xml
  create mode 12 
tests/nodedevxml2xmlout/mdev_fedc4916_1ca8_49ac_b176_871d16c13076_inactive.xml


diff --git a/include/libvirt/libvirt-nodedev.h 
b/include/libvirt/libvirt-nodedev.h

index 428b0d722f..d18246e2f6 100644
--- a/include/libvirt/libvirt-nodedev.h
+++ b/include/libvirt/libvirt-nodedev.h
@@ -117,6 +117,17 @@ int virNodeDeviceListCaps 
(virNodeDevicePtr dev,

    char **const names,
    int maxnames);
+/**
+ * virNodeDeviceGetXMLDescFlags:
+ *
+ * Flags used to provide the state of the returned node device 
configuration.

+ *
+ * Since: 10.1.0
+ */
+typedef enum {
+    VIR_NODE_DEVICE_GET_XML_DESC_INACTIVE    = 1 << 0, /* 
dump inactive device configuration (Since: 10.1.0) */

+} virNodeDeviceGetXMLDescFlags;


In all of the other similar cases, this type is named 
vir$(OBJECT)XMLFlags and the flag itself is named 
VIR_$(OBJECT)_XML_INACTIVE. So for consistency, I'd remove the 'get' 
and the 'desc' from the names.




I disagree as all other methods that make use of flags base the flags 
names on the method name. Here are the examples:


virNodeDeviceCreateXML
virNodeDeviceCreateXMLFlags
vir Node Device Create XML
VIR_NODE_DEVICE_CREATE_XML_*

virNodeDeviceDefineXML
virNodeDeviceDefineXMLFlags
vir Node Device Define XML
VIR_NODE_DEVICE_DEFINE_XML_*

virConnectListAllNodeDevices
virConnectListAllNodeDeviceFlags
vir Connect List Node Device [All is removed]
VIR_CONNECT_LIST_NODE_DEVICES_*

These are the reasons I chose for consistency:
virNodeDeviceGetXMLDesc
virNodeDeviceGetXMLDescFlags
vir Node Device Get XML Desc
VIR_NODE_DEVICE_GET_XML_DESC_INACTIVE



That's true in general, however for the *GetXMLDesc() functions, this 
pattern doesn't hold:


domain:
 - virDomainGetXMLDesc()
 - virDomainXMLFlags
   - VIR_DOMAIN_XML_INACTIVE

storage:
 - virStoragePoolGetXMLDesc()
 - virStorageXMLFlags
   - VIR_STORAGE_XML_INACTIVE

network:
 - virNetworkGetXMLDesc()
 - virNetworkXMLFlags
   - VIR_NETWORK_XML_INACTIVE

interface:
 - virInterfaceGetXMLDesc()
 - virInterfaceXMLFlags
   - VIR_INTERFACE_XML_INACTIVE

There are no types following the *GetXMLDescFlags pattern:
$ git grep XMLDescFlags include/
$


I don't feel personally strongly about this point because there are 
consistency arguments for both approaches. But I thought I'd mention it.


Jonathon



+
  char *  virNodeDeviceGetXMLDesc (virNodeDevicePtr dev,
   unsigned int flags);
diff --git a/sr

Re: [PATCH 10/11] nodedev: Implement virNodeDeviceUpdateXML

2024-01-31 Thread Jonathon Jongsma
ng a defined device and when we're creating a transient one */
  MDEVCTL_CMD_CREATE,
+MDEVCTL_CMD_MODIFY,
  
  MDEVCTL_CMD_LAST,

  } virMdevctlCommand;
@@ -186,3 +187,13 @@ virCommand*
  nodeDeviceGetMdevctlSetAutostartCommand(virNodeDeviceDef *def,
  bool autostart,
  char **errmsg);
+
+virCommand*
+nodeDeviceGetMdevctlModifyCommand(virNodeDeviceDef *def,
+  bool defined,
+  bool live,
+  char **errmsg);
+int
+nodeDeviceUpdateXML(virNodeDevice *dev,
+const char *xmlDesc,
+unsigned int flags);
diff --git a/src/node_device/node_device_udev.c 
b/src/node_device/node_device_udev.c
index 57368a96c3..4cd9d285fa 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -2403,6 +2403,7 @@ static virNodeDeviceDriver udevNodeDeviceDriver = {
  .nodeDeviceGetAutostart = nodeDeviceGetAutostart, /* 7.8.0 */
  .nodeDeviceIsPersistent = nodeDeviceIsPersistent, /* 7.8.0 */
  .nodeDeviceIsActive = nodeDeviceIsActive, /* 7.8.0 */
+.nodeDeviceUpdateXML = nodeDeviceUpdateXML, /* 10.1.0 */
  };
  
  
diff --git a/tests/nodedevmdevctldata/mdevctl-modify.argv b/tests/nodedevmdevctldata/mdevctl-modify.argv

new file mode 100644
index 00..6acb9ca0bf
--- /dev/null
+++ b/tests/nodedevmdevctldata/mdevctl-modify.argv
@@ -0,0 +1,19 @@
+mdevctl \
+modify \
+--parent=0.0.0052 \
+--jsonfile=/dev/stdin \
+--uuid=c60cc60c-c60c-c60c-c60c-c60cc60cc60c \
+--defined
+mdevctl \
+modify \
+--parent=0.0.0052 \
+--jsonfile=/dev/stdin \
+--uuid=c60cc60c-c60c-c60c-c60c-c60cc60cc60c \
+--live
+mdevctl \
+modify \
+--parent=0.0.0052 \
+--jsonfile=/dev/stdin \
+--uuid=c60cc60c-c60c-c60c-c60c-c60cc60cc60c \
+--defined \
+--live
diff --git a/tests/nodedevmdevctltest.c b/tests/nodedevmdevctltest.c
index 852d9ed6e7..37978c9a5c 100644
--- a/tests/nodedevmdevctltest.c
+++ b/tests/nodedevmdevctltest.c
@@ -63,6 +63,7 @@ testMdevctlCmd(virMdevctlCommand cmd_type,
  case MDEVCTL_CMD_START:
  case MDEVCTL_CMD_STOP:
  case MDEVCTL_CMD_UNDEFINE:
+case MDEVCTL_CMD_MODIFY:
  create = EXISTING_DEVICE;
  break;
  case MDEVCTL_CMD_LAST:
@@ -173,6 +174,64 @@ testMdevctlAutostart(const void *data G_GNUC_UNUSED)
  return ret;
  }
  
+

+static int
+testMdevctlModify(const void *data G_GNUC_UNUSED)
+{
+g_autoptr(virNodeDeviceDef) def = NULL;
+virBuffer buf = VIR_BUFFER_INITIALIZER;
+const char *actualCmdline = NULL;
+int ret = -1;
+g_autoptr(virCommand) definedcmd = NULL;
+g_autoptr(virCommand) livecmd = NULL;
+g_autoptr(virCommand) bothcmd = NULL;
+g_autofree char *errmsg = NULL;
+/* just concatenate both calls into the same output file */
+g_autofree char *cmdlinefile =
+g_strdup_printf("%s/nodedevmdevctldata/mdevctl-modify.argv",
+abs_srcdir);
+g_autofree char *mdevxml =
+
g_strdup_printf("%s/nodedevschemadata/mdev_c60cc60c_c60c_c60c_c60c_c60cc60cc60c.xml",
+abs_srcdir);
+g_autoptr(virCommandDryRunToken) dryRunToken = virCommandDryRunTokenNew();
+
+if (!(def = virNodeDeviceDefParse(NULL, mdevxml, CREATE_DEVICE, VIRT_TYPE,
+  _callbacks, NULL, false)))
+return -1;
+
+virCommandSetDryRun(dryRunToken, , true, true, NULL, NULL);


You should also capture the stdin since that's really the majority of 
the command input.



+
+if (!(definedcmd = nodeDeviceGetMdevctlModifyCommand(def, true, false, 
)))
+goto cleanup;
+
+if (virCommandRun(definedcmd, NULL) < 0)
+goto cleanup;
+
+if (!(livecmd = nodeDeviceGetMdevctlModifyCommand(def, false, true, 
)))
+goto cleanup;
+
+if (virCommandRun(livecmd, NULL) < 0)
+goto cleanup;
+
+if (!(bothcmd = nodeDeviceGetMdevctlModifyCommand(def, true, true, 
)))
+goto cleanup;
+
+if (virCommandRun(bothcmd, NULL) < 0)
+goto cleanup;
+
+if (!(actualCmdline = virBufferCurrentContent()))
+goto cleanup;
+
+if (virTestCompareToFileFull(actualCmdline, cmdlinefile, false) < 0)
+goto cleanup;
+
+ret = 0;
+
+ cleanup:
+virBufferFreeAndReset();
+return ret;
+}
+
  static int
  testMdevctlListDefined(const void *data G_GNUC_UNUSED)
  {
@@ -457,6 +516,9 @@ mymain(void)
  #define DO_TEST_AUTOSTART() \
  DO_TEST_FULL("autostart mdevs", testMdevctlAutostart, NULL)
  
+#define DO_TEST_MODIFY() \

+DO_TEST_FULL("modify mdevs", testMdevctlModify, NULL)
+
  #define DO_TEST_PARSE_JSON(filename) \
  DO_TEST_FULL("parse mdevctl json " filename, testMdevctlParse, filename)
  
@@ -485,6 +547,8 @@ mymain(void)
  
  DO_TEST_AUTOSTART();
  
+DO_TEST_MODIFY();

+
   done:
  nodedevTestDriverFree(driver);
  


Reviewed-by: Jonathon Jongsma 

Re: [PATCH 06/11] nodedev: add persisted and transient filter on list

2024-01-31 Thread Jonathon Jongsma

On 1/19/24 10:38 AM, Boris Fiuczynski wrote:

Allow to filter node devices based on their persisted or transient states.

Signed-off-by: Boris Fiuczynski 
---
  include/libvirt/libvirt-nodedev.h | 2 ++
  src/conf/node_device_conf.h   | 7 ++-
  src/conf/virnodedeviceobj.c   | 8 
  3 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/include/libvirt/libvirt-nodedev.h 
b/include/libvirt/libvirt-nodedev.h
index d18246e2f6..dff394ec86 100644
--- a/include/libvirt/libvirt-nodedev.h
+++ b/include/libvirt/libvirt-nodedev.h
@@ -91,6 +91,8 @@ typedef enum {
  VIR_CONNECT_LIST_NODE_DEVICES_CAP_AP_MATRIX = 1 << 20, /* s390 AP 
Matrix (Since: 7.0.0) */
  VIR_CONNECT_LIST_NODE_DEVICES_CAP_VPD   = 1 << 21, /* Device with 
VPD (Since: 7.9.0) */
  
+VIR_CONNECT_LIST_NODE_DEVICES_PERSISTED = 1 << 28, /* Persisted devices (Since: 10.1.0) */


s/PERSISTED/PERSISTENT/


+VIR_CONNECT_LIST_NODE_DEVICES_TRANSIENT = 1 << 29, /* Transient 
devices (Since: 10.1.0) */
  VIR_CONNECT_LIST_NODE_DEVICES_INACTIVE  = 1 << 30, /* Inactive 
devices (Since: 7.3.0) */
  VIR_CONNECT_LIST_NODE_DEVICES_ACTIVE= 1U << 31, /* Active 
devices (Since: 7.3.0) */
  } virConnectListAllNodeDeviceFlags;
diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h
index f59440dbb9..3ee1fbc665 100644
--- a/src/conf/node_device_conf.h
+++ b/src/conf/node_device_conf.h
@@ -432,9 +432,14 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(virNodeDevCapsDef, 
virNodeDevCapsDefFree);
  VIR_CONNECT_LIST_NODE_DEVICES_ACTIVE | \
  VIR_CONNECT_LIST_NODE_DEVICES_INACTIVE
  
+#define VIR_CONNECT_LIST_NODE_DEVICES_FILTERS_PERSIST \


s/PERSIST/PERSISTENT/


+VIR_CONNECT_LIST_NODE_DEVICES_PERSISTED | \


s/PERSISTED/PERSISTENT/


+VIR_CONNECT_LIST_NODE_DEVICES_TRANSIENT
+
  #define VIR_CONNECT_LIST_NODE_DEVICES_FILTERS_ALL \
  VIR_CONNECT_LIST_NODE_DEVICES_FILTERS_CAP | \
-VIR_CONNECT_LIST_NODE_DEVICES_FILTERS_ACTIVE
+VIR_CONNECT_LIST_NODE_DEVICES_FILTERS_ACTIVE | \
+VIR_CONNECT_LIST_NODE_DEVICES_FILTERS_PERSIST
  
  int

  virNodeDeviceGetSCSIHostCaps(virNodeDevCapSCSIHost *scsi_host);
diff --git a/src/conf/virnodedeviceobj.c b/src/conf/virnodedeviceobj.c
index cfef30d47e..0b9ca8c864 100644
--- a/src/conf/virnodedeviceobj.c
+++ b/src/conf/virnodedeviceobj.c
@@ -911,6 +911,14 @@ virNodeDeviceObjMatch(virNodeDeviceObj *obj,
  return false;
  }
  
+if (flags & (VIR_CONNECT_LIST_NODE_DEVICES_FILTERS_PERSIST)) {

+if (!((MATCH(VIR_CONNECT_LIST_NODE_DEVICES_PERSISTED) &&
+  virNodeDeviceObjIsPersistent(obj)) ||
+  (MATCH(VIR_CONNECT_LIST_NODE_DEVICES_TRANSIENT) &&
+   !virNodeDeviceObjIsPersistent(obj
+return false;
+}
+
  return true;
  }
  #undef MATCH


Reviewed-by: Jonathon Jongsma 
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [PATCH 07/11] tools: add switches persisted and transient to nodedev-list

2024-01-31 Thread Jonathon Jongsma

On 1/19/24 10:38 AM, Boris Fiuczynski wrote:

Now that we can filter persisted and transient node devices in
virConnectListAllNodeDevices(), add these switches also to the
virsh nodedev-list command.

Signed-off-by: Boris Fiuczynski 
---
  docs/manpages/virsh.rst |  8 ++--
  tools/virsh-nodedev.c   | 24 ++--
  2 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst
index 3a814dccd2..4bcfbc230b 100644
--- a/docs/manpages/virsh.rst
+++ b/docs/manpages/virsh.rst
@@ -5461,7 +5461,7 @@ nodedev-list
  
  ::
  
-   nodedev-list [--cap capability] [--tree] [--inactive | --all]

+   nodedev-list [--cap capability] [--tree] [--inactive | --all] [--persisted 
| --transient]


s/persisted/persistent/

  
  List all of the devices available on the node that are known by libvirt.

  *cap* is used to filter the list by capability types, the types must be
@@ -5470,7 +5470,11 @@ separated by comma, e.g. --cap pci,scsi. Valid 
capability types include
  'scsi', 'storage', 'fc_host', 'vports', 'scsi_generic', 'drm', 'mdev',
  'mdev_types', 'ccw', 'css', 'ap_card', 'ap_queue', 'ap_matrix'. By default,
  only active devices are listed. *--inactive* is used to list only inactive
-devices, and *-all* is used to list both active and inactive devices.
+devices, and *--all* is used to list both active and inactive devices.
+*--persisted* is used to list only persisted devices, and *--transient* is


here too


+used to list only transient devices. Not providing *--persisted* or
+*--transient* will list all devices unless filtered otherwise. *--transient*
+is mutually exclusive with *--persisted* and *--inactive*.


again


  If *--tree* is used, the output is formatted in a tree representing parents of
  each node.  *--tree* is mutually exclusive with all other options.
  
diff --git a/tools/virsh-nodedev.c b/tools/virsh-nodedev.c

index 54e192d619..4acb955efe 100644
--- a/tools/virsh-nodedev.c
+++ b/tools/virsh-nodedev.c
@@ -390,6 +390,14 @@ static const vshCmdOptDef opts_node_list_devices[] = {
   .type = VSH_OT_BOOL,
   .help = N_("list inactive & active devices")
  },
+{.name = "persisted",


again


+ .type = VSH_OT_BOOL,
+ .help = N_("list persisted devices")


again



+},
+{.name = "transient",
+ .type = VSH_OT_BOOL,
+ .help = N_("list transient devices")
+},
  {.name = NULL}
  };
  
@@ -407,6 +415,8 @@ cmdNodeListDevices(vshControl *ctl, const vshCmd *cmd G_GNUC_UNUSED)

  int cap_type = -1;
  bool inactive = vshCommandOptBool(cmd, "inactive");
  bool all = vshCommandOptBool(cmd, "all");
+bool persisted = vshCommandOptBool(cmd, "persisted");


again


+bool transient = vshCommandOptBool(cmd, "transient");
  
  ignore_value(vshCommandOptStringQuiet(ctl, cmd, "cap", _str));
  
@@ -420,8 +430,13 @@ cmdNodeListDevices(vshControl *ctl, const vshCmd *cmd G_GNUC_UNUSED)

  return false;
  }
  
-if (tree && (cap_str || inactive)) {

-vshError(ctl, "%s", _("Option --tree is incompatible with --cap and 
--inactive"));
+if (transient && (persisted || inactive)) {
+vshError(ctl, "%s", _("Option --transient is incompatible with --persisted 
and --inactive"));


again


+return false;
+}
+
+if (tree && (cap_str || inactive || persisted || transient)) {
+vshError(ctl, "%s", _("Option --tree is incompatible with --cap, 
--inactive, --persisted and --transient"));


again


  return false;
  }
  
@@ -509,6 +524,11 @@ cmdNodeListDevices(vshControl *ctl, const vshCmd *cmd G_GNUC_UNUSED)

  if (!inactive)
  flags |= VIR_CONNECT_LIST_NODE_DEVICES_ACTIVE;
  
+if (persisted)

+flags |= VIR_CONNECT_LIST_NODE_DEVICES_PERSISTED;
+if (transient)
+flags |= VIR_CONNECT_LIST_NODE_DEVICES_TRANSIENT;
+
  if (!(list = virshNodeDeviceListCollect(ctl, caps, ncaps, flags))) {
  ret = false;
  goto cleanup;



Reviewed-by: Jonathon Jongsma 
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [PATCH 05/11] tools: add option inactive to nodedev-dumpxml

2024-01-31 Thread Jonathon Jongsma

On 1/19/24 10:38 AM, Boris Fiuczynski wrote:

Allow to dump the XML of the persisted mdev when the mdev has been
started instead of the current state only.

Signed-off-by: Boris Fiuczynski 
---
  docs/manpages/virsh.rst |  7 +--
  tools/virsh-nodedev.c   | 15 ++-
  2 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst
index ed1027e133..3a814dccd2 100644
--- a/docs/manpages/virsh.rst
+++ b/docs/manpages/virsh.rst
@@ -5422,14 +5422,17 @@ nodedev-dumpxml
  
  ::
  
-   nodedev-dumpxml [--xpath EXPRESSION] [--wrap] device

+   nodedev-dumpxml [--inactive] [--xpath EXPRESSION] [--wrap] device
  
  Dump a  XML representation for the given node device, including

  such information as the device name, which bus owns the device, the
  vendor and product id, and any capabilities of the device usable by
  libvirt (such as whether device reset is supported). *device* can
  be either device name or wwn pair in "wwnn,wwpn" format (only works
-for HBA).
+for HBA). An additional option affecting the XML dump may be
+used. *--inactive* tells virsh to dump the node device configuration
+that will be used on next start of the node device as opposed to the
+current node device configuration.
  
  If the **--xpath** argument provides an XPath expression, it will be

  evaluated against the output XML and only those matching nodes will
diff --git a/tools/virsh-nodedev.c b/tools/virsh-nodedev.c
index fb38fd7fcc..54e192d619 100644
--- a/tools/virsh-nodedev.c
+++ b/tools/virsh-nodedev.c
@@ -575,6 +575,10 @@ static const vshCmdOptDef opts_node_device_dumpxml[] = {
   .help = N_("device name or wwn pair in 'wwnn,wwpn' format"),
   .completer = virshNodeDeviceNameCompleter,
  },
+{.name = "inactive",
+ .type = VSH_OT_BOOL,
+ .help = N_("show inactive defined XML"),
+},
  {.name = "xpath",
   .type = VSH_OT_STRING,
   .flags = VSH_OFLAG_REQ_OPT,
@@ -594,6 +598,7 @@ cmdNodeDeviceDumpXML(vshControl *ctl, const vshCmd *cmd)
  g_autoptr(virshNodeDevice) device = NULL;
  g_autofree char *xml = NULL;
  const char *device_value = NULL;
+unsigned int flags = 0;
  bool wrap = vshCommandOptBool(cmd, "wrap");
  const char *xpath = NULL;
  
@@ -608,7 +613,15 @@ cmdNodeDeviceDumpXML(vshControl *ctl, const vshCmd *cmd)

  if (!device)
  return false;
  
-if (!(xml = virNodeDeviceGetXMLDesc(device, 0)))

+if (vshCommandOptBool(cmd, "inactive")) {
+flags |= VIR_NODE_DEVICE_GET_XML_DESC_INACTIVE;
+if (!virNodeDeviceIsPersistent(device)) {
+vshError(ctl, _("Node device '%1$s' is not persistent"), 
device_value);
+return false;
+}


I believe you've already handled this within virNodeDeviceGetXMLDesc() 
in patch 4. There shouldn't be any need to duplicate that check here.



+}
+
+if (!(xml = virNodeDeviceGetXMLDesc(device, flags)))
  return false;
  
  return virshDumpXML(ctl, xml, "node-device", xpath, wrap);


Reviewed-by: Jonathon Jongsma 
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [PATCH 04/11] nodedev: add an active config to mdev

2024-01-31 Thread Jonathon Jongsma
916_1ca8_49ac_b176_871d16c13076_inactive.xml
new file mode 12
index 00..e053844177
--- /dev/null
+++ 
b/tests/nodedevxml2xmlout/mdev_fedc4916_1ca8_49ac_b176_871d16c13076_inactive.xml
@@ -0,0 +1 @@
+mdev_fedc4916_1ca8_49ac_b176_871d16c13076.xml
\ No newline at end of file
diff --git a/tests/nodedevxml2xmltest.c b/tests/nodedevxml2xmltest.c
index 068ec68769..be7a5b4df9 100644
--- a/tests/nodedevxml2xmltest.c
+++ b/tests/nodedevxml2xmltest.c
@@ -11,14 +11,20 @@
  
  #define VIR_FROM_THIS VIR_FROM_NONE
  
+struct TestData {

+const char *filename;
+unsigned int flags;
+};
+
  static int
-testCompareXMLToXMLFiles(const char *xml, const char *outfile)
+testCompareXMLToXMLFiles(const char *xml, const char *outfile, unsigned int 
flags)
  {
  g_autofree char *xmlData = NULL;
  g_autofree char *actual = NULL;
  int ret = -1;
  virNodeDeviceDef *dev = NULL;
  virNodeDevCapsDef *caps;
+size_t i;
  
  if (virTestLoadFile(xml, ) < 0)

  goto fail;
@@ -46,9 +52,22 @@ testCompareXMLToXMLFiles(const char *xml, const char 
*outfile)
 data->storage.logical_block_size;
  }
  }
+
+if (caps->data.type == VIR_NODE_DEV_CAP_MDEV &&
+!(flags & VIR_NODE_DEVICE_GET_XML_DESC_INACTIVE)) {
+data->mdev.active_config.type = 
g_strdup(data->mdev.defined_config.type);
+for (i = 0; i < data->mdev.defined_config.nattributes; i++) {
+g_autoptr(virMediatedDeviceAttr) attr = 
g_new0(virMediatedDeviceAttr, 1);
+attr->name = 
g_strdup(data->mdev.defined_config.attributes[i]->name);
+attr->value = 
g_strdup(data->mdev.defined_config.attributes[i]->value);
+VIR_APPEND_ELEMENT(data->mdev.active_config.attributes,
+   data->mdev.active_config.nattributes,
+   attr);
+}
+}
  }
  
-if (!(actual = virNodeDeviceDefFormat(dev)))

+if (!(actual = virNodeDeviceDefFormat(dev, flags)))
  goto fail;
  
  if (virTestCompareToFile(actual, outfile) < 0)

@@ -65,16 +84,21 @@ static int
  testCompareXMLToXMLHelper(const void *data)
  {
  int result = -1;
+const struct TestData *tdata = data;
  g_autofree char *xml = NULL;
  g_autofree char *outfile = NULL;
  
  xml = g_strdup_printf("%s/nodedevschemadata/%s.xml", abs_srcdir,

-  (const char *)data);
+  tdata->filename);
  
-outfile = g_strdup_printf("%s/nodedevxml2xmlout/%s.xml", abs_srcdir,

-  (const char *)data);
+if (tdata->flags & VIR_NODE_DEVICE_GET_XML_DESC_INACTIVE)
+outfile = g_strdup_printf("%s/nodedevxml2xmlout/%s_inactive.xml", 
abs_srcdir,
+  tdata->filename);
+else
+outfile = g_strdup_printf("%s/nodedevxml2xmlout/%s.xml", abs_srcdir,
+  tdata->filename);
  
-result = testCompareXMLToXMLFiles(xml, outfile);

+result = testCompareXMLToXMLFiles(xml, outfile, tdata->flags);
  
  return result;

  }
@@ -85,10 +109,20 @@ mymain(void)
  {
  int ret = 0;
  
+#define DO_TEST_FLAGS(desc, filename, flags) \

+do { \
+struct TestData data = { filename, flags }; \
+if (virTestRun(desc, testCompareXMLToXMLHelper, ) < 0) \
+ret = -1; \
+   } \
+while (0)
+
  #define DO_TEST(name) \
-if (virTestRun("Node device XML-2-XML " name, \
-   testCompareXMLToXMLHelper, (name)) < 0) \
-ret = -1
+DO_TEST_FLAGS("Node device XML-2-XML " name, name, 0)
+
+#define DO_TEST_INACTIVE(name) \
+DO_TEST_FLAGS("Node device XML-2-XML INACTIVE " name, \
+  name, VIR_NODE_DEVICE_GET_XML_DESC_INACTIVE)
  
  DO_TEST("computer");

  DO_TEST("DVD_GCC_4247N");
@@ -121,6 +155,7 @@ mymain(void)
  DO_TEST("pci__02_10_7_mdev_types");
  DO_TEST("pci__42_00_0_vpd");
  DO_TEST("mdev_3627463d_b7f0_4fea_b468_f1da537d301b");
+DO_TEST_INACTIVE("mdev_3627463d_b7f0_4fea_b468_f1da537d301b");
  DO_TEST("ccw_0_0_");
  DO_TEST("css_0_0_");
  DO_TEST("css_0_0__channel_dev_addr");
@@ -134,7 +169,13 @@ mymain(void)
  DO_TEST("mdev_d069d019_36ea_4111_8f0a_8c9a70e21366");
  DO_TEST("mdev_d2441d39_495e_4243_ad9f_beb3f14c23d9");
  DO_TEST("mdev_fedc4916_1ca8_49ac_b176_871d16c13076");
+DO_TEST_INACTIVE("mdev_ee0b88c4_f554_4dc1_809d_b2a01e8e48ad");
+DO_TEST_INACTIVE("mdev_d069d019_36ea_4111_8f0a_8c9a70e21366");
+DO_TEST_INACTIVE("mdev_d2441d39_495e_4243_ad9f_beb3f14c23d9");
+DO_TEST_INACTIVE("mdev_fedc4916_1ca8_49ac_b176_871d16c13076");
  DO_TEST("hba_vport_ops");
+DO_TEST("mdev_c60cc60c_c60c_c60c_c60c_c60cc60cc60c");
+DO_TEST_INACTIVE("mdev_c60cc60c_c60c_c60c_c60c_c60cc60cc60c");
  
  return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;

  }


Reviewed-by: Jonathon Jongsma 
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [PATCH 02/11] node_device: refactor mdev attributes handling

2024-01-31 Thread Jonathon Jongsma
this mdev
+ * to the mdevctl utility */
+static int
+nodeDeviceDefToMdevctlConfig(virNodeDeviceDef *def, char **buf)
+{
+virNodeDevCapMdev *mdev = >caps->data.mdev;
+g_autoptr(virJSONValue) json = virJSONValueNewObject();
+const char *startval = mdev->autostart ? "auto" : "manual";
+
+if (virJSONValueObjectAppendString(json, "mdev_type", mdev->dev_config.type) 
< 0)
+return -1;
+
+if (virJSONValueObjectAppendString(json, "start", startval) < 0)
+return -1;
+
+if (nodeDeviceAttributesToJSON(json, mdev->dev_config) < 0)
+return -1;
+
  *buf = virJSONValueToString(json, false);
  if (!*buf)
  return -1;
@@ -1092,6 +1103,39 @@ matchDeviceAddress(virNodeDeviceObj *obj,
  }
  
  
+static int

+nodeDeviceParseMdevctlAttribs(virMediatedDeviceConfig *config,


As far as I can tell, we don't use the abbreviation "attribs" anywhere 
else in libvirt, but we do use both 'Attributes' and 'Attrs'. For 
consistency, I'd suggest just using the full word: 
nodeDeviceParseMdevctlAttributes()



+  virJSONValue *attrs)
+{
+size_t i;
+
+if (attrs && virJSONValueIsArray(attrs)) {
+int nattrs = virJSONValueArraySize(attrs);
+
+config->attributes = g_new0(virMediatedDeviceAttr*, nattrs);
+config->nattributes = nattrs;
+
+for (i = 0; i < nattrs; i++) {
+virJSONValue *attr = virJSONValueArrayGet(attrs, i);
+virMediatedDeviceAttr *attribute;
+virJSONValue *value;
+
+if (!virJSONValueIsObject(attr) ||
+virJSONValueObjectKeysNumber(attr) != 1)
+return -1;
+
+attribute = g_new0(virMediatedDeviceAttr, 1);
+attribute->name = g_strdup(virJSONValueObjectGetKey(attr, 0));
+value = virJSONValueObjectGetValue(attr, 0);
+attribute->value = g_strdup(virJSONValueGetString(value));
+config->attributes[i] = attribute;
+}
+}
+
+return 0;
+}
+
+
  static virNodeDeviceDef*
  nodeDeviceParseMdevctlChildDevice(const char *parent,
virJSONValue *json)
@@ -1099,7 +1143,6 @@ nodeDeviceParseMdevctlChildDevice(const char *parent,
  virNodeDevCapMdev *mdev;
  const char *uuid;
  virJSONValue *props;
-virJSONValue *attrs;
  g_autoptr(virNodeDeviceDef) child = g_new0(virNodeDeviceDef, 1);
  virNodeDeviceObj *parent_obj;
  const char *start = NULL;
@@ -1134,31 +1177,10 @@ nodeDeviceParseMdevctlChildDevice(const char *parent,
  start = virJSONValueObjectGetString(props, "start");
  mdev->autostart = STREQ_NULLABLE(start, "auto");
  
-attrs = virJSONValueObjectGet(props, "attrs");

-
-if (attrs && virJSONValueIsArray(attrs)) {
-size_t i;
-int nattrs = virJSONValueArraySize(attrs);
-
-mdev->dev_config.attributes = g_new0(virMediatedDeviceAttr*, nattrs);
-mdev->dev_config.nattributes = nattrs;
-
-for (i = 0; i < nattrs; i++) {
-virJSONValue *attr = virJSONValueArrayGet(attrs, i);
-virMediatedDeviceAttr *attribute;
-virJSONValue *value;
-
-if (!virJSONValueIsObject(attr) ||
-virJSONValueObjectKeysNumber(attr) != 1)
-return NULL;
+if (nodeDeviceParseMdevctlAttribs(>dev_config,
+  virJSONValueObjectGet(props, "attrs")) < 
0)
+return NULL;
  
-attribute = g_new0(virMediatedDeviceAttr, 1);

-attribute->name = g_strdup(virJSONValueObjectGetKey(attr, 0));
-value = virJSONValueObjectGetValue(attr, 0);
-attribute->value = g_strdup(virJSONValueGetString(value));
-mdev->dev_config.attributes[i] = attribute;
-}
-}
  mdevGenerateDeviceName(child);
  
  return g_steal_pointer();

@@ -1760,7 +1782,9 @@ nodeDeviceUpdateMediatedDevices(void)
  }
  
  
-/* returns true if any attributes were copied, else returns false */

+/* Transfer mediated device attributes to the new definition. Any change in
+ * the attributes is elminated but causes the return value to be true.
+ * Returns true if any attribute is copied, else returns false */


This change doesn't really seem to belong in this commit as there are no 
changes to this function. Also, I don't understand the comment. I 
suppose "elminated" is supposed to be "eliminated", but I still can't 
quite understand what it's trying to say.


Reviewed-by: Jonathon Jongsma 
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [PATCH 0/3] qemu: Improvements related to MODEL_SCSI_AUTO

2024-01-31 Thread Jonathon Jongsma

On 1/30/24 10:57 AM, Andrea Bolognani wrote:



Andrea Bolognani (3):
   tests: Add controller-scsi-auto
   qemu: Handle MODEL_SCSI_{AUTO,DEFAULT} appropriately
   qemu: Use virDomainControllerDefNew() more

  src/qemu/qemu_command.c   |  4 +--
  src/qemu/qemu_domain_address.c|  4 +--
  src/qemu/qemu_hotplug.c   |  4 +--
  src/qemu/qemu_validate.c  |  2 +-
  .../controller-scsi-auto.x86_64-latest.args   | 32 +++
  .../controller-scsi-auto.x86_64-latest.xml| 30 +
  .../qemuxmlconfdata/controller-scsi-auto.xml  | 15 +
  tests/qemuxmlconftest.c   |  1 +
  8 files changed, 85 insertions(+), 7 deletions(-)
  create mode 100644 
tests/qemuxmlconfdata/controller-scsi-auto.x86_64-latest.args
  create mode 100644 
tests/qemuxmlconfdata/controller-scsi-auto.x86_64-latest.xml
  create mode 100644 tests/qemuxmlconfdata/controller-scsi-auto.xml



Reviewed-by: Jonathon Jongsma 
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


[PATCH] qemu: fix nbdkit command test for backing chains

2024-01-26 Thread Jonathon Jongsma
Previously this test only tested the generated nbdkit command for the
top level disk source. Update it to test the generated commmands for all
sources in the chain.

Signed-off-by: Jonathon Jongsma 
---
 ...sk0 => disk-cdrom-network.args.disk0-src0} |  2 +-
 ...sk1 => disk-cdrom-network.args.disk1-src0} |  2 +-
 ...sk-cdrom-network.args.disk1-src0.pipe.778} |  0
 ...sk2 => disk-cdrom-network.args.disk2-src0} |  2 +-
 ...sk-cdrom-network.args.disk2-src0.pipe.780} |  0
 ...isk0 => disk-network-http.args.disk0-src0} |  2 +-
 ...isk1 => disk-network-http.args.disk1-src0} |  2 +-
 ...isk2 => disk-network-http.args.disk2-src0} |  2 +-
 ...isk-network-http.args.disk2-src0.pipe.778} |  0
 ...isk3 => disk-network-http.args.disk3-src0} |  2 +-
 ...isk-network-http.args.disk3-src0.pipe.780} |  0
 ...ource-curl-nbdkit-backing.args.disk0-src0} |  2 +-
 ...l-nbdkit-backing.args.disk0-src0.pipe.778} |  0
 ...source-curl-nbdkit-backing.args.disk0-src1 |  7 ++
 ...rl-nbdkit-backing.args.disk0-src1.pipe.780 |  1 +
 ... disk-network-source-curl.args.disk0-src0} |  2 +-
 ...work-source-curl.args.disk0-src0.pipe.778} |  0
 ... disk-network-source-curl.args.disk1-src0} |  2 +-
 ...work-source-curl.args.disk1-src0.pipe.780} |  0
 ...work-source-curl.args.disk1-src0.pipe.782} |  0
 ... disk-network-source-curl.args.disk2-src0} |  2 +-
 ...work-source-curl.args.disk2-src0.pipe.784} |  0
 ... disk-network-source-curl.args.disk3-src0} |  2 +-
 ... disk-network-source-curl.args.disk4-src0} |  2 +-
 ...0 => disk-network-ssh-key.args.disk0-src0} |  2 +-
 ...1 => disk-network-ssh-key.args.disk1-src0} |  2 +-
 ...disk-network-ssh-password.args.disk0-src0} |  2 +-
 ...ork-ssh-password.args.disk0-src0.pipe.778} |  0
 ...disk0 => disk-network-ssh.args.disk0-src0} |  2 +-
 tests/qemunbdkittest.c| 96 ++-
 30 files changed, 77 insertions(+), 61 deletions(-)
 rename tests/qemunbdkitdata/{disk-cdrom-network.args.disk0 => 
disk-cdrom-network.args.disk0-src0} (63%)
 rename tests/qemunbdkitdata/{disk-cdrom-network.args.disk1 => 
disk-cdrom-network.args.disk1-src0} (70%)
 rename tests/qemunbdkitdata/{disk-cdrom-network.args.disk1.pipe.778 => 
disk-cdrom-network.args.disk1-src0.pipe.778} (100%)
 rename tests/qemunbdkitdata/{disk-cdrom-network.args.disk2 => 
disk-cdrom-network.args.disk2-src0} (72%)
 rename tests/qemunbdkitdata/{disk-cdrom-network.args.disk2.pipe.780 => 
disk-cdrom-network.args.disk2-src0.pipe.780} (100%)
 rename tests/qemunbdkitdata/{disk-network-http.args.disk0 => 
disk-network-http.args.disk0-src0} (64%)
 rename tests/qemunbdkitdata/{disk-network-http.args.disk1 => 
disk-network-http.args.disk1-src0} (59%)
 rename tests/qemunbdkitdata/{disk-network-http.args.disk2 => 
disk-network-http.args.disk2-src0} (64%)
 rename tests/qemunbdkitdata/{disk-network-http.args.disk2.pipe.778 => 
disk-network-http.args.disk2-src0.pipe.778} (100%)
 rename tests/qemunbdkitdata/{disk-network-http.args.disk3 => 
disk-network-http.args.disk3-src0} (70%)
 rename tests/qemunbdkitdata/{disk-network-http.args.disk3.pipe.780 => 
disk-network-http.args.disk3-src0.pipe.780} (100%)
 rename 
tests/qemunbdkitdata/{disk-network-source-curl-nbdkit-backing.args.disk0 => 
disk-network-source-curl-nbdkit-backing.args.disk0-src0} (69%)
 rename 
tests/qemunbdkitdata/{disk-network-source-curl-nbdkit-backing.args.disk0.pipe.778
 => disk-network-source-curl-nbdkit-backing.args.disk0-src0.pipe.778} (100%)
 create mode 100644 
tests/qemunbdkitdata/disk-network-source-curl-nbdkit-backing.args.disk0-src1
 create mode 100644 
tests/qemunbdkitdata/disk-network-source-curl-nbdkit-backing.args.disk0-src1.pipe.780
 rename tests/qemunbdkitdata/{disk-network-source-curl.args.disk0 => 
disk-network-source-curl.args.disk0-src0} (69%)
 rename tests/qemunbdkitdata/{disk-network-source-curl.args.disk0.pipe.778 => 
disk-network-source-curl.args.disk0-src0.pipe.778} (100%)
 rename tests/qemunbdkitdata/{disk-network-source-curl.args.disk1 => 
disk-network-source-curl.args.disk1-src0} (75%)
 rename tests/qemunbdkitdata/{disk-network-source-curl.args.disk1.pipe.780 => 
disk-network-source-curl.args.disk1-src0.pipe.780} (100%)
 rename tests/qemunbdkitdata/{disk-network-source-curl.args.disk1.pipe.782 => 
disk-network-source-curl.args.disk1-src0.pipe.782} (100%)
 rename tests/qemunbdkitdata/{disk-network-source-curl.args.disk2 => 
disk-network-source-curl.args.disk2-src0} (69%)
 rename tests/qemunbdkitdata/{disk-network-source-curl.args.disk2.pipe.784 => 
disk-network-source-curl.args.disk2-src0.pipe.784} (100%)
 rename tests/qemunbdkitdata/{disk-network-source-curl.args.disk3 => 
disk-network-source-curl.args.disk3-src0} (64%)
 rename tests/qemunbdkitdata/{disk-network-source-curl.args.disk4 => 
disk-network-source-curl.args.disk4-src0} (65%)
 rename tests/qemunbdkitdata/{disk-network-ssh-key.args.disk0 => 
disk-network-ssh-key.args.disk0-src0} (74%)
 re

[PATCH 2/3] qemu: roll back if not all nbdkit backends are successful

2024-01-25 Thread Jonathon Jongsma
When starting nbdkit processes for the backing store of a disk, we were
returning an error if any backing store failed, but we were not cleaning
up processes that succeeded higher in the chain. Make sure that if we
return a failure status from qemuNbdkitStartStorageSource() that we roll
back any processes that had been started.

Signed-off-by: Jonathon Jongsma 
---
 src/qemu/qemu_nbdkit.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/qemu/qemu_nbdkit.c b/src/qemu/qemu_nbdkit.c
index 39f9c58a48..edbe2137d0 100644
--- a/src/qemu/qemu_nbdkit.c
+++ b/src/qemu/qemu_nbdkit.c
@@ -920,8 +920,11 @@ qemuNbdkitStartStorageSource(virQEMUDriver *driver,
 return qemuNbdkitStartStorageSourceOne(driver, vm, src);
 
 for (backing = src; backing != NULL; backing = backing->backingStore) {
-if (qemuNbdkitStartStorageSourceOne(driver, vm, backing) < 0)
+if (qemuNbdkitStartStorageSourceOne(driver, vm, backing) < 0) {
+/* roll back any previously-started sources */
+qemuNbdkitStopStorageSource(src, vm, true);
 return -1;
+}
 }
 
 return 0;
-- 
2.43.0
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


[PATCH 3/3] qemu: handle adding/removing nbdkit-backed disk sources

2024-01-25 Thread Jonathon Jongsma
Previously we were only starting or stopping nbdkit when the guest was
started or stopped or when hotplugging/unplugging a disk. But when doing
block operations, the disk backing store sources can also be be added or
removed independently of the disk device. When this happens the nbdkit
backend was not being handled properly. For example, when doing a
blockcopy from a nbdkit-backed disk to a new disk and pivoting to that
new location, the nbdkit process did not get cleaned up properly. Add
some functionality to qemuDomainStorageSourceAccessModify() to handle
this scenario.

Since we're now potentially starting nbdkit from another place in the
code, add a check to qemuNbdkitProcessStart() to report an error if we
are trying to start nbdkit for a disk source that already has a running
nbdkit process. This should never happen. If it does, it indicates an
error in another part of our code.

Signed-off-by: Jonathon Jongsma 
---
 src/qemu/qemu_domain.c | 10 ++
 src/qemu/qemu_nbdkit.c |  7 +++
 2 files changed, 17 insertions(+)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index de36641137..973a9af0b6 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -8026,6 +8026,7 @@ qemuDomainStorageSourceAccessModify(virQEMUDriver *driver,
 bool revoke_namespace = false;
 bool revoke_nvme = false;
 bool revoke_lockspace = false;
+bool revoke_nbdkit = false;
 
 VIR_DEBUG("src='%s' readonly=%d force_ro=%d force_rw=%d revoke=%d 
chain=%d",
   NULLSTR(src->path), src->readonly, force_ro, force_rw, revoke, 
chain);
@@ -8044,6 +8045,7 @@ qemuDomainStorageSourceAccessModify(virQEMUDriver *driver,
 revoke_namespace = true;
 revoke_nvme = true;
 revoke_lockspace = true;
+revoke_nbdkit = true;
 ret = 0;
 goto revoke;
 }
@@ -8059,6 +8061,11 @@ qemuDomainStorageSourceAccessModify(virQEMUDriver 
*driver,
 
 revoke_nvme = true;
 
+if (qemuNbdkitStartStorageSource(driver, vm, src, chain) < 0)
+goto revoke;
+
+revoke_nbdkit = true;
+
 if (qemuDomainNamespaceSetupDisk(vm, src, _namespace) < 0)
 goto revoke;
 }
@@ -8113,6 +8120,9 @@ qemuDomainStorageSourceAccessModify(virQEMUDriver *driver,
 VIR_WARN("Unable to release lock on %s", srcstr);
 }
 
+if (revoke_nbdkit)
+qemuNbdkitStopStorageSource(src, vm, chain);
+
  cleanup:
 src->readonly = was_readonly;
 virErrorRestore(_err);
diff --git a/src/qemu/qemu_nbdkit.c b/src/qemu/qemu_nbdkit.c
index edbe2137d0..73dc90af3e 100644
--- a/src/qemu/qemu_nbdkit.c
+++ b/src/qemu/qemu_nbdkit.c
@@ -1195,6 +1195,13 @@ qemuNbdkitProcessStart(qemuNbdkitProcess *proc,
 struct nbd_handle *nbd = NULL;
 #endif
 
+/* don't try to start nbdkit again if we've already started it */
+if (proc->pid > 0) {
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+   _("Attempting to start nbdkit twice"));
+return -1;
+}
+
 if (!(cmd = qemuNbdkitProcessBuildCommand(proc)))
 return -1;
 
-- 
2.43.0
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


[PATCH 1/3] qemu: add a 'chain' parameter to nbdkit start/stop

2024-01-25 Thread Jonathon Jongsma
This will allow us to start or stop nbdkit for just a single disk source
or for every source in the backing chain. This will be used in following
patches.

Signed-off-by: Jonathon Jongsma 
---
 src/qemu/qemu_extdevice.c |  8 +++---
 src/qemu/qemu_hotplug.c   |  6 ++---
 src/qemu/qemu_nbdkit.c| 51 ++-
 src/qemu/qemu_nbdkit.h|  6 +++--
 4 files changed, 51 insertions(+), 20 deletions(-)

diff --git a/src/qemu/qemu_extdevice.c b/src/qemu/qemu_extdevice.c
index 3cf3867056..ed5976d1f7 100644
--- a/src/qemu/qemu_extdevice.c
+++ b/src/qemu/qemu_extdevice.c
@@ -234,12 +234,12 @@ qemuExtDevicesStart(virQEMUDriver *driver,
 
 for (i = 0; i < def->ndisks; i++) {
 virDomainDiskDef *disk = def->disks[i];
-if (qemuNbdkitStartStorageSource(driver, vm, disk->src) < 0)
+if (qemuNbdkitStartStorageSource(driver, vm, disk->src, true) < 0)
 return -1;
 }
 
 if (def->os.loader && def->os.loader->nvram) {
-if (qemuNbdkitStartStorageSource(driver, vm, def->os.loader->nvram) < 
0)
+if (qemuNbdkitStartStorageSource(driver, vm, def->os.loader->nvram, 
true) < 0)
 return -1;
 }
 
@@ -297,11 +297,11 @@ qemuExtDevicesStop(virQEMUDriver *driver,
 
 for (i = 0; i < def->ndisks; i++) {
 virDomainDiskDef *disk = def->disks[i];
-qemuNbdkitStopStorageSource(disk->src, vm);
+qemuNbdkitStopStorageSource(disk->src, vm, true);
 }
 
 if (def->os.loader && def->os.loader->nvram)
-qemuNbdkitStopStorageSource(def->os.loader->nvram, vm);
+qemuNbdkitStopStorageSource(def->os.loader->nvram, vm, true);
 }
 
 
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 31b00e05ca..e67673b762 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1018,7 +1018,7 @@ qemuDomainAttachDeviceDiskLiveInternal(virQEMUDriver 
*driver,
 if (qemuHotplugAttachManagedPR(vm, disk->src, VIR_ASYNC_JOB_NONE) < 0)
 goto cleanup;
 
-if (qemuNbdkitStartStorageSource(driver, vm, disk->src) < 0)
+if (qemuNbdkitStartStorageSource(driver, vm, disk->src, true) < 0)
 goto cleanup;
 }
 
@@ -1045,7 +1045,7 @@ qemuDomainAttachDeviceDiskLiveInternal(virQEMUDriver 
*driver,
 if (virStorageSourceChainHasManagedPR(disk->src))
 ignore_value(qemuHotplugRemoveManagedPR(vm, VIR_ASYNC_JOB_NONE));
 
-qemuNbdkitStopStorageSource(disk->src, vm);
+qemuNbdkitStopStorageSource(disk->src, vm, true);
 }
 qemuDomainSecretDiskDestroy(disk);
 qemuDomainCleanupStorageSourceFD(disk->src);
@@ -4562,7 +4562,7 @@ qemuDomainRemoveDiskDevice(virQEMUDriver *driver,
 qemuHotplugRemoveManagedPR(vm, VIR_ASYNC_JOB_NONE) < 0)
 goto cleanup;
 
-qemuNbdkitStopStorageSource(disk->src, vm);
+qemuNbdkitStopStorageSource(disk->src, vm, true);
 
 if (disk->transient) {
 VIR_DEBUG("Removing transient overlay '%s' of disk '%s'",
diff --git a/src/qemu/qemu_nbdkit.c b/src/qemu/qemu_nbdkit.c
index 1c72b6fe6a..39f9c58a48 100644
--- a/src/qemu/qemu_nbdkit.c
+++ b/src/qemu/qemu_nbdkit.c
@@ -893,18 +893,34 @@ qemuNbdkitInitStorageSource(qemuNbdkitCaps *caps 
WITHOUT_NBDKIT_UNUSED,
 }
 
 
+static int
+qemuNbdkitStartStorageSourceOne(virQEMUDriver *driver,
+virDomainObj *vm,
+virStorageSource *src)
+{
+qemuDomainStorageSourcePrivate *priv = 
QEMU_DOMAIN_STORAGE_SOURCE_PRIVATE(src);
+
+if (priv && priv->nbdkitProcess &&
+qemuNbdkitProcessStart(priv->nbdkitProcess, vm, driver) < 0)
+return -1;
+
+return 0;
+}
+
+
 int
 qemuNbdkitStartStorageSource(virQEMUDriver *driver,
  virDomainObj *vm,
- virStorageSource *src)
+ virStorageSource *src,
+ bool chain)
 {
 virStorageSource *backing;
 
-for (backing = src; backing != NULL; backing = backing->backingStore) {
-qemuDomainStorageSourcePrivate *priv = 
QEMU_DOMAIN_STORAGE_SOURCE_PRIVATE(backing);
+if (!chain)
+return qemuNbdkitStartStorageSourceOne(driver, vm, src);
 
-if (priv && priv->nbdkitProcess &&
-qemuNbdkitProcessStart(priv->nbdkitProcess, vm, driver) < 0)
+for (backing = src; backing != NULL; backing = backing->backingStore) {
+if (qemuNbdkitStartStorageSourceOne(driver, vm, backing) < 0)
 return -1;
 }
 
@@ -912,18 +928,31 @@ qemuNbdkitStartStorageSource(virQEMUDriver *driver,
 }
 
 
+static void
+qemuNbdkitStopStorageSourceOne(virStorageSource *src,
+   virDomainObj *vm)
+{
+qemuDomainStorageSourcePrivate *priv

[PATCH v2 2/2] tests: Remove readahead and timeout from ssh tests

2024-01-23 Thread Jonathon Jongsma
These values are currently unsupported for ssh disks, and in fact aren't
even parsed for ssh disks. So while this didn't result in any test
errors, we can remove them from the test input files.

Signed-off-by: Jonathon Jongsma 
---
 tests/qemuxml2argvdata/disk-network-ssh-key.xml  | 4 
 tests/qemuxml2argvdata/disk-network-ssh-password.xml | 2 --
 tests/qemuxml2argvdata/disk-network-ssh.xml  | 2 --
 3 files changed, 8 deletions(-)

diff --git a/tests/qemuxml2argvdata/disk-network-ssh-key.xml 
b/tests/qemuxml2argvdata/disk-network-ssh-key.xml
index 6328a9b7ef..1277a9b3cf 100644
--- a/tests/qemuxml2argvdata/disk-network-ssh-key.xml
+++ b/tests/qemuxml2argvdata/disk-network-ssh-key.xml
@@ -17,8 +17,6 @@
   
   
 
-
-
 
 
   
@@ -28,8 +26,6 @@
   
   
 
-
-
 
 
   
diff --git a/tests/qemuxml2argvdata/disk-network-ssh-password.xml 
b/tests/qemuxml2argvdata/disk-network-ssh-password.xml
index bdb4cf6e35..1ba0cb094c 100644
--- a/tests/qemuxml2argvdata/disk-network-ssh-password.xml
+++ b/tests/qemuxml2argvdata/disk-network-ssh-password.xml
@@ -17,8 +17,6 @@
   
   
 
-
-
 
   
 
diff --git a/tests/qemuxml2argvdata/disk-network-ssh.xml 
b/tests/qemuxml2argvdata/disk-network-ssh.xml
index a3aeca0c99..f5956fcc6f 100644
--- a/tests/qemuxml2argvdata/disk-network-ssh.xml
+++ b/tests/qemuxml2argvdata/disk-network-ssh.xml
@@ -17,8 +17,6 @@
   
   
 
-
-
 
   
   
-- 
2.43.0
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


[PATCH v2 1/2] qemu: Fix bug in nbdkit-backed backing chains

2024-01-23 Thread Jonathon Jongsma
When trying to start nbdkit-backed disks in backing chains, we were
accidentally always checking the private data of the top of the chain
instead of using the loop variable.

Signed-off-by: Jonathon Jongsma 
---
 src/qemu/qemu_nbdkit.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/qemu/qemu_nbdkit.c b/src/qemu/qemu_nbdkit.c
index 85e61be44c..1c72b6fe6a 100644
--- a/src/qemu/qemu_nbdkit.c
+++ b/src/qemu/qemu_nbdkit.c
@@ -901,7 +901,7 @@ qemuNbdkitStartStorageSource(virQEMUDriver *driver,
 virStorageSource *backing;
 
 for (backing = src; backing != NULL; backing = backing->backingStore) {
-qemuDomainStorageSourcePrivate *priv = 
QEMU_DOMAIN_STORAGE_SOURCE_PRIVATE(src);
+qemuDomainStorageSourcePrivate *priv = 
QEMU_DOMAIN_STORAGE_SOURCE_PRIVATE(backing);
 
 if (priv && priv->nbdkitProcess &&
 qemuNbdkitProcessStart(priv->nbdkitProcess, vm, driver) < 0)
@@ -919,7 +919,7 @@ qemuNbdkitStopStorageSource(virStorageSource *src,
 virStorageSource *backing;
 
 for (backing = src; backing != NULL; backing = backing->backingStore) {
-qemuDomainStorageSourcePrivate *priv = 
QEMU_DOMAIN_STORAGE_SOURCE_PRIVATE(src);
+qemuDomainStorageSourcePrivate *priv = 
QEMU_DOMAIN_STORAGE_SOURCE_PRIVATE(backing);
 
 if (priv && priv->nbdkitProcess &&
 qemuNbdkitProcessStop(priv->nbdkitProcess, vm) < 0)
-- 
2.43.0
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


[PATCH v2 0/2] A couple nbdkit-related fixes

2024-01-23 Thread Jonathon Jongsma
Changes in v2
 - patch 1 now includes the same patch for both start and stop storage source
   functions

Jonathon Jongsma (2):
  qemu: Fix bug in nbdkit-backed backing chains
  tests: Remove readahead and timeout from ssh tests

 src/qemu/qemu_nbdkit.c   | 4 ++--
 tests/qemuxml2argvdata/disk-network-ssh-key.xml  | 4 
 tests/qemuxml2argvdata/disk-network-ssh-password.xml | 2 --
 tests/qemuxml2argvdata/disk-network-ssh.xml  | 2 --
 4 files changed, 2 insertions(+), 10 deletions(-)

-- 
2.43.0
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [PATCH v4 0/2] A couple nbdkit-related fixes

2024-01-23 Thread Jonathon Jongsma

On 1/23/24 2:47 PM, Peter Krempa wrote:

On Tue, Jan 23, 2024 at 13:00:35 -0600, Jonathon Jongsma wrote:

 From subject: v4?


Jonathon Jongsma (2):
   qemu: Fix bug in nbdkit-backed backing chains
   tests: Remove readahead and timeout from ssh tests


Reviewed-by: Peter Krempa 



Oops re v4. I think that happened from calling git publish on my master 
branch rather than a different branch. Apparently I've submitted patches 
from master before and git publish things it should bump the revision 
for this series...


Also, I'm going to self-nack and send a v2 because I just noticed that 
the same error in iteration occurs in the StopStorageSource() function.

___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


[PATCH v4 1/2] qemu: Fix bug in nbdkit-backed backing chains

2024-01-23 Thread Jonathon Jongsma
When trying to start nbdkit-backed disks in backing chains, we were
accidentally always checking the private data of the top of the chain
instead of using the loop variable.

Signed-off-by: Jonathon Jongsma 
---
 src/qemu/qemu_nbdkit.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/qemu/qemu_nbdkit.c b/src/qemu/qemu_nbdkit.c
index 85e61be44c..0ff07c45fc 100644
--- a/src/qemu/qemu_nbdkit.c
+++ b/src/qemu/qemu_nbdkit.c
@@ -901,7 +901,7 @@ qemuNbdkitStartStorageSource(virQEMUDriver *driver,
 virStorageSource *backing;
 
 for (backing = src; backing != NULL; backing = backing->backingStore) {
-qemuDomainStorageSourcePrivate *priv = 
QEMU_DOMAIN_STORAGE_SOURCE_PRIVATE(src);
+qemuDomainStorageSourcePrivate *priv = 
QEMU_DOMAIN_STORAGE_SOURCE_PRIVATE(backing);
 
 if (priv && priv->nbdkitProcess &&
 qemuNbdkitProcessStart(priv->nbdkitProcess, vm, driver) < 0)
-- 
2.43.0
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


[PATCH v4 2/2] tests: Remove readahead and timeout from ssh tests

2024-01-23 Thread Jonathon Jongsma
These values are currently unsupported for ssh disks, and in fact aren't
even parsed for ssh disks. So while this didn't result in any test
errors, we can remove them from the test input files.

Signed-off-by: Jonathon Jongsma 
---
 tests/qemuxml2argvdata/disk-network-ssh-key.xml  | 4 
 tests/qemuxml2argvdata/disk-network-ssh-password.xml | 2 --
 tests/qemuxml2argvdata/disk-network-ssh.xml  | 2 --
 3 files changed, 8 deletions(-)

diff --git a/tests/qemuxml2argvdata/disk-network-ssh-key.xml 
b/tests/qemuxml2argvdata/disk-network-ssh-key.xml
index 6328a9b7ef..1277a9b3cf 100644
--- a/tests/qemuxml2argvdata/disk-network-ssh-key.xml
+++ b/tests/qemuxml2argvdata/disk-network-ssh-key.xml
@@ -17,8 +17,6 @@
   
   
 
-
-
 
 
   
@@ -28,8 +26,6 @@
   
   
 
-
-
 
 
   
diff --git a/tests/qemuxml2argvdata/disk-network-ssh-password.xml 
b/tests/qemuxml2argvdata/disk-network-ssh-password.xml
index bdb4cf6e35..1ba0cb094c 100644
--- a/tests/qemuxml2argvdata/disk-network-ssh-password.xml
+++ b/tests/qemuxml2argvdata/disk-network-ssh-password.xml
@@ -17,8 +17,6 @@
   
   
 
-
-
 
   
 
diff --git a/tests/qemuxml2argvdata/disk-network-ssh.xml 
b/tests/qemuxml2argvdata/disk-network-ssh.xml
index a3aeca0c99..f5956fcc6f 100644
--- a/tests/qemuxml2argvdata/disk-network-ssh.xml
+++ b/tests/qemuxml2argvdata/disk-network-ssh.xml
@@ -17,8 +17,6 @@
   
   
 
-
-
 
   
   
-- 
2.43.0
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


[PATCH v4 0/2] A couple nbdkit-related fixes

2024-01-23 Thread Jonathon Jongsma


Jonathon Jongsma (2):
  qemu: Fix bug in nbdkit-backed backing chains
  tests: Remove readahead and timeout from ssh tests

 src/qemu/qemu_nbdkit.c   | 2 +-
 tests/qemuxml2argvdata/disk-network-ssh-key.xml  | 4 
 tests/qemuxml2argvdata/disk-network-ssh-password.xml | 2 --
 tests/qemuxml2argvdata/disk-network-ssh.xml  | 2 --
 4 files changed, 1 insertion(+), 9 deletions(-)

-- 
2.43.0
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [PATCH] NEWS: Document my contributions for upcoming release

2024-01-12 Thread Jonathon Jongsma

On 1/12/24 6:48 AM, Michal Privoznik wrote:

Signed-off-by: Michal Privoznik 
---
  NEWS.rst | 27 +++
  1 file changed, 27 insertions(+)

diff --git a/NEWS.rst b/NEWS.rst
index af3c4906df..e8cc89a2ee 100644
--- a/NEWS.rst
+++ b/NEWS.rst
@@ -55,6 +55,10 @@ v10.0.0 (unreleased)
  Libvirt aleviates this by automatically adding a  to match the
  size of the source image rather than failing the migration.
  
+  * test driver: Support for hotplug/hotunplug of PCI devices

+
+The test driver now supports basic hotplug and hotunplug of PCI devices.
+
  * **Bug fixes**
  
* qemu: Various migration bug fixes and debuggability improvement

@@ -63,6 +67,29 @@ v10.0.0 (unreleased)
  migration arguments and XMLs and modifies error reporting for better
  debugging.
  
+  * conf: Restore setting default bus for input devices

+
+Because of a regression, starting from 9.3.0 libvirt did not autofill bus
+for input devices. With this release the regression was identified and
+fixed.
+
+  * qemu: Relax check for memory device coldplug
+
+Because of too aggressive check, a virtio-mem memory device could not be


s/too aggressive check/a check that was too aggressive/


+cold plugged. This now fixed.


missing 'is'


+
+  * qemu: Be less aggressive when dropping channel source paths
+
+Another regression is resolved, (introduced in 9.7.0) when libvirt was too
+aggressive when dropping parsed paths for  sources
+
+  * qemuDomainChangeNet: Reflect trustGuestRxFilters change
+
+On device-update, when user requests change of trustGuestRxFilters for a


s/user requests/a user requested/


+domain's  libvirt did nothing. Neither it thrown an error nor


s/Neither it thrown/It did not throw/


+did it reflect the change. Starting with this release, the change is
+reflected.
+
  
  v9.10.0 (2023-12-01)

  


Just some minor grammatical suggestions

Reviewed-by: Jonathon Jongsma 
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


[PATCH] NEWS: mention nbdkit config option

2024-01-12 Thread Jonathon Jongsma
Signed-off-by: Jonathon Jongsma 
---
 NEWS.rst | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/NEWS.rst b/NEWS.rst
index af3c4906df..8088097ad6 100644
--- a/NEWS.rst
+++ b/NEWS.rst
@@ -37,6 +37,16 @@ v10.0.0 (unreleased)
 ``virDomainBlockResize`` allows resizing a block-device backed ``raw`` disk
 of a VM without the need to specify the full size of the block device.
 
+  * qemu: add runtime configuration option for nbdkit
+
+Since the new nbdkit support requires a recent selinux policy that is not
+widely available yet, it is now possible to build libvirt with nbdkit
+support for remote disks but disabled at runtime. This behavior is
+controlled via the storage_use_nbdkit option of the qemu driver
+configuration file. The option will default to being disabled, but this may
+change in a future release and can be customized with the
+nbdkit_config_default build option.
+
 * **Improvements**
 
   * qemu: Improve migration XML use when persisting VM on destination
-- 
2.43.0
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [PATCH v3 00/12] Improve versioned CPU support in libvirt

2024-01-11 Thread Jonathon Jongsma

polite ping


On 12/15/23 4:11 PM, Jonathon Jongsma wrote:

For SEV-SNP support we will need to be able to specify versioned CPU models
that are not yet available in libvirt. Rather than just adding a versioned CPU
or two that would satisfy that immediate need, I decided to try to add
versioned CPUs in a more standard way. This series generates CPU definitions
for all cpu versions that are defined in upstream qemu (at least for
recent Intel and AMD CPUs).

libvirt already provides a select subset of these versions as configurable CPU
models. But we only include the ones that have defined aliases in qemu, such as
EPYC-IBPB. After this patchset, all verisioned cpu models supported by qemu
will be available in libvirt.

In addition to adding these new versioned models, based on feedback from Daniel
Berrange, I've also translated all CPU model aliases to a specific version when
specifying a CPU model to qemu. This means that we will no longer specify e.g.
'-cpu EPYC' to qemu, but will rather specify '-cpu EPYC-v1'

Changes in v3:
  - handle unversioned aliases

Changes in v2:
  - don't make any changes to existing CPU models
  - drop concept of aliases from libvirt and only provide new versioned models
that aren't already available via their qemu alias.

Jonathon Jongsma (12):
   cpu_map: update script to handle versioned CPUs
   cpu_map: add canonical names to existing CPU models
   cpu: parse the canonical name from the cpu model
   qemu: use canonical name for CPU models
   cpu_map: Add versioned EPYC CPUs
   cpu_map: Add versioned Intel Skylake CPUs
   cpu_map: Add versioned Intel Cascadelake CPUs
   cpu_map: Add versioned Intel Icelake CPUs
   cpu_map: Add versioned Intel Cooperlake CPUs
   cpu_map: Add versioned Intel Snowridge CPUs
   cpu_map: Add versioned Intel SapphireRapids CPUs
   cpu_map: Add versioned Dhyana CPUs

  src/conf/cpu_conf.c   |   3 +
  src/conf/cpu_conf.h   |   1 +
  src/cpu/cpu_x86.c |  24 
  src/cpu_map/index.xml |  22 +++
  src/cpu_map/meson.build   |  22 +++
  src/cpu_map/sync_qemu_models_i386.py  |  42 --
  src/cpu_map/x86_Broadwell-IBRS.xml|   1 +
  src/cpu_map/x86_Broadwell-noTSX-IBRS.xml  |   1 +
  src/cpu_map/x86_Broadwell-noTSX.xml   |   1 +
  src/cpu_map/x86_Broadwell.xml |   1 +
  src/cpu_map/x86_Cascadelake-Server-noTSX.xml  |   1 +
  src/cpu_map/x86_Cascadelake-Server-v2.xml |  93 +
  src/cpu_map/x86_Cascadelake-Server-v4.xml |  91 +
  src/cpu_map/x86_Cascadelake-Server-v5.xml |  92 +
  src/cpu_map/x86_Cascadelake-Server.xml|   1 +
  src/cpu_map/x86_Cooperlake-v2.xml |  98 ++
  src/cpu_map/x86_Cooperlake.xml|   1 +
  src/cpu_map/x86_Dhyana-v2.xml |  81 
  src/cpu_map/x86_Dhyana.xml|   1 +
  src/cpu_map/x86_EPYC-IBPB.xml |   1 +
  src/cpu_map/x86_EPYC-Milan-v2.xml | 108 +++
  src/cpu_map/x86_EPYC-Milan.xml|   1 +
  src/cpu_map/x86_EPYC-Rome-v2.xml  |  93 +
  src/cpu_map/x86_EPYC-Rome-v3.xml  |  95 +
  src/cpu_map/x86_EPYC-Rome-v4.xml  |  94 +
  src/cpu_map/x86_EPYC-Rome.xml |   1 +
  src/cpu_map/x86_EPYC-v3.xml   |  87 
  src/cpu_map/x86_EPYC-v4.xml   |  88 
  src/cpu_map/x86_EPYC.xml  |   1 +
  src/cpu_map/x86_Haswell-IBRS.xml  |   1 +
  src/cpu_map/x86_Haswell-noTSX-IBRS.xml|   1 +
  src/cpu_map/x86_Haswell-noTSX.xml |   1 +
  src/cpu_map/x86_Haswell.xml   |   1 +
  src/cpu_map/x86_Icelake-Server-noTSX.xml  |   1 +
  src/cpu_map/x86_Icelake-Server-v3.xml | 103 +++
  src/cpu_map/x86_Icelake-Server-v4.xml | 108 +++
  src/cpu_map/x86_Icelake-Server-v5.xml | 109 +++
  src/cpu_map/x86_Icelake-Server-v6.xml | 109 +++
  src/cpu_map/x86_Icelake-Server.xml|   1 +
  src/cpu_map/x86_IvyBridge-IBRS.xml|   1 +
  src/cpu_map/x86_IvyBridge.xml |   1 +
  src/cpu_map/x86_Nehalem-IBRS.xml  |   1 +
  src/cpu_map/x86_Nehalem.xml   |   1 +
  src/cpu_map/x86_SandyBridge-IBRS.xml  |   1 +
  src/cpu_map/x86_SandyBridge.xml   |   1 +
  src/cpu_map/x86_SapphireRapids-v2.xml | 125 ++
  src/cpu_map/x86_SapphireRapids.xml|   1 +
  src/cpu_map/x86_Skylake-Client-IBRS.xml   |   1 +
  src/cpu_map/x86_Skylake-Client-noTSX-IBRS.xml |   1 +
  src/cpu_map/x86_Skylake-Client-v4.xml |  77 +++
  src/cpu_map/x86_Skylake-Client.xml|   1 +
  src/cpu_map/x86_Skylake-Server-IBRS.xml   |   1

Re: [PATCH] conf: domain_conf: cleanup def in case of errors

2024-01-11 Thread Jonathon Jongsma

On 1/11/24 6:57 AM, Shaleen Bathla wrote:

Just like in rest of the function virDomainFSDefParseXML,
use goto error so that def will be cleaned up in error cases.

Signed-off-by: Shaleen Bathla 
---
  src/conf/domain_conf.c | 8 
  1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index be57a1981e7d..5d55d2acdace 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -8866,23 +8866,23 @@ virDomainFSDefParseXML(virDomainXMLOption *xmlopt,
  goto error;
  
  if ((n = virXPathNodeSet("./idmap/uid", ctxt, _nodes)) < 0)

-return NULL;
+goto error;
  
  if (n) {

  def->idmap.uidmap = virDomainIdmapDefParseXML(ctxt, uid_nodes, n);
  if (!def->idmap.uidmap)
-return NULL;
+goto error;
  
  def->idmap.nuidmap = n;

  }
  
  if ((n = virXPathNodeSet("./idmap/gid", ctxt, _nodes)) < 0)

-return NULL;
+goto error;
  
  if (n) {

  def->idmap.gidmap = virDomainIdmapDefParseXML(ctxt, gid_nodes, n);
  if (!def->idmap.gidmap)
-return NULL;
+goto error;
  
  def->idmap.ngidmap = n;

  }


It might be worthwhile to introduce an automatic cleanup function for 
virDomainFSDef and remove the gotos from this function completely, but 
this patch fixes the immediate issue.


Reviewed-by: Jonathon Jongsma 

___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [PATCH v4] qemu: add runtime config option for nbdkit

2024-01-04 Thread Jonathon Jongsma

On 1/4/24 1:14 PM, Andrea Bolognani wrote:

On Thu, Jan 04, 2024 at 12:24:38PM -0600, Jonathon Jongsma wrote:

Currently when we build with nbdkit support, libvirt will always try to
use nbdkit to access remote disk sources when it is available. But
without an up-to-date selinux policy allowing this, it will fail.
because the required selinux policies are not yet widely available, we
have disabled nbdkit support on rpm builds for all distributions before
Fedora 40.

Unfortunately, this makes it more difficult to test nbdkit support.
After someone updates to the necessary selinux policies, they would also
need to rebuild libvirt to enable nbdkit support. By introducing a
configure option (nbdkit_config_default), we can build packages with
nbdkit support but have it disabled by default.

Signed-off-by: Jonathon Jongsma 
Suggested-by: Andrea Bolognani 
---
changes in v4
  - squashed in Andrea's suggested changes
- updated error message
- Changed one instance of WITH_NDBKIT to WITH_NBDKIT :)


Nice catch O:-)


+static int
+virQEMUDriverConfigLoadStorageEntry(virQEMUDriverConfig *cfg,
+virConf *conf)
+{
+if (virConfGetValueBool(conf, "storage_use_nbdkit", >storageUseNbdkit) 
< 0)
+return -1;
+
+#if !WITH_NBDKIT
+if (cfg->storageUseNbdkit) {
+virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+   "%s",
+   _("configuration option 'storage_use_nbdkit' was specified, 
but nbdkit is not supported by this libvirt"));
+return -1;
+}
+#endif /* WITH_NBDKIT */


I was about to ACK this directly, but while performing some
last-minute due diligence I realized that unfortunately this approach
comes with its own drawbacks.

Because of socket activation, this failure is not as visible to the
admin as we would like it to be: in particular, if you set the option
and then restart virtqemud, you won't get any error message. The
issue will only really become visible once someone, who might not be
the admin, tries to connect to the driver, and they won't even get a
good error message out of it.

As a consequence, I suggest we adopt a middle of the road behavior:
ignore the option, but at least log a warning that will hopefully
clue in the admin once they realize that nbdkit is not being used
after all and wonder why.

Everything else looks good, so you can consider the patch

   Reviewed-by: Andrea Bolognani 

if you agree with this idea and squash in the diff below. Feel free
to tweak the error message.


yeah, that's a good point. I've squashed your patch below and pushed it. 
I think the warning message was fine.


Jonathon




Thank you for your patience :)


diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 53eec9c43a..4050a82341 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -1075,10 +1075,8 @@
virQEMUDriverConfigLoadStorageEntry(virQEMUDriverConfig *cfg,

  #if !WITH_NBDKIT
  if (cfg->storageUseNbdkit) {
-virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-   "%s",
-   _("configuration option 'storage_use_nbdkit'
was specified, but nbdkit is not supported by this libvirt"));
-return -1;
+VIR_WARN("Ignoring configuration option 'storage_use_nbdkit':
nbdkit is not supported by this libvirt");
+cfg->storageUseNbdkit = false;
  }
  #endif /* WITH_NBDKIT */


___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


[PATCH v4] qemu: add runtime config option for nbdkit

2024-01-04 Thread Jonathon Jongsma
Currently when we build with nbdkit support, libvirt will always try to
use nbdkit to access remote disk sources when it is available. But
without an up-to-date selinux policy allowing this, it will fail.
because the required selinux policies are not yet widely available, we
have disabled nbdkit support on rpm builds for all distributions before
Fedora 40.

Unfortunately, this makes it more difficult to test nbdkit support.
After someone updates to the necessary selinux policies, they would also
need to rebuild libvirt to enable nbdkit support. By introducing a
configure option (nbdkit_config_default), we can build packages with
nbdkit support but have it disabled by default.

Signed-off-by: Jonathon Jongsma 
Suggested-by: Andrea Bolognani 
---
changes in v4
 - squashed in Andrea's suggested changes
   - updated error message
   - Changed one instance of WITH_NDBKIT to WITH_NBDKIT :)
   - tested

 libvirt.spec.in| 18 ++
 meson.build| 10 ++
 meson_options.txt  |  3 ++-
 src/qemu/libvirtd_qemu.aug |  3 +++
 src/qemu/meson.build   |  2 ++
 src/qemu/qemu.conf.in  | 11 +++
 src/qemu/qemu_conf.c   | 24 
 src/qemu/qemu_conf.h   |  2 ++
 src/qemu/qemu_domain.c |  3 +++
 src/qemu/test_libvirtd_qemu.aug.in |  1 +
 tests/qemuxml2argvtest.c   | 15 +--
 11 files changed, 81 insertions(+), 11 deletions(-)

diff --git a/libvirt.spec.in b/libvirt.spec.in
index 1d0ec5073d..2f2d713732 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -96,6 +96,7 @@
 %define with_sanlock  0
 %define with_numad0
 %define with_nbdkit   0
+%define with_nbdkit_config_default 0
 %define with_firewalld_zone   0
 %define with_netcf0
 %define with_libssh2  0
@@ -174,15 +175,17 @@
 %endif
 %endif
 
-# We should only enable nbdkit support if the OS ships a SELinux policy that
-# allows libvirt to launch it. Right now that's not the case anywhere, but
-# things should be fine by the time Fedora 40 is released.
+# We want to build with nbdkit support, but should only enable nbdkit by
+# default if the OS ships a SELinux policy that allows libvirt to launch it.
+# Right now that's not the case anywhere, but things should be fine by the time
+# Fedora 40 is released.
 #
 # TODO: add RHEL 9 once a minor release that contains the necessary SELinux
 #   bits exists (we only support the most recent minor release)
 %if %{with_qemu}
+%define with_nbdkit 0%{!?_without_nbdkit:1}
 %if 0%{?fedora} >= 40
-%define with_nbdkit 0%{!?_without_nbdkit:1}
+%define with_nbdkit_config_default 
0%{!?_without_nbdkit_config_default:1}
 %endif
 %endif
 
@@ -1207,6 +1210,12 @@ exit 1
 %define arg_nbdkit -Dnbdkit=disabled
 %endif
 
+%if %{with_nbdkit_config_default}
+%define arg_nbdkit_config_default -Dnbdkit_config_default=enabled
+%else
+%define arg_nbdkit_config_default -Dnbdkit_config_default=disabled
+%endif
+
 %if %{with_fuse}
 %define arg_fuse -Dfuse=enabled
 %else
@@ -1322,6 +1331,7 @@ export SOURCE_DATE_EPOCH=$(stat --printf='%Y' 
%{_specdir}/libvirt.spec)
%{?arg_sanlock} \
-Dlibpcap=enabled \
%{?arg_nbdkit} \
+   %{?arg_nbdkit_config_default} \
-Dlibnl=enabled \
-Daudit=enabled \
-Ddtrace=enabled \
diff --git a/meson.build b/meson.build
index 4d96b32e58..1e5e1d7954 100644
--- a/meson.build
+++ b/meson.build
@@ -1009,6 +1009,16 @@ if not conf.has('WITH_NBDKIT')
   libnbd_dep = dependency('', required: false)
 endif
 
+# default value for storage_use_nbdkit config option.
+# For now 'auto' just maps to disabled, but in the future it may depend on
+# which security drivers are enabled
+use_nbdkit_default = get_option('nbdkit_config_default').enabled()
+
+if use_nbdkit_default and not conf.has('WITH_NBDKIT')
+  error('nbdkit_config_default requires nbdkit to be enabled')
+endif
+conf.set10('USE_NBDKIT_DEFAULT', use_nbdkit_default)
+
 libnl_version = '3.0'
 if not get_option('libnl').disabled() and host_machine.system() == 'linux'
   libnl_dep = dependency('libnl-3.0', version: '>=' + libnl_version, required: 
get_option('libnl'))
diff --git a/meson_options.txt b/meson_options.txt
index a0928102bf..182e28b3d1 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -104,7 +104,8 @@ option('loader_nvram', type: 'string', value: '', 
description: 'Pass list of pai
 option('login_shell', type: 'feature', value: 'auto', description: 'build 
virt-login-shell')
 option('nss', type: 'feature', value: 'auto', description: 'enable Name 
Service Switch plugin for resolving guest IP addresses')
 option('numad', type: 'feature', value: 'auto', description: 'use numad to 
manage CPU placement dynamically')
-option('nbdkit', type: 'feature', value: 'auto', description: 'use nbdkit to 
access network

Re: [libvirt PATCH v3] qemu: add runtime config option for nbdkit

2024-01-03 Thread Jonathon Jongsma

On 1/3/24 12:37 PM, Andrea Bolognani wrote:

On Thu, Nov 30, 2023 at 05:04:11PM -0600, Jonathon Jongsma wrote:

Sorry for the delay in getting out a new version. Thanksgiving break in
the USA, etc.


... followed by holidays in Europe. We still have a few days to get
this into 10.0.0 though :)


+++ b/meson_options.txt
@@ -104,7 +104,8 @@ option('loader_nvram', type: 'string', value: '', 
description: 'Pass list of pai
  option('login_shell', type: 'feature', value: 'auto', description: 'build 
virt-login-shell')
  option('nss', type: 'feature', value: 'auto', description: 'enable Name 
Service Switch plugin for resolving guest IP addresses')
  option('numad', type: 'feature', value: 'auto', description: 'use numad to 
manage CPU placement dynamically')
-option('nbdkit', type: 'feature', value: 'auto', description: 'use nbdkit to 
access network disks')
+option('nbdkit', type: 'feature', value: 'auto', description: 'Build nbdkit 
storage backend')
+option('nbdkit_config_default', type: 'feature', value: 'disabled', 
description: 'Whether to use nbdkit storage backend for network disks by 
default (configurable)')


You can have 'auto' as the default value here, it's still going to
behave the same as 'disabled' due to the way you've implemented the
meson.build part but it'll appear more consistent with existing
options.


+++ b/src/qemu/qemu.conf.in
@@ -974,3 +974,16 @@
  # "full"-  both QEMU and its helper processes are placed into separate
  #  scheduling group
  #sched_core = "none"
+
+@CUT_WITH_NBDKIT@
+# Using nbdkit to access remote disk sources
+#
+# If this is set then libvirt will use nbdkit to access remote disk sources
+# when available. nbdkit will export an NBD share to QEMU rather than having
+# QEMU attempt to access the remote server directly.
+#
+# Possible values are 0 or 1. Default value is @USE_NBDKIT_DEFAULT@. Please
+# note that the default might change in future releases.
+#
+# storage_use_nbdkit = @USE_NBDKIT_DEFAULT@
+@END@


I think this is unnecessary. It's okay to leave the comment in there
even if ndbkit support is compiled out. More on this below.


I'm happy to drop all of this stuff. But just by way of explanation, but 
after your comments on v2, I decided to try to mimic the only other 
configuration option in libvirt that could be compiled out: the WITH_IP 
build configuration in the remote driver.




Either way, the line for the option itself needs to look like

   #storage_use_nbdkit = @USE_NBDKIT_DEFAULT@

Note the lack of whitespace between the comment marker and the option
name. That's not just for looks: the augeas test requires this
specific arrangement.

To make the augeas test I've just mentioned work, you also need to
squash in the following:

   diff --git a/src/qemu/test_libvirtd_qemu.aug.in
b/src/qemu/test_libvirtd_qemu.aug.in
   index c730df40b0..e4cfde6cc7 100644
   --- a/src/qemu/test_libvirtd_qemu.aug.in
   +++ b/src/qemu/test_libvirtd_qemu.aug.in
   @@ -117,3 +117,4 @@ module Test_libvirtd_qemu =
}
{ "deprecation_behavior" = "none" }
{ "sched_core" = "none" }
   +{ "storage_use_nbdkit" = "@USE_NBDKIT_DEFAULT@" }

This demonstrates that augeas is really picking up the value for the
option and interpreting it correctly.


Oops, thanks for catching that.




+++ b/src/qemu/meson.build
@@ -137,9 +137,41 @@ if conf.has('WITH_QEMU')
+  # preprocess config files to remove items related to features that are not
+  # compiled in
+  preprocess_config_files =  [
+{
+  'inpath': 'qemu.conf.in',
+  'outpath': 'qemu.conf.tmp',
+  'outvar': 'qemu_conf_tmp',
+},
+{
+  'inpath': 'libvirtd_qemu.aug.in',
+  'outpath': 'libvirtd_qemu.aug',
+  'outvar': 'libvirtd_qemu_aug',
+}
+  ]
+  foreach item : preprocess_config_files
+if conf.has('WITH_NBDKIT')
+  preprocess_cmd = [ 'sed', '-e', '/[@]CUT_WITH_NBDKIT[@]/d', '-e', 
'/[@]END[@]/d', '@INPUT@' ]
+else
+  preprocess_cmd = [ 'sed', '-e', '/[@]CUT_WITH_NBDKIT[@]/,/[@]END[@]/d', 
'@INPUT@' ]
+endif
+
+tmp = configure_file(
+  input: item['inpath'],
+  output: item['outpath'],
+  command: preprocess_cmd,
+  capture: true,
+)
+set_variable(item['outvar'], tmp)
+  endforeach


Once you stop cutting out the bits of the config file related to
nbdkit when nbdkit support is compiled out, you no longer need any of
this additional complexity.


+++ b/src/qemu/qemu_conf.c
@@ -1065,6 +1066,19 @@ 
virQEMUDriverConfigLoadCapsFiltersEntry(virQEMUDriverConfig *cfg,
  }


+#if WITH_NBDKIT
+static int
+virQEMUDriverConfigLoadStorageEntry(virQEMUDriverConfig *cfg,
+virConf *conf)
+{
+if (virConfGetValueBool(conf, "storage_use_nbdkit", >storageUseNbdkit) 
< 0)
+return -1;
+
+return 0;
+}
+#endif /* WITH_NBDKIT */


When parsing the configuration file, we shouldn't make this part
co

[PATCH v3 08/12] cpu_map: Add versioned Intel Icelake CPUs

2023-12-15 Thread Jonathon Jongsma
Signed-off-by: Jonathon Jongsma 
---
 src/cpu_map/index.xml |   4 +
 src/cpu_map/meson.build   |   4 +
 src/cpu_map/x86_Icelake-Server-v3.xml | 103 +
 src/cpu_map/x86_Icelake-Server-v4.xml | 108 +
 src/cpu_map/x86_Icelake-Server-v5.xml | 109 ++
 src/cpu_map/x86_Icelake-Server-v6.xml | 109 ++
 .../domaincapsdata/qemu_5.0.0-q35.x86_64.xml  |   1 +
 .../domaincapsdata/qemu_5.0.0-tcg.x86_64.xml  |   1 +
 tests/domaincapsdata/qemu_5.0.0.x86_64.xml|   1 +
 .../domaincapsdata/qemu_5.1.0-q35.x86_64.xml  |   2 +
 .../domaincapsdata/qemu_5.1.0-tcg.x86_64.xml  |   2 +
 tests/domaincapsdata/qemu_5.1.0.x86_64.xml|   2 +
 .../domaincapsdata/qemu_5.2.0-q35.x86_64.xml  |   2 +
 .../domaincapsdata/qemu_5.2.0-tcg.x86_64.xml  |   2 +
 tests/domaincapsdata/qemu_5.2.0.x86_64.xml|   2 +
 .../domaincapsdata/qemu_6.0.0-q35.x86_64.xml  |   2 +
 .../domaincapsdata/qemu_6.0.0-tcg.x86_64.xml  |   2 +
 tests/domaincapsdata/qemu_6.0.0.x86_64.xml|   2 +
 .../domaincapsdata/qemu_6.1.0-q35.x86_64.xml  |   3 +
 .../domaincapsdata/qemu_6.1.0-tcg.x86_64.xml  |   3 +
 tests/domaincapsdata/qemu_6.1.0.x86_64.xml|   3 +
 .../domaincapsdata/qemu_6.2.0-q35.x86_64.xml  |   3 +
 .../domaincapsdata/qemu_6.2.0-tcg.x86_64.xml  |   3 +
 tests/domaincapsdata/qemu_6.2.0.x86_64.xml|   3 +
 .../domaincapsdata/qemu_7.0.0-q35.x86_64.xml  |   4 +
 .../domaincapsdata/qemu_7.0.0-tcg.x86_64.xml  |   4 +
 tests/domaincapsdata/qemu_7.0.0.x86_64.xml|   4 +
 .../domaincapsdata/qemu_7.1.0-q35.x86_64.xml  |   4 +
 .../domaincapsdata/qemu_7.1.0-tcg.x86_64.xml  |   4 +
 tests/domaincapsdata/qemu_7.1.0.x86_64.xml|   4 +
 .../domaincapsdata/qemu_7.2.0-q35.x86_64.xml  |   4 +
 .../qemu_7.2.0-tcg.x86_64+hvf.xml |   4 +
 .../domaincapsdata/qemu_7.2.0-tcg.x86_64.xml  |   4 +
 tests/domaincapsdata/qemu_7.2.0.x86_64.xml|   4 +
 .../domaincapsdata/qemu_8.0.0-q35.x86_64.xml  |   4 +
 .../domaincapsdata/qemu_8.0.0-tcg.x86_64.xml  |   4 +
 tests/domaincapsdata/qemu_8.0.0.x86_64.xml|   4 +
 .../domaincapsdata/qemu_8.1.0-q35.x86_64.xml  |   4 +
 .../domaincapsdata/qemu_8.1.0-tcg.x86_64.xml  |   4 +
 tests/domaincapsdata/qemu_8.1.0.x86_64.xml|   4 +
 .../domaincapsdata/qemu_8.2.0-q35.x86_64.xml  |   4 +
 .../domaincapsdata/qemu_8.2.0-tcg.x86_64.xml  |   4 +
 tests/domaincapsdata/qemu_8.2.0.x86_64.xml|   4 +
 43 files changed, 552 insertions(+)
 create mode 100644 src/cpu_map/x86_Icelake-Server-v3.xml
 create mode 100644 src/cpu_map/x86_Icelake-Server-v4.xml
 create mode 100644 src/cpu_map/x86_Icelake-Server-v5.xml
 create mode 100644 src/cpu_map/x86_Icelake-Server-v6.xml

diff --git a/src/cpu_map/index.xml b/src/cpu_map/index.xml
index ad6361ee51..c0971c9391 100644
--- a/src/cpu_map/index.xml
+++ b/src/cpu_map/index.xml
@@ -60,6 +60,10 @@
 
 
 
+
+
+
+
 
 
 
diff --git a/src/cpu_map/meson.build b/src/cpu_map/meson.build
index 7a3712280a..6e77f78b1c 100644
--- a/src/cpu_map/meson.build
+++ b/src/cpu_map/meson.build
@@ -59,6 +59,10 @@ cpumap_data = [
   'x86_Icelake-Client-noTSX.xml',
   'x86_Icelake-Client.xml',
   'x86_Icelake-Server-noTSX.xml',
+  'x86_Icelake-Server-v3.xml',
+  'x86_Icelake-Server-v4.xml',
+  'x86_Icelake-Server-v5.xml',
+  'x86_Icelake-Server-v6.xml',
   'x86_Icelake-Server.xml',
   'x86_IvyBridge-IBRS.xml',
   'x86_IvyBridge.xml',
diff --git a/src/cpu_map/x86_Icelake-Server-v3.xml 
b/src/cpu_map/x86_Icelake-Server-v3.xml
new file mode 100644
index 00..070951108a
--- /dev/null
+++ b/src/cpu_map/x86_Icelake-Server-v3.xml
@@ -0,0 +1,103 @@
+
+
+  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  
+
diff --git a/src/cpu_map/x86_Icelake-Server-v4.xml 
b/src/cpu_map/x86_Icelake-Server-v4.xml
new file mode 100644
index 00..a65271e801
--- /dev/null
+++ b/src/cpu_map/x86_Icelake-Server-v4.xml
@@ -0,0 +1,108

[PATCH v3 10/12] cpu_map: Add versioned Intel Snowridge CPUs

2023-12-15 Thread Jonathon Jongsma
Signed-off-by: Jonathon Jongsma 
---
 src/cpu_map/index.xml |  3 +
 src/cpu_map/meson.build   |  3 +
 src/cpu_map/x86_Snowridge-v2.xml  | 78 ++
 src/cpu_map/x86_Snowridge-v3.xml  | 80 +++
 src/cpu_map/x86_Snowridge-v4.xml  | 78 ++
 .../x86_64-cpuid-Atom-P5362-guest.xml |  3 +-
 .../x86_64-cpuid-Atom-P5362-json.xml  |  3 +-
 .../domaincapsdata/qemu_4.2.0-q35.x86_64.xml  |  1 +
 .../domaincapsdata/qemu_4.2.0-tcg.x86_64.xml  |  1 +
 tests/domaincapsdata/qemu_4.2.0.x86_64.xml|  1 +
 .../domaincapsdata/qemu_5.0.0-q35.x86_64.xml  |  1 +
 .../domaincapsdata/qemu_5.0.0-tcg.x86_64.xml  |  1 +
 tests/domaincapsdata/qemu_5.0.0.x86_64.xml|  1 +
 .../domaincapsdata/qemu_5.1.0-q35.x86_64.xml  |  1 +
 .../domaincapsdata/qemu_5.1.0-tcg.x86_64.xml  |  1 +
 tests/domaincapsdata/qemu_5.1.0.x86_64.xml|  1 +
 .../domaincapsdata/qemu_5.2.0-q35.x86_64.xml  |  1 +
 .../domaincapsdata/qemu_5.2.0-tcg.x86_64.xml  |  1 +
 tests/domaincapsdata/qemu_5.2.0.x86_64.xml|  1 +
 .../domaincapsdata/qemu_6.0.0-q35.x86_64.xml  |  1 +
 .../domaincapsdata/qemu_6.0.0-tcg.x86_64.xml  |  1 +
 tests/domaincapsdata/qemu_6.0.0.x86_64.xml|  1 +
 .../domaincapsdata/qemu_6.1.0-q35.x86_64.xml  |  2 +
 .../domaincapsdata/qemu_6.1.0-tcg.x86_64.xml  |  2 +
 tests/domaincapsdata/qemu_6.1.0.x86_64.xml|  2 +
 .../domaincapsdata/qemu_6.2.0-q35.x86_64.xml  |  3 +
 .../domaincapsdata/qemu_6.2.0-tcg.x86_64.xml  |  3 +
 tests/domaincapsdata/qemu_6.2.0.x86_64.xml|  3 +
 .../domaincapsdata/qemu_7.0.0-q35.x86_64.xml  |  3 +
 .../domaincapsdata/qemu_7.0.0-tcg.x86_64.xml  |  3 +
 tests/domaincapsdata/qemu_7.0.0.x86_64.xml|  3 +
 .../domaincapsdata/qemu_7.1.0-q35.x86_64.xml  |  3 +
 .../domaincapsdata/qemu_7.1.0-tcg.x86_64.xml  |  3 +
 tests/domaincapsdata/qemu_7.1.0.x86_64.xml|  3 +
 .../domaincapsdata/qemu_7.2.0-q35.x86_64.xml  |  3 +
 .../qemu_7.2.0-tcg.x86_64+hvf.xml |  3 +
 .../domaincapsdata/qemu_7.2.0-tcg.x86_64.xml  |  3 +
 tests/domaincapsdata/qemu_7.2.0.x86_64.xml|  3 +
 .../domaincapsdata/qemu_8.0.0-q35.x86_64.xml  |  3 +
 .../domaincapsdata/qemu_8.0.0-tcg.x86_64.xml  |  3 +
 tests/domaincapsdata/qemu_8.0.0.x86_64.xml|  3 +
 .../domaincapsdata/qemu_8.1.0-q35.x86_64.xml  |  3 +
 .../domaincapsdata/qemu_8.1.0-tcg.x86_64.xml  |  3 +
 tests/domaincapsdata/qemu_8.1.0.x86_64.xml|  3 +
 .../domaincapsdata/qemu_8.2.0-q35.x86_64.xml  |  3 +
 .../domaincapsdata/qemu_8.2.0-tcg.x86_64.xml  |  3 +
 tests/domaincapsdata/qemu_8.2.0.x86_64.xml|  3 +
 47 files changed, 331 insertions(+), 4 deletions(-)
 create mode 100644 src/cpu_map/x86_Snowridge-v2.xml
 create mode 100644 src/cpu_map/x86_Snowridge-v3.xml
 create mode 100644 src/cpu_map/x86_Snowridge-v4.xml

diff --git a/src/cpu_map/index.xml b/src/cpu_map/index.xml
index 3d8be6e41a..449abbd8f3 100644
--- a/src/cpu_map/index.xml
+++ b/src/cpu_map/index.xml
@@ -67,6 +67,9 @@
 
 
 
+
+
+
 
 
 
diff --git a/src/cpu_map/meson.build b/src/cpu_map/meson.build
index a6db0b1503..073fd66bec 100644
--- a/src/cpu_map/meson.build
+++ b/src/cpu_map/meson.build
@@ -97,6 +97,9 @@ cpumap_data = [
   'x86_Skylake-Server-v4.xml',
   'x86_Skylake-Server-v5.xml',
   'x86_Skylake-Server.xml',
+  'x86_Snowridge-v2.xml',
+  'x86_Snowridge-v3.xml',
+  'x86_Snowridge-v4.xml',
   'x86_Snowridge.xml',
   'x86_vendors.xml',
   'x86_Westmere-IBRS.xml',
diff --git a/src/cpu_map/x86_Snowridge-v2.xml b/src/cpu_map/x86_Snowridge-v2.xml
new file mode 100644
index 00..59b7aafe8d
--- /dev/null
+++ b/src/cpu_map/x86_Snowridge-v2.xml
@@ -0,0 +1,78 @@
+
+
+  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  
+
diff --git a/src/cpu_map/x86_Snowridge-v3.xml b/src/cpu_map/x86_Snowridge-v3.xml
new file mode 100644
index 00..949c5d2633
--- /dev/null
+++ b/src/cpu_map/x86_Snowridge-v3.xml
@@ -0,0 +1,80 @@
+
+
+  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  
+
diff --git a/src/cpu_map/x86_Snowridge-v4.xml b/src/cpu_map/x86_Snowridge-v4.xml
new file mode 100644
index 00..818e75f90d
--- /dev/null
+++ b/src/cpu_map/x86_Snowridge-v4.xml
@@ -0,0 +1,78

[PATCH v3 12/12] cpu_map: Add versioned Dhyana CPUs

2023-12-15 Thread Jonathon Jongsma
Signed-off-by: Jonathon Jongsma 
---
 src/cpu_map/index.xml |  1 +
 src/cpu_map/meson.build   |  1 +
 src/cpu_map/x86_Dhyana-v2.xml | 81 +++
 ..._64-cpuid-Hygon-C86-7185-32-core-guest.xml |  5 +-
 ...6_64-cpuid-Hygon-C86-7185-32-core-host.xml |  5 +-
 ...6_64-cpuid-Hygon-C86-7185-32-core-json.xml |  6 +-
 .../domaincapsdata/qemu_6.1.0-q35.x86_64.xml  |  1 +
 .../domaincapsdata/qemu_6.1.0-tcg.x86_64.xml  |  1 +
 tests/domaincapsdata/qemu_6.1.0.x86_64.xml|  1 +
 .../domaincapsdata/qemu_6.2.0-q35.x86_64.xml  |  1 +
 .../domaincapsdata/qemu_6.2.0-tcg.x86_64.xml  |  1 +
 tests/domaincapsdata/qemu_6.2.0.x86_64.xml|  1 +
 .../domaincapsdata/qemu_7.0.0-q35.x86_64.xml  |  1 +
 .../domaincapsdata/qemu_7.0.0-tcg.x86_64.xml  |  1 +
 tests/domaincapsdata/qemu_7.0.0.x86_64.xml|  1 +
 .../domaincapsdata/qemu_7.1.0-q35.x86_64.xml  |  1 +
 .../domaincapsdata/qemu_7.1.0-tcg.x86_64.xml  |  1 +
 tests/domaincapsdata/qemu_7.1.0.x86_64.xml|  1 +
 .../domaincapsdata/qemu_7.2.0-q35.x86_64.xml  |  1 +
 .../qemu_7.2.0-tcg.x86_64+hvf.xml |  1 +
 .../domaincapsdata/qemu_7.2.0-tcg.x86_64.xml  |  1 +
 tests/domaincapsdata/qemu_7.2.0.x86_64.xml|  1 +
 .../domaincapsdata/qemu_8.0.0-q35.x86_64.xml  |  1 +
 .../domaincapsdata/qemu_8.0.0-tcg.x86_64.xml  |  1 +
 tests/domaincapsdata/qemu_8.0.0.x86_64.xml|  1 +
 .../domaincapsdata/qemu_8.1.0-q35.x86_64.xml  |  1 +
 .../domaincapsdata/qemu_8.1.0-tcg.x86_64.xml  |  1 +
 tests/domaincapsdata/qemu_8.1.0.x86_64.xml|  1 +
 .../domaincapsdata/qemu_8.2.0-q35.x86_64.xml  |  1 +
 .../domaincapsdata/qemu_8.2.0-tcg.x86_64.xml  |  1 +
 tests/domaincapsdata/qemu_8.2.0.x86_64.xml|  1 +
 31 files changed, 112 insertions(+), 12 deletions(-)
 create mode 100644 src/cpu_map/x86_Dhyana-v2.xml

diff --git a/src/cpu_map/index.xml b/src/cpu_map/index.xml
index 9b3719c5ef..e643aa01be 100644
--- a/src/cpu_map/index.xml
+++ b/src/cpu_map/index.xml
@@ -95,6 +95,7 @@
 
 
 
+
   
 
   
diff --git a/src/cpu_map/meson.build b/src/cpu_map/meson.build
index 4b2a90fd74..e16a16c276 100644
--- a/src/cpu_map/meson.build
+++ b/src/cpu_map/meson.build
@@ -40,6 +40,7 @@ cpumap_data = [
   'x86_coreduo.xml',
   'x86_cpu64-rhel5.xml',
   'x86_cpu64-rhel6.xml',
+  'x86_Dhyana-v2.xml',
   'x86_Dhyana.xml',
   'x86_EPYC-IBPB.xml',
   'x86_EPYC.xml',
diff --git a/src/cpu_map/x86_Dhyana-v2.xml b/src/cpu_map/x86_Dhyana-v2.xml
new file mode 100644
index 00..d5568e77b3
--- /dev/null
+++ b/src/cpu_map/x86_Dhyana-v2.xml
@@ -0,0 +1,81 @@
+
+
+  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  
+
diff --git a/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-guest.xml 
b/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-guest.xml
index 8669e5bd1b..0b318b94c4 100644
--- a/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-guest.xml
+++ b/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-guest.xml
@@ -1,10 +1,9 @@
 
-  Dhyana
+  Dhyana-v2
   Hygon
   
   
   
-  
   
   
   
@@ -16,10 +15,8 @@
   
   
   
-  
   
   
-  
   
   
   
diff --git a/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-host.xml 
b/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-host.xml
index ddb14c0440..74c751ad1f 100644
--- a/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-host.xml
+++ b/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-host.xml
@@ -1,12 +1,11 @@
 
   x86_64
-  Dhyana
+  Dhyana-v2
   Hygon
   
   
   
   
-  
   
   
   
@@ -18,10 +17,8 @@
   
   
   
-  
   
   
-  
   
   
   
diff --git a/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-json.xml 
b/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-json.xml
index 0408d51c10..2ff92e2c15 100644
--- a/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-json.xml
+++ b/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-json.xml
@@ -1,5 +1,5 @@
 
-  Dhyana
+  Dhyana-v2
   Hygon
   
   
@@ -7,8 +7,6 @@
   
   
   
-  
-  
+  
   
-  
 
diff --git a/tests/domaincapsdata/qemu_6.1.0-q35.x86_64.xml 
b/tests/domaincapsdata/qemu_6.1.0-q35.x86_64.xml
index 59276428c1..31c8a5d4ed 100644
--- a/tests/domaincapsdata/qemu_6.1.0-q35.x86_64.xml
+++ b/tests/domaincapsdata/qemu_6.1.0-q35.x86_64.xml
@@ -118,6 +118,7 @@
   EPYC-Milan
   EPYC-IBPB
   EPYC
+  Dhyana-v2
   Dhyana
   Cooperlake-v2
   Cooperlake
diff --git a/tests/domaincapsdata/qemu_6.1.0-tcg.x86_64.xml 
b/tests/domaincapsdata/qemu_6.1.0-tcg.x86_64.xml
index eff9d4c8eb..b9e671e1f7 100644
--- a/tests/domaincapsdata/qemu_6.1.0-tcg.x86_64.xml
+++ b/tests/domaincapsdata/qemu_6.1.0-tcg.x86_64

[PATCH v3 04/12] qemu: use canonical name for CPU models

2023-12-15 Thread Jonathon Jongsma
As described in detail in the commit "cpu_map: add canonical names to
existing CPU models", the unversioned CPU model names are not
migration-safe. If qemu makes the anticipated changes to CPU alias
mapping, an unversioned CPU model may be represented by different
underlying CPU models on different hosts. To avoid being susceptible to
this issue, use the new 'canonical_name' property of the CPU definition
to always specify a specific versioned CPU model version to qemu rather
than using CPU model aliases.

This canonical name is only used in the qemu backend and is not exposed
to the user in anyway. The libvirt CPU configuration will continue to
use existing unversioned model names in the domain xml for continuity.
But internally we will translate these to a specific version.

Signed-off-by: Jonathon Jongsma 
---
 src/qemu/qemu_command.c  | 5 -
 tests/qemuxml2argvdata/cpu-Haswell-noTSX.x86_64-latest.args  | 2 +-
 tests/qemuxml2argvdata/cpu-Haswell.x86_64-latest.args| 2 +-
 tests/qemuxml2argvdata/cpu-Haswell2.x86_64-latest.args   | 2 +-
 tests/qemuxml2argvdata/cpu-Haswell3.x86_64-latest.args   | 2 +-
 .../cpu-Icelake-Server-pconfig.x86_64-latest.args| 2 +-
 tests/qemuxml2argvdata/cpu-cache-disable3.x86_64-latest.args | 2 +-
 .../cpu-check-default-partial.x86_64-latest.args | 2 +-
 tests/qemuxml2argvdata/cpu-fallback.x86_64-5.2.0.args| 2 +-
 tests/qemuxml2argvdata/cpu-fallback.x86_64-8.0.0.args| 2 +-
 tests/qemuxml2argvdata/cpu-host-model-cmt.x86_64-latest.args | 2 +-
 .../cpu-host-model-fallback-kvm.x86_64-4.2.0.args| 2 +-
 .../cpu-host-model-fallback-kvm.x86_64-5.0.0.args| 2 +-
 .../cpu-host-model-fallback-kvm.x86_64-5.1.0.args| 2 +-
 .../cpu-host-model-fallback-kvm.x86_64-5.2.0.args| 2 +-
 .../cpu-host-model-fallback-kvm.x86_64-6.0.0.args| 2 +-
 .../cpu-host-model-fallback-kvm.x86_64-6.1.0.args| 2 +-
 .../cpu-host-model-fallback-kvm.x86_64-6.2.0.args| 2 +-
 .../cpu-host-model-fallback-kvm.x86_64-7.0.0.args| 2 +-
 .../cpu-host-model-fallback-kvm.x86_64-7.1.0.args| 2 +-
 .../cpu-host-model-fallback-kvm.x86_64-7.2.0.args| 2 +-
 .../cpu-host-model-fallback-kvm.x86_64-8.0.0.args| 2 +-
 .../cpu-host-model-fallback-kvm.x86_64-8.1.0.args| 2 +-
 .../cpu-host-model-fallback-kvm.x86_64-latest.args   | 2 +-
 .../cpu-host-model-fallback-tcg.x86_64-7.2.0.args| 2 +-
 .../cpu-host-model-fallback-tcg.x86_64-8.0.0.args| 2 +-
 .../cpu-host-model-fallback-tcg.x86_64-8.1.0.args| 2 +-
 .../cpu-host-model-fallback-tcg.x86_64-latest.args   | 2 +-
 tests/qemuxml2argvdata/cpu-host-model-kvm.x86_64-4.2.0.args  | 2 +-
 tests/qemuxml2argvdata/cpu-host-model-kvm.x86_64-5.0.0.args  | 2 +-
 tests/qemuxml2argvdata/cpu-host-model-kvm.x86_64-5.1.0.args  | 2 +-
 tests/qemuxml2argvdata/cpu-host-model-kvm.x86_64-5.2.0.args  | 2 +-
 tests/qemuxml2argvdata/cpu-host-model-kvm.x86_64-6.0.0.args  | 2 +-
 tests/qemuxml2argvdata/cpu-host-model-kvm.x86_64-6.1.0.args  | 2 +-
 tests/qemuxml2argvdata/cpu-host-model-kvm.x86_64-6.2.0.args  | 2 +-
 tests/qemuxml2argvdata/cpu-host-model-kvm.x86_64-7.0.0.args  | 2 +-
 tests/qemuxml2argvdata/cpu-host-model-kvm.x86_64-7.1.0.args  | 2 +-
 tests/qemuxml2argvdata/cpu-host-model-kvm.x86_64-7.2.0.args  | 2 +-
 tests/qemuxml2argvdata/cpu-host-model-kvm.x86_64-8.0.0.args  | 2 +-
 tests/qemuxml2argvdata/cpu-host-model-kvm.x86_64-8.1.0.args  | 2 +-
 tests/qemuxml2argvdata/cpu-host-model-kvm.x86_64-latest.args | 2 +-
 .../cpu-host-model-nofallback-kvm.x86_64-4.2.0.args  | 2 +-
 .../cpu-host-model-nofallback-kvm.x86_64-5.0.0.args  | 2 +-
 .../cpu-host-model-nofallback-kvm.x86_64-5.1.0.args  | 2 +-
 .../cpu-host-model-nofallback-kvm.x86_64-5.2.0.args  | 2 +-
 .../cpu-host-model-nofallback-kvm.x86_64-6.0.0.args  | 2 +-
 .../cpu-host-model-nofallback-kvm.x86_64-6.1.0.args  | 2 +-
 .../cpu-host-model-nofallback-kvm.x86_64-6.2.0.args  | 2 +-
 .../cpu-host-model-nofallback-kvm.x86_64-7.0.0.args  | 2 +-
 .../cpu-host-model-nofallback-kvm.x86_64-7.1.0.args  | 2 +-
 .../cpu-host-model-nofallback-kvm.x86_64-7.2.0.args  | 2 +-
 .../cpu-host-model-nofallback-kvm.x86_64-8.0.0.args  | 2 +-
 .../cpu-host-model-nofallback-kvm.x86_64-8.1.0.args  | 2 +-
 .../cpu-host-model-nofallback-kvm.x86_64-latest.args | 2 +-
 .../cpu-host-model-nofallback-tcg.x86_64-7.2.0.args  | 2 +-
 .../cpu-host-model-nofallback-tcg.x86_64-8.0.0.args  | 2 +-
 .../cpu-host-model-nofallback-tcg.x86_64-8.1.0.args  | 2 +-
 .../cpu-host-model-nofallback-tcg.x86_64-latest.args | 2 +-
 tests/qemuxml2argvdata/cpu-host-model-tcg.x86_64-7.2.0.args  | 2 +-
 tests/qemuxml2argvdata/cpu-host-model-tcg.x86_64-8.0.0.args  | 2 +-
 tests/qemuxml2ar

[PATCH v3 07/12] cpu_map: Add versioned Intel Cascadelake CPUs

2023-12-15 Thread Jonathon Jongsma
Signed-off-by: Jonathon Jongsma 
---
 src/cpu_map/index.xml |  3 +
 src/cpu_map/meson.build   |  3 +
 src/cpu_map/x86_Cascadelake-Server-v2.xml | 93 +++
 src/cpu_map/x86_Cascadelake-Server-v4.xml | 91 ++
 src/cpu_map/x86_Cascadelake-Server-v5.xml | 92 ++
 .../x86_64-cpuid-Xeon-Platinum-8268-guest.xml |  9 +-
 .../x86_64-cpuid-Xeon-Platinum-8268-host.xml  |  9 +-
 .../x86_64-cpuid-Xeon-Platinum-9242-guest.xml |  9 +-
 .../x86_64-cpuid-Xeon-Platinum-9242-host.xml  |  9 +-
 .../x86_64-cpuid-Xeon-Platinum-9242-json.xml  |  9 +-
 ..._64-cpuid-baseline-Cascadelake+Icelake.xml |  9 +-
 ...-cpuid-baseline-Cooperlake+Cascadelake.xml |  9 +-
 ...6_64-cpuid-baseline-Cooperlake+Icelake.xml |  9 +-
 .../domaincapsdata/qemu_4.2.0-q35.x86_64.xml  |  1 +
 .../domaincapsdata/qemu_4.2.0-tcg.x86_64.xml  |  1 +
 tests/domaincapsdata/qemu_4.2.0.x86_64.xml|  1 +
 .../domaincapsdata/qemu_5.0.0-q35.x86_64.xml  |  1 +
 .../domaincapsdata/qemu_5.0.0-tcg.x86_64.xml  |  1 +
 tests/domaincapsdata/qemu_5.0.0.x86_64.xml|  1 +
 .../domaincapsdata/qemu_5.1.0-q35.x86_64.xml  |  2 +
 .../domaincapsdata/qemu_5.1.0-tcg.x86_64.xml  |  2 +
 tests/domaincapsdata/qemu_5.1.0.x86_64.xml|  2 +
 .../domaincapsdata/qemu_5.2.0-q35.x86_64.xml  |  2 +
 .../domaincapsdata/qemu_5.2.0-tcg.x86_64.xml  |  2 +
 tests/domaincapsdata/qemu_5.2.0.x86_64.xml|  2 +
 .../domaincapsdata/qemu_6.0.0-q35.x86_64.xml  |  2 +
 .../domaincapsdata/qemu_6.0.0-tcg.x86_64.xml  |  2 +
 tests/domaincapsdata/qemu_6.0.0.x86_64.xml|  2 +
 .../domaincapsdata/qemu_6.1.0-q35.x86_64.xml  |  3 +
 .../domaincapsdata/qemu_6.1.0-tcg.x86_64.xml  |  3 +
 tests/domaincapsdata/qemu_6.1.0.x86_64.xml|  3 +
 .../domaincapsdata/qemu_6.2.0-q35.x86_64.xml  |  3 +
 .../domaincapsdata/qemu_6.2.0-tcg.x86_64.xml  |  3 +
 tests/domaincapsdata/qemu_6.2.0.x86_64.xml|  3 +
 .../domaincapsdata/qemu_7.0.0-q35.x86_64.xml  |  3 +
 .../domaincapsdata/qemu_7.0.0-tcg.x86_64.xml  |  3 +
 tests/domaincapsdata/qemu_7.0.0.x86_64.xml|  3 +
 .../domaincapsdata/qemu_7.1.0-q35.x86_64.xml  |  3 +
 .../domaincapsdata/qemu_7.1.0-tcg.x86_64.xml  |  3 +
 tests/domaincapsdata/qemu_7.1.0.x86_64.xml|  3 +
 .../domaincapsdata/qemu_7.2.0-q35.x86_64.xml  |  3 +
 .../qemu_7.2.0-tcg.x86_64+hvf.xml |  3 +
 .../domaincapsdata/qemu_7.2.0-tcg.x86_64.xml  |  3 +
 tests/domaincapsdata/qemu_7.2.0.x86_64.xml|  3 +
 .../domaincapsdata/qemu_8.0.0-q35.x86_64.xml  |  3 +
 .../domaincapsdata/qemu_8.0.0-tcg.x86_64.xml  |  3 +
 tests/domaincapsdata/qemu_8.0.0.x86_64.xml|  3 +
 .../domaincapsdata/qemu_8.1.0-q35.x86_64.xml  |  3 +
 .../domaincapsdata/qemu_8.1.0-tcg.x86_64.xml  |  3 +
 tests/domaincapsdata/qemu_8.1.0.x86_64.xml|  3 +
 .../domaincapsdata/qemu_8.2.0-q35.x86_64.xml  |  3 +
 .../domaincapsdata/qemu_8.2.0-tcg.x86_64.xml  |  3 +
 tests/domaincapsdata/qemu_8.2.0.x86_64.xml|  3 +
 53 files changed, 399 insertions(+), 54 deletions(-)
 create mode 100644 src/cpu_map/x86_Cascadelake-Server-v2.xml
 create mode 100644 src/cpu_map/x86_Cascadelake-Server-v4.xml
 create mode 100644 src/cpu_map/x86_Cascadelake-Server-v5.xml

diff --git a/src/cpu_map/index.xml b/src/cpu_map/index.xml
index a4fe2ec781..ad6361ee51 100644
--- a/src/cpu_map/index.xml
+++ b/src/cpu_map/index.xml
@@ -53,6 +53,9 @@
 
 
 
+
+
+
 
 
 
diff --git a/src/cpu_map/meson.build b/src/cpu_map/meson.build
index f6b95863b3..7a3712280a 100644
--- a/src/cpu_map/meson.build
+++ b/src/cpu_map/meson.build
@@ -29,6 +29,9 @@ cpumap_data = [
   'x86_Broadwell-noTSX.xml',
   'x86_Broadwell.xml',
   'x86_Cascadelake-Server-noTSX.xml',
+  'x86_Cascadelake-Server-v2.xml',
+  'x86_Cascadelake-Server-v4.xml',
+  'x86_Cascadelake-Server-v5.xml',
   'x86_Cascadelake-Server.xml',
   'x86_Conroe.xml',
   'x86_Cooperlake.xml',
diff --git a/src/cpu_map/x86_Cascadelake-Server-v2.xml 
b/src/cpu_map/x86_Cascadelake-Server-v2.xml
new file mode 100644
index 00..5152f0390b
--- /dev/null
+++ b/src/cpu_map/x86_Cascadelake-Server-v2.xml
@@ -0,0 +1,93 @@
+
+
+  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  
+
diff --git a/src/cpu_map/x86_Cascadelake-Server-v4.xml 
b/src/cpu_map/x86_Cascadelake-Server-v4.xml
new file mode 100644
index 00..b2173d1308
--- /dev/null
+++ b/src/cpu_map/x86_Cascadelake-Server-v4.xml
@@ -0,0 +1,91

[PATCH v3 05/12] cpu_map: Add versioned EPYC CPUs

2023-12-15 Thread Jonathon Jongsma
Signed-off-by: Jonathon Jongsma 
---
 src/cpu_map/index.xml |   6 +
 src/cpu_map/meson.build   |   6 +
 src/cpu_map/x86_EPYC-Milan-v2.xml | 108 ++
 src/cpu_map/x86_EPYC-Rome-v2.xml  |  93 +++
 src/cpu_map/x86_EPYC-Rome-v3.xml  |  95 +++
 src/cpu_map/x86_EPYC-Rome-v4.xml  |  94 +++
 src/cpu_map/x86_EPYC-v3.xml   |  87 ++
 src/cpu_map/x86_EPYC-v4.xml   |  88 ++
 .../x86_64-cpuid-EPYC-7502-32-Core-host.xml   |   5 +-
 .../x86_64-cpuid-EPYC-7601-32-Core-guest.xml  |   9 +-
 ...6_64-cpuid-EPYC-7601-32-Core-ibpb-host.xml |   8 +-
 ...4-cpuid-Ryzen-7-1800X-Eight-Core-guest.xml |   9 +-
 .../domaincapsdata/qemu_5.0.0-q35.x86_64.xml  |   1 +
 .../domaincapsdata/qemu_5.0.0-tcg.x86_64.xml  |   1 +
 tests/domaincapsdata/qemu_5.0.0.x86_64.xml|   1 +
 .../domaincapsdata/qemu_5.1.0-q35.x86_64.xml  |   1 +
 .../domaincapsdata/qemu_5.1.0-tcg.x86_64.xml  |   1 +
 tests/domaincapsdata/qemu_5.1.0.x86_64.xml|   1 +
 .../domaincapsdata/qemu_5.2.0-q35.x86_64.xml  |   1 +
 .../domaincapsdata/qemu_5.2.0-tcg.x86_64.xml  |   1 +
 tests/domaincapsdata/qemu_5.2.0.x86_64.xml|   1 +
 .../domaincapsdata/qemu_6.0.0-q35.x86_64.xml  |   2 +
 .../domaincapsdata/qemu_6.0.0-tcg.x86_64.xml  |   2 +
 tests/domaincapsdata/qemu_6.0.0.x86_64.xml|   2 +
 .../domaincapsdata/qemu_6.1.0-q35.x86_64.xml  |   2 +
 .../domaincapsdata/qemu_6.1.0-tcg.x86_64.xml  |   2 +
 tests/domaincapsdata/qemu_6.1.0.x86_64.xml|   2 +
 .../domaincapsdata/qemu_6.2.0-q35.x86_64.xml  |   2 +
 .../domaincapsdata/qemu_6.2.0-tcg.x86_64.xml  |   2 +
 tests/domaincapsdata/qemu_6.2.0.x86_64.xml|   2 +
 .../domaincapsdata/qemu_7.0.0-q35.x86_64.xml  |   2 +
 .../domaincapsdata/qemu_7.0.0-tcg.x86_64.xml  |   2 +
 tests/domaincapsdata/qemu_7.0.0.x86_64.xml|   2 +
 .../domaincapsdata/qemu_7.1.0-q35.x86_64.xml  |   2 +
 .../domaincapsdata/qemu_7.1.0-tcg.x86_64.xml  |   2 +
 tests/domaincapsdata/qemu_7.1.0.x86_64.xml|   2 +
 .../domaincapsdata/qemu_7.2.0-q35.x86_64.xml  |   2 +
 .../qemu_7.2.0-tcg.x86_64+hvf.xml |   2 +
 .../domaincapsdata/qemu_7.2.0-tcg.x86_64.xml  |   2 +
 tests/domaincapsdata/qemu_7.2.0.x86_64.xml|   2 +
 .../domaincapsdata/qemu_8.0.0-q35.x86_64.xml  |   2 +
 .../domaincapsdata/qemu_8.0.0-tcg.x86_64.xml  |   2 +
 tests/domaincapsdata/qemu_8.0.0.x86_64.xml|   2 +
 .../domaincapsdata/qemu_8.1.0-q35.x86_64.xml  |  11 +-
 .../domaincapsdata/qemu_8.1.0-tcg.x86_64.xml  |   6 +
 tests/domaincapsdata/qemu_8.1.0.x86_64.xml|  11 +-
 .../domaincapsdata/qemu_8.2.0-q35.x86_64.xml  |  11 +-
 .../domaincapsdata/qemu_8.2.0-tcg.x86_64.xml  |   6 +
 tests/domaincapsdata/qemu_8.2.0.x86_64.xml|  11 +-
 ...-host-model-fallback-kvm.x86_64-8.1.0.args |   2 +-
 ...host-model-fallback-kvm.x86_64-latest.args |   2 +-
 .../cpu-host-model-kvm.x86_64-8.1.0.args  |   2 +-
 .../cpu-host-model-kvm.x86_64-latest.args |   2 +-
 ...ost-model-nofallback-kvm.x86_64-8.1.0.args |   2 +-
 ...st-model-nofallback-kvm.x86_64-latest.args |   2 +-
 55 files changed, 686 insertions(+), 43 deletions(-)
 create mode 100644 src/cpu_map/x86_EPYC-Milan-v2.xml
 create mode 100644 src/cpu_map/x86_EPYC-Rome-v2.xml
 create mode 100644 src/cpu_map/x86_EPYC-Rome-v3.xml
 create mode 100644 src/cpu_map/x86_EPYC-Rome-v4.xml
 create mode 100644 src/cpu_map/x86_EPYC-v3.xml
 create mode 100644 src/cpu_map/x86_EPYC-v4.xml

diff --git a/src/cpu_map/index.xml b/src/cpu_map/index.xml
index d2c5af5797..861edc3bb7 100644
--- a/src/cpu_map/index.xml
+++ b/src/cpu_map/index.xml
@@ -67,9 +67,15 @@
 
 
 
+
+
 
 
+
+
+
 
+
 
 
 
diff --git a/src/cpu_map/meson.build b/src/cpu_map/meson.build
index ae5293e85f..68e093e041 100644
--- a/src/cpu_map/meson.build
+++ b/src/cpu_map/meson.build
@@ -39,8 +39,14 @@ cpumap_data = [
   'x86_Dhyana.xml',
   'x86_EPYC-IBPB.xml',
   'x86_EPYC.xml',
+  'x86_EPYC-v3.xml',
+  'x86_EPYC-v4.xml',
   'x86_EPYC-Genoa.xml',
+  'x86_EPYC-Milan-v2.xml',
   'x86_EPYC-Milan.xml',
+  'x86_EPYC-Rome-v2.xml',
+  'x86_EPYC-Rome-v3.xml',
+  'x86_EPYC-Rome-v4.xml',
   'x86_EPYC-Rome.xml',
   'x86_features.xml',
   'x86_Haswell-IBRS.xml',
diff --git a/src/cpu_map/x86_EPYC-Milan-v2.xml 
b/src/cpu_map/x86_EPYC-Milan-v2.xml
new file mode 100644
index 00..4cadba2325
--- /dev/null
+++ b/src/cpu_map/x86_EPYC-Milan-v2.xml
@@ -0,0 +1,108

[PATCH v3 06/12] cpu_map: Add versioned Intel Skylake CPUs

2023-12-15 Thread Jonathon Jongsma
Signed-off-by: Jonathon Jongsma 
---
 src/cpu_map/index.xml |  3 +
 src/cpu_map/meson.build   |  3 +
 src/cpu_map/x86_Skylake-Client-v4.xml | 77 +
 src/cpu_map/x86_Skylake-Server-v4.xml | 83 ++
 src/cpu_map/x86_Skylake-Server-v5.xml | 85 +++
 .../domaincapsdata/qemu_5.1.0-q35.x86_64.xml  |  1 +
 .../domaincapsdata/qemu_5.1.0-tcg.x86_64.xml  |  1 +
 tests/domaincapsdata/qemu_5.1.0.x86_64.xml|  1 +
 .../domaincapsdata/qemu_5.2.0-q35.x86_64.xml  |  1 +
 .../domaincapsdata/qemu_5.2.0-tcg.x86_64.xml  |  1 +
 tests/domaincapsdata/qemu_5.2.0.x86_64.xml|  1 +
 .../domaincapsdata/qemu_6.0.0-q35.x86_64.xml  |  1 +
 .../domaincapsdata/qemu_6.0.0-tcg.x86_64.xml  |  1 +
 tests/domaincapsdata/qemu_6.0.0.x86_64.xml|  1 +
 .../domaincapsdata/qemu_6.1.0-q35.x86_64.xml  |  3 +
 .../domaincapsdata/qemu_6.1.0-tcg.x86_64.xml  |  3 +
 tests/domaincapsdata/qemu_6.1.0.x86_64.xml|  3 +
 .../domaincapsdata/qemu_6.2.0-q35.x86_64.xml  |  3 +
 .../domaincapsdata/qemu_6.2.0-tcg.x86_64.xml  |  3 +
 tests/domaincapsdata/qemu_6.2.0.x86_64.xml|  3 +
 .../domaincapsdata/qemu_7.0.0-q35.x86_64.xml  |  3 +
 .../domaincapsdata/qemu_7.0.0-tcg.x86_64.xml  |  3 +
 tests/domaincapsdata/qemu_7.0.0.x86_64.xml|  3 +
 .../domaincapsdata/qemu_7.1.0-q35.x86_64.xml  |  3 +
 .../domaincapsdata/qemu_7.1.0-tcg.x86_64.xml  |  3 +
 tests/domaincapsdata/qemu_7.1.0.x86_64.xml|  3 +
 .../domaincapsdata/qemu_7.2.0-q35.x86_64.xml  |  3 +
 .../qemu_7.2.0-tcg.x86_64+hvf.xml |  3 +
 .../domaincapsdata/qemu_7.2.0-tcg.x86_64.xml  |  3 +
 tests/domaincapsdata/qemu_7.2.0.x86_64.xml|  3 +
 .../domaincapsdata/qemu_8.0.0-q35.x86_64.xml  |  3 +
 .../domaincapsdata/qemu_8.0.0-tcg.x86_64.xml  |  3 +
 tests/domaincapsdata/qemu_8.0.0.x86_64.xml|  3 +
 .../domaincapsdata/qemu_8.1.0-q35.x86_64.xml  |  3 +
 .../domaincapsdata/qemu_8.1.0-tcg.x86_64.xml  |  3 +
 tests/domaincapsdata/qemu_8.1.0.x86_64.xml|  3 +
 .../domaincapsdata/qemu_8.2.0-q35.x86_64.xml  |  3 +
 .../domaincapsdata/qemu_8.2.0-tcg.x86_64.xml  |  3 +
 tests/domaincapsdata/qemu_8.2.0.x86_64.xml|  3 +
 39 files changed, 335 insertions(+)
 create mode 100644 src/cpu_map/x86_Skylake-Client-v4.xml
 create mode 100644 src/cpu_map/x86_Skylake-Server-v4.xml
 create mode 100644 src/cpu_map/x86_Skylake-Server-v5.xml

diff --git a/src/cpu_map/index.xml b/src/cpu_map/index.xml
index 861edc3bb7..a4fe2ec781 100644
--- a/src/cpu_map/index.xml
+++ b/src/cpu_map/index.xml
@@ -45,9 +45,12 @@
 
 
 
+
 
 
 
+
+
 
 
 
diff --git a/src/cpu_map/meson.build b/src/cpu_map/meson.build
index 68e093e041..f6b95863b3 100644
--- a/src/cpu_map/meson.build
+++ b/src/cpu_map/meson.build
@@ -82,9 +82,12 @@ cpumap_data = [
   'x86_SapphireRapids.xml',
   'x86_Skylake-Client-IBRS.xml',
   'x86_Skylake-Client-noTSX-IBRS.xml',
+  'x86_Skylake-Client-v4.xml',
   'x86_Skylake-Client.xml',
   'x86_Skylake-Server-IBRS.xml',
   'x86_Skylake-Server-noTSX-IBRS.xml',
+  'x86_Skylake-Server-v4.xml',
+  'x86_Skylake-Server-v5.xml',
   'x86_Skylake-Server.xml',
   'x86_Snowridge.xml',
   'x86_vendors.xml',
diff --git a/src/cpu_map/x86_Skylake-Client-v4.xml 
b/src/cpu_map/x86_Skylake-Client-v4.xml
new file mode 100644
index 00..038ac376b6
--- /dev/null
+++ b/src/cpu_map/x86_Skylake-Client-v4.xml
@@ -0,0 +1,77 @@
+
+
+  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  
+
diff --git a/src/cpu_map/x86_Skylake-Server-v4.xml 
b/src/cpu_map/x86_Skylake-Server-v4.xml
new file mode 100644
index 00..6c864f6b9c
--- /dev/null
+++ b/src/cpu_map/x86_Skylake-Server-v4.xml
@@ -0,0 +1,83 @@
+
+
+  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  
+
diff --git a/src/cpu_map/x86_Skylake-Server-v5.xml 
b/src/cpu_map/x86_Skylake-Server-v5.xml
new file mode 100644
index 00..f3d49fb5d2
--- /dev/null
+++ b/src/cpu_map/x86_Skylake-Server-v5.xml
@@ -0,0 +1,85

[PATCH v3 09/12] cpu_map: Add versioned Intel Cooperlake CPUs

2023-12-15 Thread Jonathon Jongsma
Signed-off-by: Jonathon Jongsma 
---
 src/cpu_map/index.xml |  1 +
 src/cpu_map/meson.build   |  1 +
 src/cpu_map/x86_Cooperlake-v2.xml | 98 +++
 .../x86_64-cpuid-Cooperlake-host.xml  |  3 +-
 .../domaincapsdata/qemu_6.1.0-q35.x86_64.xml  |  1 +
 .../domaincapsdata/qemu_6.1.0-tcg.x86_64.xml  |  1 +
 tests/domaincapsdata/qemu_6.1.0.x86_64.xml|  1 +
 .../domaincapsdata/qemu_6.2.0-q35.x86_64.xml  |  1 +
 .../domaincapsdata/qemu_6.2.0-tcg.x86_64.xml  |  1 +
 tests/domaincapsdata/qemu_6.2.0.x86_64.xml|  1 +
 .../domaincapsdata/qemu_7.0.0-q35.x86_64.xml  |  1 +
 .../domaincapsdata/qemu_7.0.0-tcg.x86_64.xml  |  1 +
 tests/domaincapsdata/qemu_7.0.0.x86_64.xml|  1 +
 .../domaincapsdata/qemu_7.1.0-q35.x86_64.xml  |  1 +
 .../domaincapsdata/qemu_7.1.0-tcg.x86_64.xml  |  1 +
 tests/domaincapsdata/qemu_7.1.0.x86_64.xml|  1 +
 .../domaincapsdata/qemu_7.2.0-q35.x86_64.xml  |  1 +
 .../qemu_7.2.0-tcg.x86_64+hvf.xml |  1 +
 .../domaincapsdata/qemu_7.2.0-tcg.x86_64.xml  |  1 +
 tests/domaincapsdata/qemu_7.2.0.x86_64.xml|  1 +
 .../domaincapsdata/qemu_8.0.0-q35.x86_64.xml  |  1 +
 .../domaincapsdata/qemu_8.0.0-tcg.x86_64.xml  |  1 +
 tests/domaincapsdata/qemu_8.0.0.x86_64.xml|  1 +
 .../domaincapsdata/qemu_8.1.0-q35.x86_64.xml  |  1 +
 .../domaincapsdata/qemu_8.1.0-tcg.x86_64.xml  |  1 +
 tests/domaincapsdata/qemu_8.1.0.x86_64.xml|  1 +
 .../domaincapsdata/qemu_8.2.0-q35.x86_64.xml  |  1 +
 .../domaincapsdata/qemu_8.2.0-tcg.x86_64.xml  |  1 +
 tests/domaincapsdata/qemu_8.2.0.x86_64.xml|  1 +
 29 files changed, 126 insertions(+), 2 deletions(-)
 create mode 100644 src/cpu_map/x86_Cooperlake-v2.xml

diff --git a/src/cpu_map/index.xml b/src/cpu_map/index.xml
index c0971c9391..3d8be6e41a 100644
--- a/src/cpu_map/index.xml
+++ b/src/cpu_map/index.xml
@@ -65,6 +65,7 @@
 
 
 
+
 
 
 
diff --git a/src/cpu_map/meson.build b/src/cpu_map/meson.build
index 6e77f78b1c..a6db0b1503 100644
--- a/src/cpu_map/meson.build
+++ b/src/cpu_map/meson.build
@@ -34,6 +34,7 @@ cpumap_data = [
   'x86_Cascadelake-Server-v5.xml',
   'x86_Cascadelake-Server.xml',
   'x86_Conroe.xml',
+  'x86_Cooperlake-v2.xml',
   'x86_Cooperlake.xml',
   'x86_core2duo.xml',
   'x86_coreduo.xml',
diff --git a/src/cpu_map/x86_Cooperlake-v2.xml 
b/src/cpu_map/x86_Cooperlake-v2.xml
new file mode 100644
index 00..bf0ba626d6
--- /dev/null
+++ b/src/cpu_map/x86_Cooperlake-v2.xml
@@ -0,0 +1,98 @@
+
+
+  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  
+
diff --git a/tests/cputestdata/x86_64-cpuid-Cooperlake-host.xml 
b/tests/cputestdata/x86_64-cpuid-Cooperlake-host.xml
index 8dfc62a5c1..dea9bc9b9f 100644
--- a/tests/cputestdata/x86_64-cpuid-Cooperlake-host.xml
+++ b/tests/cputestdata/x86_64-cpuid-Cooperlake-host.xml
@@ -1,6 +1,6 @@
 
   x86_64
-  Cooperlake
+  Cooperlake-v2
   Intel
   
   
@@ -27,7 +27,6 @@
   
   
   
-  
   
   
   
diff --git a/tests/domaincapsdata/qemu_6.1.0-q35.x86_64.xml 
b/tests/domaincapsdata/qemu_6.1.0-q35.x86_64.xml
index 3385f64440..ec469d2ef2 100644
--- a/tests/domaincapsdata/qemu_6.1.0-q35.x86_64.xml
+++ b/tests/domaincapsdata/qemu_6.1.0-q35.x86_64.xml
@@ -117,6 +117,7 @@
   EPYC-IBPB
   EPYC
   Dhyana
+  Cooperlake-v2
   Cooperlake
   Conroe
   Cascadelake-Server-v5
diff --git a/tests/domaincapsdata/qemu_6.1.0-tcg.x86_64.xml 
b/tests/domaincapsdata/qemu_6.1.0-tcg.x86_64.xml
index b26fad77d0..ecdf591638 100644
--- a/tests/domaincapsdata/qemu_6.1.0-tcg.x86_64.xml
+++ b/tests/domaincapsdata/qemu_6.1.0-tcg.x86_64.xml
@@ -129,6 +129,7 @@
   EPYC-IBPB
   EPYC
   Dhyana
+  Cooperlake-v2
   Cooperlake
   Conroe
   Cascadelake-Server-v5
diff --git a/tests/domaincapsdata/qemu_6.1.0.x86_64.xml 
b/tests/domaincapsdata/qemu_6.1.0.x86_64.xml
index 0c02963502..5059e61c87 100644
--- a/tests/domaincapsdata/qemu_6.1.0.x86_64.xml
+++ b/tests/domaincapsdata/qemu_6.1.0.x86_64.xml
@@ -116,6 +116,7 @@
   EPYC-IBPB
   EPYC
   Dhyana
+  Cooperlake-v2
   Cooperlake
   Conroe
   Cascadelake-Server-v5
diff --git a/tests/domaincapsdata/qemu_6.2.0-q35.x86_64.xml 
b/tests/domaincapsdata/qemu_6.2.0-q35.x86_64.xml
index bc93fb8412..d4d90817b1 100644
--- a/tests/domaincapsdata/qemu_6.2.0-q35.x86_64.xml
+++ b/tests/domaincapsdata/qemu_6.2.0-q35.x86_64.xml
@@ -117,6 +117,7 @@
   EPYC-IBPB
   EPYC
   Dhyana
+  Cooperlake-v2
   Cooperlake
   Conroe

[PATCH v3 11/12] cpu_map: Add versioned Intel SapphireRapids CPUs

2023-12-15 Thread Jonathon Jongsma
Signed-off-by: Jonathon Jongsma 
---
 src/cpu_map/index.xml |   1 +
 src/cpu_map/meson.build   |   1 +
 src/cpu_map/x86_SapphireRapids-v2.xml | 125 ++
 .../domaincapsdata/qemu_8.1.0-q35.x86_64.xml  |   1 +
 .../domaincapsdata/qemu_8.1.0-tcg.x86_64.xml  |   1 +
 tests/domaincapsdata/qemu_8.1.0.x86_64.xml|   1 +
 .../domaincapsdata/qemu_8.2.0-q35.x86_64.xml  |   1 +
 .../domaincapsdata/qemu_8.2.0-tcg.x86_64.xml  |   1 +
 tests/domaincapsdata/qemu_8.2.0.x86_64.xml|   1 +
 9 files changed, 133 insertions(+)
 create mode 100644 src/cpu_map/x86_SapphireRapids-v2.xml

diff --git a/src/cpu_map/index.xml b/src/cpu_map/index.xml
index 449abbd8f3..9b3719c5ef 100644
--- a/src/cpu_map/index.xml
+++ b/src/cpu_map/index.xml
@@ -71,6 +71,7 @@
 
 
 
+
 
 
 
diff --git a/src/cpu_map/meson.build b/src/cpu_map/meson.build
index 073fd66bec..4b2a90fd74 100644
--- a/src/cpu_map/meson.build
+++ b/src/cpu_map/meson.build
@@ -87,6 +87,7 @@ cpumap_data = [
   'x86_qemu64.xml',
   'x86_SandyBridge-IBRS.xml',
   'x86_SandyBridge.xml',
+  'x86_SapphireRapids-v2.xml',
   'x86_SapphireRapids.xml',
   'x86_Skylake-Client-IBRS.xml',
   'x86_Skylake-Client-noTSX-IBRS.xml',
diff --git a/src/cpu_map/x86_SapphireRapids-v2.xml 
b/src/cpu_map/x86_SapphireRapids-v2.xml
new file mode 100644
index 00..0d90d50f5f
--- /dev/null
+++ b/src/cpu_map/x86_SapphireRapids-v2.xml
@@ -0,0 +1,125 @@
+
+
+  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  
+
diff --git a/tests/domaincapsdata/qemu_8.1.0-q35.x86_64.xml 
b/tests/domaincapsdata/qemu_8.1.0-q35.x86_64.xml
index c80455a6b5..4067720049 100644
--- a/tests/domaincapsdata/qemu_8.1.0-q35.x86_64.xml
+++ b/tests/domaincapsdata/qemu_8.1.0-q35.x86_64.xml
@@ -98,6 +98,7 @@
   Skylake-Client-noTSX-IBRS
   Skylake-Client-IBRS
   Skylake-Client
+  SapphireRapids-v2
   SapphireRapids
   SandyBridge-IBRS
   SandyBridge
diff --git a/tests/domaincapsdata/qemu_8.1.0-tcg.x86_64.xml 
b/tests/domaincapsdata/qemu_8.1.0-tcg.x86_64.xml
index ee67181b3e..7c836af7e6 100644
--- a/tests/domaincapsdata/qemu_8.1.0-tcg.x86_64.xml
+++ b/tests/domaincapsdata/qemu_8.1.0-tcg.x86_64.xml
@@ -99,6 +99,7 @@
   Skylake-Client-noTSX-IBRS
   Skylake-Client-IBRS
   Skylake-Client
+  SapphireRapids-v2
   SapphireRapids
   SandyBridge-IBRS
   SandyBridge
diff --git a/tests/domaincapsdata/qemu_8.1.0.x86_64.xml 
b/tests/domaincapsdata/qemu_8.1.0.x86_64.xml
index 00b6d45314..6ff2ebbde8 100644
--- a/tests/domaincapsdata/qemu_8.1.0.x86_64.xml
+++ b/tests/domaincapsdata/qemu_8.1.0.x86_64.xml
@@ -97,6 +97,7 @@
   Skylake-Client-noTSX-IBRS
   Skylake-Client-IBRS
   Skylake-Client
+  SapphireRapids-v2
   SapphireRapids
   SandyBridge-IBRS
   SandyBridge
diff --git a/tests/domaincapsdata/qemu_8.2.0-q35.x86_64.xml 
b/tests/domaincapsdata/qemu_8.2.0-q35.x86_64.xml
index 4aebd4a128..8e504436cf 100644
--- a/tests/domaincapsdata/qemu_8.2.0-q35.x86_64.xml
+++ b/tests/domaincapsdata/qemu_8.2.0-q35.x86_64.xml
@@ -99,6 +99,7 @@
   Skylake-Client-noTSX-IBRS
   Skylake-Client-IBRS
   Skylake-Client
+  SapphireRapids-v2
   SapphireRapids
   SandyBridge-IBRS
   SandyBridge
diff --git a/tests/domaincapsdata/qemu_8.2.0-tcg.x86_64.xml 
b/tests/domaincapsdata/qemu_8.2.0-tcg.x86_64.xml
index c9fc385bfa..7f0b057d97 100644
--- a/tests/domaincapsdata/qemu_8.2.0-tcg.x86_64.xml
+++ b/tests/domaincapsdata/qemu_8.2.0-tcg.x86_64.xml
@@ -98,6 +98,7 @@
   Skylake-Client-noTSX-IBRS
   Skylake-Client-IBRS
   Skylake-Client
+  SapphireRapids-v2
   SapphireRapids
   SandyBridge-IBRS
   SandyBridge
diff --git a/tests/domaincapsdata/qemu_8.2.0.x86_64.xml 
b/tests/domaincapsdata/qemu_8.2.0.x86_64.xml
index 0e424db1d8..0f43f5b543 100644
--- a/tests/domaincapsdata/qemu_8.2.0.x86_64.xml
+++ b/tests/domaincapsdata/qemu_8.2.0.x86_64.xml
@@ -98,6 +98,7 @@
   Skylake-Client-noTSX-IBRS
   Skylake-Client-IBRS
   Skylake-Client
+  SapphireRapids-v2
   SapphireRapids
   SandyBridge-IBRS
   SandyBridge
-- 
2.41.0
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


[PATCH v3 02/12] cpu_map: add canonical names to existing CPU models

2023-12-15 Thread Jonathon Jongsma
Signed-off-by: Jonathon Jongsma 
---
 src/cpu_map/x86_Broadwell-IBRS.xml| 1 +
 src/cpu_map/x86_Broadwell-noTSX-IBRS.xml  | 1 +
 src/cpu_map/x86_Broadwell-noTSX.xml   | 1 +
 src/cpu_map/x86_Broadwell.xml | 1 +
 src/cpu_map/x86_Cascadelake-Server-noTSX.xml  | 1 +
 src/cpu_map/x86_Cascadelake-Server.xml| 1 +
 src/cpu_map/x86_Cooperlake.xml| 1 +
 src/cpu_map/x86_Dhyana.xml| 1 +
 src/cpu_map/x86_EPYC-IBPB.xml | 1 +
 src/cpu_map/x86_EPYC-Milan.xml| 1 +
 src/cpu_map/x86_EPYC-Rome.xml | 1 +
 src/cpu_map/x86_EPYC.xml  | 1 +
 src/cpu_map/x86_Haswell-IBRS.xml  | 1 +
 src/cpu_map/x86_Haswell-noTSX-IBRS.xml| 1 +
 src/cpu_map/x86_Haswell-noTSX.xml | 1 +
 src/cpu_map/x86_Haswell.xml   | 1 +
 src/cpu_map/x86_Icelake-Server-noTSX.xml  | 1 +
 src/cpu_map/x86_Icelake-Server.xml| 1 +
 src/cpu_map/x86_IvyBridge-IBRS.xml| 1 +
 src/cpu_map/x86_IvyBridge.xml | 1 +
 src/cpu_map/x86_Nehalem-IBRS.xml  | 1 +
 src/cpu_map/x86_Nehalem.xml   | 1 +
 src/cpu_map/x86_SandyBridge-IBRS.xml  | 1 +
 src/cpu_map/x86_SandyBridge.xml   | 1 +
 src/cpu_map/x86_SapphireRapids.xml| 1 +
 src/cpu_map/x86_Skylake-Client-IBRS.xml   | 1 +
 src/cpu_map/x86_Skylake-Client-noTSX-IBRS.xml | 1 +
 src/cpu_map/x86_Skylake-Client.xml| 1 +
 src/cpu_map/x86_Skylake-Server-IBRS.xml   | 1 +
 src/cpu_map/x86_Skylake-Server-noTSX-IBRS.xml | 1 +
 src/cpu_map/x86_Skylake-Server.xml| 1 +
 src/cpu_map/x86_Snowridge.xml | 1 +
 src/cpu_map/x86_Westmere-IBRS.xml | 1 +
 src/cpu_map/x86_Westmere.xml  | 1 +
 34 files changed, 34 insertions(+)

diff --git a/src/cpu_map/x86_Broadwell-IBRS.xml 
b/src/cpu_map/x86_Broadwell-IBRS.xml
index 9033d5fcd5..13568eac81 100644
--- a/src/cpu_map/x86_Broadwell-IBRS.xml
+++ b/src/cpu_map/x86_Broadwell-IBRS.xml
@@ -1,5 +1,6 @@
 
   
+Broadwell-v3
 
  
  
diff --git a/src/cpu_map/x86_Broadwell-noTSX-IBRS.xml 
b/src/cpu_map/x86_Broadwell-noTSX-IBRS.xml
index c044b60e36..4ec35ce3a2 100644
--- a/src/cpu_map/x86_Broadwell-noTSX-IBRS.xml
+++ b/src/cpu_map/x86_Broadwell-noTSX-IBRS.xml
@@ -1,5 +1,6 @@
 
   
+Broadwell-v4
 
  
  
diff --git a/src/cpu_map/x86_Broadwell-noTSX.xml 
b/src/cpu_map/x86_Broadwell-noTSX.xml
index 637f29ba1c..3fed34e3a4 100644
--- a/src/cpu_map/x86_Broadwell-noTSX.xml
+++ b/src/cpu_map/x86_Broadwell-noTSX.xml
@@ -1,5 +1,6 @@
 
   
+Broadwell-v2
 
  
  
diff --git a/src/cpu_map/x86_Broadwell.xml b/src/cpu_map/x86_Broadwell.xml
index 82939a4509..79c96c3857 100644
--- a/src/cpu_map/x86_Broadwell.xml
+++ b/src/cpu_map/x86_Broadwell.xml
@@ -1,5 +1,6 @@
 
   
+Broadwell-v1
 
  
  
diff --git a/src/cpu_map/x86_Cascadelake-Server-noTSX.xml 
b/src/cpu_map/x86_Cascadelake-Server-noTSX.xml
index bfd4629836..e1b2a820dc 100644
--- a/src/cpu_map/x86_Cascadelake-Server-noTSX.xml
+++ b/src/cpu_map/x86_Cascadelake-Server-noTSX.xml
@@ -1,5 +1,6 @@
 
   
+Cascadelake-Server-v3
 
  
 
diff --git a/src/cpu_map/x86_Cascadelake-Server.xml 
b/src/cpu_map/x86_Cascadelake-Server.xml
index 335e9cb584..4e72518e0d 100644
--- a/src/cpu_map/x86_Cascadelake-Server.xml
+++ b/src/cpu_map/x86_Cascadelake-Server.xml
@@ -1,5 +1,6 @@
 
   
+Cascadelake-Server-v1
 
  
 
diff --git a/src/cpu_map/x86_Cooperlake.xml b/src/cpu_map/x86_Cooperlake.xml
index ceca687334..d2967daf3b 100644
--- a/src/cpu_map/x86_Cooperlake.xml
+++ b/src/cpu_map/x86_Cooperlake.xml
@@ -1,5 +1,6 @@
 
   
+Cooperlake-v1
 
  
 
diff --git a/src/cpu_map/x86_Dhyana.xml b/src/cpu_map/x86_Dhyana.xml
index cfde07f99f..a7fb540973 100644
--- a/src/cpu_map/x86_Dhyana.xml
+++ b/src/cpu_map/x86_Dhyana.xml
@@ -1,5 +1,6 @@
 
   
+Dhyana-v1
 
  
 
diff --git a/src/cpu_map/x86_EPYC-IBPB.xml b/src/cpu_map/x86_EPYC-IBPB.xml
index fc5aadf52e..28f0113392 100644
--- a/src/cpu_map/x86_EPYC-IBPB.xml
+++ b/src/cpu_map/x86_EPYC-IBPB.xml
@@ -1,5 +1,6 @@
 
   
+EPYC-v2
 
  
 
diff --git a/src/cpu_map/x86_EPYC-Milan.xml b/src/cpu_map/x86_EPYC-Milan.xml
index 3055e175fa..0dfdbb5b4b 100644
--- a/src/cpu_map/x86_EPYC-Milan.xml
+++ b/src/cpu_map/x86_EPYC-Milan.xml
@@ -1,5 +1,6 @@
 
   
+EPYC-Milan-v1
 
 
 
diff --git a/src/cpu_map/x86_EPYC-Rome.xml b/src/cpu_map/x86_EPYC-Rome.xml
index e54d0a48d8..794f3a8ff6 100644
--- a/src/cpu_map/x86_EPYC-Rome.xml
+++ b/src/cpu_map/x86_EPYC-Rome.xml
@@ -1,5 +1,6 @@
 
   
+EPYC-Rome-v1
 
 
 
diff --git a/src/cpu_map/x86_EPYC.xml b/src/cpu_map/x86_EPYC.xml
index 3b406de37a..852ca047e4 100644
--- a/src/cpu_map/x86_EPYC.xml
+++ b/src/cpu_map/x86_EPYC.xml
@@ -1,5 +1,6 @@
 
   
+EPYC-v1
 
  
 
diff --git a/src/cpu_map/x86_Haswell

[PATCH v3 03/12] cpu: parse the canonical name from the cpu model

2023-12-15 Thread Jonathon Jongsma
Recent changes have added a 'canonical_name' field to the xml
definitions for our CPU models. Parse this field into the C structure
and pass it around where necessary.
---
 src/conf/cpu_conf.c |  3 +++
 src/conf/cpu_conf.h |  1 +
 src/cpu/cpu_x86.c   | 24 
 3 files changed, 28 insertions(+)

diff --git a/src/conf/cpu_conf.c b/src/conf/cpu_conf.c
index 7abe489733..a771893956 100644
--- a/src/conf/cpu_conf.c
+++ b/src/conf/cpu_conf.c
@@ -113,6 +113,7 @@ void ATTRIBUTE_NONNULL(1)
 virCPUDefFreeModel(virCPUDef *def)
 {
 VIR_FREE(def->model);
+VIR_FREE(def->canonical_model);
 VIR_FREE(def->vendor);
 VIR_FREE(def->vendor_id);
 virCPUDefFreeFeatures(def);
@@ -161,6 +162,7 @@ virCPUDefCopyModelFilter(virCPUDef *dst,
 
 dst->features = g_new0(virCPUFeatureDef, src->nfeatures);
 dst->model = g_strdup(src->model);
+dst->canonical_model = g_strdup(src->canonical_model);
 dst->vendor = g_strdup(src->vendor);
 dst->vendor_id = g_strdup(src->vendor_id);
 dst->microcodeVersion = src->microcodeVersion;
@@ -211,6 +213,7 @@ virCPUDefStealModel(virCPUDef *dst,
 virCPUDefFreeModel(dst);
 
 dst->model = g_steal_pointer(>model);
+dst->canonical_model = g_steal_pointer(>canonical_model);
 dst->features = g_steal_pointer(>features);
 dst->microcodeVersion = src->microcodeVersion;
 dst->nfeatures_max = src->nfeatures_max;
diff --git a/src/conf/cpu_conf.h b/src/conf/cpu_conf.h
index 3e4c53675c..ba8dab6c7f 100644
--- a/src/conf/cpu_conf.h
+++ b/src/conf/cpu_conf.h
@@ -142,6 +142,7 @@ struct _virCPUDef {
 virCPUCheck check;
 virArch arch;
 char *model;
+char *canonical_model;
 char *vendor_id;/* vendor id returned by CPUID in the guest */
 int fallback;   /* enum virCPUFallback */
 char *vendor;
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
index 8d0e3947ce..70800d9579 100644
--- a/src/cpu/cpu_x86.c
+++ b/src/cpu/cpu_x86.c
@@ -142,6 +142,7 @@ struct _virCPUx86Signatures {
 typedef struct _virCPUx86Model virCPUx86Model;
 struct _virCPUx86Model {
 char *name;
+char *canonical_name;
 bool decodeHost;
 bool decodeGuest;
 virCPUx86Vendor *vendor;
@@ -864,6 +865,7 @@ x86DataToCPU(const virCPUx86Data *data,
 cpu = virCPUDefNew();
 
 cpu->model = g_strdup(model->name);
+cpu->canonical_model = g_strdup(model->canonical_name);
 
 x86DataCopy(, data);
 x86DataCopy(, >data);
@@ -1281,6 +1283,7 @@ x86ModelFree(virCPUx86Model *model)
 return;
 
 g_free(model->name);
+g_free(model->canonical_name);
 virCPUx86SignaturesFree(model->signatures);
 virCPUx86DataClear(>data);
 g_strfreev(model->removedFeatures);
@@ -1296,6 +1299,7 @@ x86ModelCopy(virCPUx86Model *model)
 
 copy = g_new0(virCPUx86Model, 1);
 copy->name = g_strdup(model->name);
+copy->canonical_name = g_strdup(model->canonical_name);
 copy->signatures = virCPUx86SignaturesCopy(model->signatures);
 x86DataCopy(>data, >data);
 copy->removedFeatures = g_strdupv(model->removedFeatures);
@@ -1451,6 +1455,17 @@ x86ModelCompare(virCPUx86Model *model1,
 }
 
 
+static int
+x86ModelParseCanonicalName(virCPUx86Model *model,
+   xmlXPathContextPtr ctxt)
+{
+if (!(model->canonical_name = 
virXPathString("string(./canonical_name[1])", ctxt)))
+model->canonical_name = g_strdup(model->name);
+
+return 0;
+}
+
+
 static int
 x86ModelParseDecode(virCPUx86Model *model,
 xmlXPathContextPtr ctxt)
@@ -1668,6 +1683,9 @@ x86ModelParse(xmlXPathContextPtr ctxt,
 model = g_new0(virCPUx86Model, 1);
 model->name = g_strdup(name);
 
+if (x86ModelParseCanonicalName(model, ctxt) < 0)
+return -1;
+
 if (x86ModelParseDecode(model, ctxt) < 0)
 return -1;
 
@@ -2268,6 +2286,7 @@ x86Decode(virCPUDef *cpu,
   sigFamily, sigModel, sigStepping);
 
 cpu->model = g_steal_pointer(>model);
+cpu->canonical_model = g_steal_pointer(>canonical_model);
 cpu->features = g_steal_pointer(>features);
 cpu->nfeatures = cpuModel->nfeatures;
 cpuModel->nfeatures = 0;
@@ -3010,6 +3029,11 @@ virCPUx86Update(virCPUDef *guest,
 return -1;
 }
 
+if (guestModel->canonical_name) {
+g_free(guest->canonical_model);
+guest->canonical_model = g_strdup(guestModel->canonical_name);
+}
+
 if (virCPUx86DisableRemovedFeatures(guest, guestModel) < 0)
 return -1;
 
-- 
2.41.0
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


[PATCH v3 00/12] Improve versioned CPU support in libvirt

2023-12-15 Thread Jonathon Jongsma
For SEV-SNP support we will need to be able to specify versioned CPU models
that are not yet available in libvirt. Rather than just adding a versioned CPU
or two that would satisfy that immediate need, I decided to try to add
versioned CPUs in a more standard way. This series generates CPU definitions
for all cpu versions that are defined in upstream qemu (at least for
recent Intel and AMD CPUs).

libvirt already provides a select subset of these versions as configurable CPU
models. But we only include the ones that have defined aliases in qemu, such as
EPYC-IBPB. After this patchset, all verisioned cpu models supported by qemu
will be available in libvirt.

In addition to adding these new versioned models, based on feedback from Daniel
Berrange, I've also translated all CPU model aliases to a specific version when
specifying a CPU model to qemu. This means that we will no longer specify e.g.
'-cpu EPYC' to qemu, but will rather specify '-cpu EPYC-v1'

Changes in v3:
 - handle unversioned aliases

Changes in v2:
 - don't make any changes to existing CPU models
 - drop concept of aliases from libvirt and only provide new versioned models
   that aren't already available via their qemu alias.

Jonathon Jongsma (12):
  cpu_map: update script to handle versioned CPUs
  cpu_map: add canonical names to existing CPU models
  cpu: parse the canonical name from the cpu model
  qemu: use canonical name for CPU models
  cpu_map: Add versioned EPYC CPUs
  cpu_map: Add versioned Intel Skylake CPUs
  cpu_map: Add versioned Intel Cascadelake CPUs
  cpu_map: Add versioned Intel Icelake CPUs
  cpu_map: Add versioned Intel Cooperlake CPUs
  cpu_map: Add versioned Intel Snowridge CPUs
  cpu_map: Add versioned Intel SapphireRapids CPUs
  cpu_map: Add versioned Dhyana CPUs

 src/conf/cpu_conf.c   |   3 +
 src/conf/cpu_conf.h   |   1 +
 src/cpu/cpu_x86.c |  24 
 src/cpu_map/index.xml |  22 +++
 src/cpu_map/meson.build   |  22 +++
 src/cpu_map/sync_qemu_models_i386.py  |  42 --
 src/cpu_map/x86_Broadwell-IBRS.xml|   1 +
 src/cpu_map/x86_Broadwell-noTSX-IBRS.xml  |   1 +
 src/cpu_map/x86_Broadwell-noTSX.xml   |   1 +
 src/cpu_map/x86_Broadwell.xml |   1 +
 src/cpu_map/x86_Cascadelake-Server-noTSX.xml  |   1 +
 src/cpu_map/x86_Cascadelake-Server-v2.xml |  93 +
 src/cpu_map/x86_Cascadelake-Server-v4.xml |  91 +
 src/cpu_map/x86_Cascadelake-Server-v5.xml |  92 +
 src/cpu_map/x86_Cascadelake-Server.xml|   1 +
 src/cpu_map/x86_Cooperlake-v2.xml |  98 ++
 src/cpu_map/x86_Cooperlake.xml|   1 +
 src/cpu_map/x86_Dhyana-v2.xml |  81 
 src/cpu_map/x86_Dhyana.xml|   1 +
 src/cpu_map/x86_EPYC-IBPB.xml |   1 +
 src/cpu_map/x86_EPYC-Milan-v2.xml | 108 +++
 src/cpu_map/x86_EPYC-Milan.xml|   1 +
 src/cpu_map/x86_EPYC-Rome-v2.xml  |  93 +
 src/cpu_map/x86_EPYC-Rome-v3.xml  |  95 +
 src/cpu_map/x86_EPYC-Rome-v4.xml  |  94 +
 src/cpu_map/x86_EPYC-Rome.xml |   1 +
 src/cpu_map/x86_EPYC-v3.xml   |  87 
 src/cpu_map/x86_EPYC-v4.xml   |  88 
 src/cpu_map/x86_EPYC.xml  |   1 +
 src/cpu_map/x86_Haswell-IBRS.xml  |   1 +
 src/cpu_map/x86_Haswell-noTSX-IBRS.xml|   1 +
 src/cpu_map/x86_Haswell-noTSX.xml |   1 +
 src/cpu_map/x86_Haswell.xml   |   1 +
 src/cpu_map/x86_Icelake-Server-noTSX.xml  |   1 +
 src/cpu_map/x86_Icelake-Server-v3.xml | 103 +++
 src/cpu_map/x86_Icelake-Server-v4.xml | 108 +++
 src/cpu_map/x86_Icelake-Server-v5.xml | 109 +++
 src/cpu_map/x86_Icelake-Server-v6.xml | 109 +++
 src/cpu_map/x86_Icelake-Server.xml|   1 +
 src/cpu_map/x86_IvyBridge-IBRS.xml|   1 +
 src/cpu_map/x86_IvyBridge.xml |   1 +
 src/cpu_map/x86_Nehalem-IBRS.xml  |   1 +
 src/cpu_map/x86_Nehalem.xml   |   1 +
 src/cpu_map/x86_SandyBridge-IBRS.xml  |   1 +
 src/cpu_map/x86_SandyBridge.xml   |   1 +
 src/cpu_map/x86_SapphireRapids-v2.xml | 125 ++
 src/cpu_map/x86_SapphireRapids.xml|   1 +
 src/cpu_map/x86_Skylake-Client-IBRS.xml   |   1 +
 src/cpu_map/x86_Skylake-Client-noTSX-IBRS.xml |   1 +
 src/cpu_map/x86_Skylake-Client-v4.xml |  77 +++
 src/cpu_map/x86_Skylake-Client.xml|   1 +
 src/cpu_map/x86_Skylake-Server-IBRS.xml   |   1 +
 src/cpu_map/x86_Skylake-Server-noTSX-IBRS.xml |   1 +
 src/cpu_map/x86_Skylake-Server-v4.xml |  83 
 src

[PATCH v3 01/12] cpu_map: update script to handle versioned CPUs

2023-12-15 Thread Jonathon Jongsma
Previously, the script only generated the parent CPU and any versions
that had a defined alias. The script now generates all CPU versions. Any
version that had a defined alias will continue to use that alias, but
those without aliases will use the generated name $BASECPUNAME-vN.

The reason for this change is two-fold. First, we need to add new models
that support new features (such as SEV-SNP). To deal with this, the
script now generates model definitions for all versions.

But we also need to ensure that our CPU definitions are migration-safe.
To deal with this issue we need to make sure we're always using the
canonical versioned names for CPUs.

Qemu documentation states that unversioned names for CPU models (e.g.
'EPYC') are actually aliases to a specific versioned CPU model (e.g.
'EPYC-v1'). The documentation further states that the specific version
targeted by the alias may change based on the machine type of the
domain. Management software such as libvirt is directed to translate
these aliases to a concrete version in order to make sure that the CPU
definition is safe when migrating between different qemu versions that
may make different choices for which underlying versioned model
represents the alias.

In practice, at the time of writing qemu always maps the unversioned
aliases to the -v1 model. And libvirt's CPU model definitions also
assume that this is the case. For example, the 'x86_EPYC.xml' file
contains the features that are defined for the EPYC-v1 inside of qemu.
But if qemu ever changes their alias mapping, libvirt's idea of what an
'EPYC' CPU means and qemu's idea of what an 'EPYC' CPU means will no
longer match. So when choosing a CPU model for a domain, we should
always pass the canonical versioned name to libvirt rather than the
unversioned alias. To enable this, the script will generate a new
'canonical_name' field to the CPU model xml definition.

Signed-off-by: Jonathon Jongsma 
---
 src/cpu_map/sync_qemu_models_i386.py | 42 ++--
 1 file changed, 34 insertions(+), 8 deletions(-)

diff --git a/src/cpu_map/sync_qemu_models_i386.py 
b/src/cpu_map/sync_qemu_models_i386.py
index 1c6a2d4d27..7fd62eba4a 100755
--- a/src/cpu_map/sync_qemu_models_i386.py
+++ b/src/cpu_map/sync_qemu_models_i386.py
@@ -322,31 +322,55 @@ def expand_model(model):
 different fields and may have differing versions into several libvirt-
 friendly cpu models."""
 
-result = {
-"name": model.pop(".name"),
+basename = model.pop(".name")
+parent = {
+"name": basename,
 "vendor": translate_vendor(model.pop(".vendor")),
 "features": set(),
 "extra": dict()}
 
 if ".family" in model and ".model" in model:
-result["family"] = model.pop(".family")
-result["model"] = model.pop(".model")
+parent["family"] = model.pop(".family")
+parent["model"] = model.pop(".model")
 
 for k in [k for k in model if k.startswith(".features")]:
 v = model.pop(k)
 for feature in v.split():
 translated = translate_feature(feature)
 if translated:
-result["features"].add(translated)
+parent["features"].add(translated)
 
 versions = model.pop(".versions", [])
 for k, v in model.items():
-result["extra"]["model" + k] = v
-yield result
+parent["extra"]["model" + k] = v
+
+if not versions:
+yield parent
+return
+
+result = parent
 
 for version in versions:
+# each version builds on the previous one
 result = copy.deepcopy(result)
-result["name"] = version.pop(".alias", result["name"])
+vnum = int(version.pop(".version"))
+vname = "{}-v{}".format(basename, vnum)
+result["canonical_name"] = vname
+if vnum == 1:
+# the first version should always be an alias for the parent and
+# should therefore have no extra properties
+if version.items():
+raise RuntimeError("Unexpected properties in version 1")
+yield result
+continue
+
+# prefer the 'alias' over the generated the name if it exists since we
+# have already been using these aliases
+alias = version.pop(".alias", None)
+if alias:
+result["name"] = alias
+else:
+result["name"] = vname
 
 props = version.pop(".props", dict())
 for k, v in props:
@@ -377,6 +401,8 @@ def output_model(f, model):
 
 f.write("\n")
 f.write("  \n".f

Re: [PATCH v2 00/14] Unreacheble code cleanup

2023-12-14 Thread Jonathon Jongsma

On 12/14/23 8:50 AM, Dmitry Frolov wrote:

A lot of unreacheble code was caused by int functions, which return nothing
except zero. Unreacheble code was removed. Corresponding functions type was
changed to void.

Dmitry Frolov (14):
   cpu: turn virCPUx86DataAddItem() to void
   cpu: turn virCPUx86DataAdd() to void
   libxl: turn libxlCapsAddCPUID() to void
   libxl: turn virCapabilitiesAddHostFeature() to void
   libxl: turn libxl_get_physinfo() to void
   conf: turn virCapabilitiesSetNetPrefix() to void
   libxl: turn libxlMakeDomainOSCaps() to void
   libxl: turn libxlMakeDomainDeviceDiskCaps() to void
   libxl: turn libxlMakeDomainDeviceGraphicsCaps() to void
   libxl: turn libxlMakeDomainDeviceVideoCaps() to void
   conf: turn virDomainGraphicsListenAppendAddress() to void
   vbox: turn vboxDumpDisplay() to void
   libxl: turn xenParseXLNamespaceData() to void
   rpc: turn virNetClientAddProgram() to void

  src/admin/admin_remote.c|  3 +-
  src/conf/capabilities.c |  8 +--
  src/conf/capabilities.h |  4 +-
  src/conf/domain_conf.c  |  4 +-
  src/conf/domain_conf.h  |  2 +-
  src/cpu/cpu_x86.c   | 91 -
  src/cpu/cpu_x86.h   |  2 +-
  src/libxl/libxl_capabilities.c  | 54 +++
  src/libxl/libxl_conf.c  | 20 ++--
  src/libxl/libxl_driver.c|  6 +--
  src/libxl/xen_common.c  |  7 +--
  src/libxl/xen_xl.c  |  8 ++-
  src/locking/lock_driver_lockd.c |  3 +-
  src/logging/log_manager.c   |  3 +-
  src/lxc/lxc_monitor.c   |  4 +-
  src/remote/remote_driver.c  |  7 ++-
  src/rpc/virnetclient.c  |  3 +-
  src/rpc/virnetclient.h  |  2 +-
  src/test/test_driver.c  |  6 +--
  src/vbox/vbox_common.c  | 13 ++---
  src/vmx/vmx.c   |  3 +-
  tests/libxlmock.c   |  5 +-
  22 files changed, 86 insertions(+), 172 deletions(-)



A couple minor comments sent separately

Reviewed-by: Jonathon Jongsma 
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [PATCH v2 14/14] rpc: turn virNetClientAddProgram() to void

2023-12-14 Thread Jonathon Jongsma

On 12/14/23 8:51 AM, Dmitry Frolov wrote:

virNetClientAddProgram() always returns 0.

Signed-off-by: Dmitry Frolov 
---
  src/admin/admin_remote.c| 3 +--
  src/locking/lock_driver_lockd.c | 3 +--
  src/logging/log_manager.c   | 3 +--
  src/lxc/lxc_monitor.c   | 4 +---
  src/remote/remote_driver.c  | 7 +++
  src/rpc/virnetclient.c  | 3 +--
  src/rpc/virnetclient.h  | 2 +-
  7 files changed, 9 insertions(+), 16 deletions(-)

diff --git a/src/admin/admin_remote.c b/src/admin/admin_remote.c
index 3291a1e965..5c4913a76e 100644
--- a/src/admin/admin_remote.c
+++ b/src/admin/admin_remote.c
@@ -214,8 +214,7 @@ remoteAdminPrivNew(const char *sock_path)
   NULL, 0, NULL)))
  goto error;
  
-if (virNetClientAddProgram(priv->client, priv->program) < 0)

-goto error;
+virNetClientAddProgram(priv->client, priv->program);
  
  return priv;

   error:
diff --git a/src/locking/lock_driver_lockd.c b/src/locking/lock_driver_lockd.c
index d75302dd0a..0b6c720477 100644
--- a/src/locking/lock_driver_lockd.c
+++ b/src/locking/lock_driver_lockd.c
@@ -213,8 +213,7 @@ static virNetClient 
*virLockManagerLockDaemonConnectionNew(bool privileged,
   NULL)))
  goto error;
  
-if (virNetClientAddProgram(client, *prog) < 0)

-goto error;
+virNetClientAddProgram(client, *prog);
  
  return client;
  
diff --git a/src/logging/log_manager.c b/src/logging/log_manager.c

index d8490f4e5a..19e23d65c5 100644
--- a/src/logging/log_manager.c
+++ b/src/logging/log_manager.c
@@ -88,8 +88,7 @@ virLogManagerConnect(bool privileged,
   NULL)))
  goto error;
  
-if (virNetClientAddProgram(client, *prog) < 0)

-goto error;
+virNetClientAddProgram(client, *prog);
  
  VIR_FREE(daemonPath);

  VIR_FREE(logdpath);
diff --git a/src/lxc/lxc_monitor.c b/src/lxc/lxc_monitor.c
index 811d6685e5..cf2fd1897f 100644
--- a/src/lxc/lxc_monitor.c
+++ b/src/lxc/lxc_monitor.c
@@ -169,9 +169,7 @@ virLXCMonitor *virLXCMonitorNew(virDomainObj *vm,
  mon)))
  goto error;
  
-if (virNetClientAddProgram(mon->client,

-   mon->program) < 0)
-goto error;
+virNetClientAddProgram(mon->client, mon->program);
  
  mon->vm = virObjectRef(vm);

  memcpy(>cb, cb, sizeof(mon->cb));
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 132d0194c6..8db638d6cc 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -1160,10 +1160,9 @@ doRemoteOpen(virConnectPtr conn,
   conn)))
  goto error;
  
-if (virNetClientAddProgram(priv->client, priv->remoteProgram) < 0 ||

-virNetClientAddProgram(priv->client, priv->lxcProgram) < 0 ||
-virNetClientAddProgram(priv->client, priv->qemuProgram) < 0)
-goto error;
+virNetClientAddProgram(priv->client, priv->remoteProgram);
+virNetClientAddProgram(priv->client, priv->lxcProgram);
+virNetClientAddProgram(priv->client, priv->qemuProgram);
  
  /* Try and authenticate with server */

  VIR_DEBUG("Trying authentication");
diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c
index 4ab8af68c5..c5be82abee 100644
--- a/src/rpc/virnetclient.c
+++ b/src/rpc/virnetclient.c
@@ -1053,7 +1053,7 @@ bool virNetClientIsOpen(virNetClient *client)
  }
  
  
-int virNetClientAddProgram(virNetClient *client,

+void virNetClientAddProgram(virNetClient *client,
 virNetClientProgram *prog)
  {
  virObjectLock(client);
@@ -1062,7 +1062,6 @@ int virNetClientAddProgram(virNetClient *client,
  client->programs[client->nprograms-1] = virObjectRef(prog);
  
  virObjectUnlock(client);

-return 0;
  }
  
  
diff --git a/src/rpc/virnetclient.h b/src/rpc/virnetclient.h

index 1647a6cc71..7726b57ef4 100644
--- a/src/rpc/virnetclient.h
+++ b/src/rpc/virnetclient.h
@@ -117,7 +117,7 @@ int virNetClientDupFD(virNetClient *client, bool cloexec);
  
  bool virNetClientHasPassFD(virNetClient *client);
  
-int virNetClientAddProgram(virNetClient *client,

+void virNetClientAddProgram(virNetClient *client,
 virNetClientProgram *prog);


another minor alignment issue here (though not obvious in my email reply)

  
  int virNetClientAddStream(virNetClient *client,

___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [PATCH v2 13/14] libxl: turn xenParseXLNamespaceData() to void

2023-12-14 Thread Jonathon Jongsma

On 12/14/23 8:51 AM, Dmitry Frolov wrote:

xenParseXLNamespaceData() always returns 0.

Signed-off-by: Dmitry Frolov 
---
  src/libxl/xen_xl.c | 5 ++---
  1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/src/libxl/xen_xl.c b/src/libxl/xen_xl.c
index 553aa77896..78a3e1d519 100644
--- a/src/libxl/xen_xl.c
+++ b/src/libxl/xen_xl.c
@@ -1017,7 +1017,7 @@ xenParseXLChannel(virConf *conf, virDomainDef *def)
  return -1;
  }
  
-static int

+static void
  xenParseXLNamespaceData(virConf *conf, virDomainDef *def)
  {
  virConfValue *list = virConfGetValue(conf, "device_model_args");


You changed the return type to void, but you didn't actually remove the 
'return' statements from the function.




@@ -1104,8 +1104,7 @@ xenParseXL(virConf *conf,
  if (xenParseXLChannel(conf, def) < 0)
  return NULL;
  
-if (xenParseXLNamespaceData(conf, def) < 0)

-return NULL;
+xenParseXLNamespaceData(conf, def);
  
  if (virDomainDefPostParse(def, VIR_DOMAIN_DEF_PARSE_ABI_UPDATE,

xmlopt, NULL) < 0)

___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


Re: [PATCH v2 11/14] conf: turn virDomainGraphicsListenAppendAddress() to void

2023-12-14 Thread Jonathon Jongsma

On 12/14/23 8:51 AM, Dmitry Frolov wrote:

virDomainGraphicsListenAppendAddress() always returns 0.

Signed-off-by: Dmitry Frolov 
---
  src/conf/domain_conf.c | 4 +---
  src/conf/domain_conf.h | 2 +-
  src/libxl/xen_common.c | 7 ++-
  src/libxl/xen_xl.c | 3 +--
  src/vbox/vbox_common.c | 4 +---
  src/vmx/vmx.c  | 3 +--
  6 files changed, 7 insertions(+), 16 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 22ad43e1d7..7b4d86d837 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -29053,7 +29053,7 @@ virDomainGraphicsGetListen(virDomainGraphicsDef *def, 
size_t i)
  }
  
  
-int

+void
  virDomainGraphicsListenAppendAddress(virDomainGraphicsDef *def,
   const char *address)
  {
@@ -29064,8 +29064,6 @@ 
virDomainGraphicsListenAppendAddress(virDomainGraphicsDef *def,
  glisten.address = g_strdup(address);
  
  VIR_APPEND_ELEMENT_COPY(def->listens, def->nListens, glisten);

-
-return 0;
  }
  
  
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h

index ed07859bc5..7002bd072b 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -3909,7 +3909,7 @@ int virDomainHostdevMatch(virDomainHostdevDef *a,
  
  virDomainGraphicsListenDef *

  virDomainGraphicsGetListen(virDomainGraphicsDef *def, size_t i);
-int virDomainGraphicsListenAppendAddress(virDomainGraphicsDef *def,
+void virDomainGraphicsListenAppendAddress(virDomainGraphicsDef *def,
   const char *address)


It looks like there's a slight alignment mismatch here now. The hanging 
function argument should probably be re-indented.




  ATTRIBUTE_NONNULL(1);
  int virDomainGraphicsListenAppendSocket(virDomainGraphicsDef *def,
diff --git a/src/libxl/xen_common.c b/src/libxl/xen_common.c
index d5a0399613..c7bc51b926 100644
--- a/src/libxl/xen_common.c
+++ b/src/libxl/xen_common.c
@@ -673,8 +673,7 @@ xenParseVfb(virConf *conf, virDomainDef *def)
  
  if (xenConfigCopyStringOpt(conf, "vnclisten", ) < 0)

  goto cleanup;
-if (virDomainGraphicsListenAppendAddress(graphics, listenAddr) < 0)
-goto cleanup;
+virDomainGraphicsListenAppendAddress(graphics, listenAddr);
  VIR_FREE(listenAddr);
  
  if (xenConfigCopyStringOpt(conf, "vncpasswd", >data.vnc.auth.passwd) < 0)

@@ -766,9 +765,7 @@ xenParseVfb(virConf *conf, virDomainDef *def)
  key = nextkey;
  }
  if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
-if (virDomainGraphicsListenAppendAddress(graphics,
- listenAddr) < 0)
-goto cleanup;
+virDomainGraphicsListenAppendAddress(graphics, listenAddr);
  VIR_FREE(listenAddr);
  }
  def->graphics = g_new0(virDomainGraphicsDef *, 1);
diff --git a/src/libxl/xen_xl.c b/src/libxl/xen_xl.c
index f175359307..553aa77896 100644
--- a/src/libxl/xen_xl.c
+++ b/src/libxl/xen_xl.c
@@ -341,8 +341,7 @@ xenParseXLSpice(virConf *conf, virDomainDef *def)
  graphics->type = VIR_DOMAIN_GRAPHICS_TYPE_SPICE;
  if (xenConfigCopyStringOpt(conf, "spicehost", ) < 0)
  goto cleanup;
-if (virDomainGraphicsListenAppendAddress(graphics, listenAddr) < 0)
-goto cleanup;
+virDomainGraphicsListenAppendAddress(graphics, listenAddr);
  
  if (xenConfigGetULong(conf, "spicetls_port", , 0) < 0)

  goto cleanup;
diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c
index de3c9989a5..9f6612ad61 100644
--- a/src/vbox/vbox_common.c
+++ b/src/vbox/vbox_common.c
@@ -3625,8 +3625,7 @@ vboxDumpDisplay(virDomainDef *def, struct _vboxDriver 
*data, IMachine *machine)
  if (netAddressUtf8 && STREQ(netAddressUtf8, ""))
  VBOX_UTF8_FREE(netAddressUtf8);
  
-if (virDomainGraphicsListenAppendAddress(graphics, netAddressUtf8) < 0)

-goto cleanup;
+virDomainGraphicsListenAppendAddress(graphics, netAddressUtf8);
  
  gVBoxAPI.UIVRDEServer.GetAllowMultiConnection(VRDEServer, );

  if (allowMultiConnection)
@@ -3641,7 +3640,6 @@ vboxDumpDisplay(virDomainDef *def, struct _vboxDriver 
*data, IMachine *machine)
  
  ret = 0;
  
- cleanup:

  VBOX_RELEASE(VRDEServer);
  VBOX_UTF8_FREE(valueTypeUtf8);
  VBOX_UTF8_FREE(netAddressUtf8);
diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c
index 26b89776e1..e746ff213b 100644
--- a/src/vmx/vmx.c
+++ b/src/vmx/vmx.c
@@ -2017,8 +2017,7 @@ virVMXParseVNC(virConf *conf, virDomainGraphicsDef **def)
  goto failure;
  }
  
-if (virDomainGraphicsListenAppendAddress(*def, listenAddr) < 0)

-goto failure;
+virDomainGraphicsListenAppendAddress(*def, listenAddr);
  VIR_FREE(listenAddr);
  
  if (port < 0) {


Re: [PATCH v2 0/9] RFC: Add versioned CPUs to libvirt

2023-12-08 Thread Jonathon Jongsma

On 12/8/23 5:03 AM, Daniel P. Berrangé wrote:

On Thu, Dec 07, 2023 at 04:07:48PM -0600, Jonathon Jongsma wrote:

For SEV-SNP support we will need to be able to specify versioned CPU models
that are not yet available in libvirt. Rather than just adding a versioned CPU
or two that would satisfy that immediate need, I decided to try to add
versioned CPUs in a more standard way. This series generates CPU definitions
for all cpu versions that are defined in upstream qemu (at least for
recent Intel and AMD CPUs).

libvirt already provides a select subset of these versions as configurable CPU
models. But we only include the ones that have defined aliases in qemu, such as
EPYC-IBPB. After this patchset, all verisioned cpu models supported by qemu
will be available in libvirt.

Note that I'm only adding versions that are not already available via their
alias. For example, I am not adding an EPYC-v2 CPU model since it is already
available as EPYC-IBPB.


That is not reliable, as the alias mapping between a short name "EPYC"
and a version is set by the choice of machine type.

ie one machine type might map EPYC to v1, and another machine type
might map EPYC to v2.

It just happens to be the case that currently all machine types have
the same alias expansion, but that's not guaranteed.

So if we're going down this route, we need to bring in all versioned
machine types.



I suppose this is true, but it doesn't seem meaningfully different than 
our current situation where we have already introduced a subset of 
versioned types. It's just that we've only added the ones with 
human-readable names. So while this patch doesn't solve the issue you 
mentioned, I don't think that it makes the situation any worse. We are 
already susceptible to any changes that qemu might make with respect to 
machine-specific CPU aliases. But I'll try to figure out a more 
comprehensive approach.


Jonathon
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


[PATCH v2 1/9] cpu_map: update script to generate versioned CPUs

2023-12-07 Thread Jonathon Jongsma
Previously, the script only generated the parent CPU and any versions
that had a defined alias. Now generate all CPU versions. Any version
that had a defined alias will continue to use that alias, but those
without aliases will use the generated name $BASECPUNAME-vN. This
generated name will be used as an alternate name for those CPU versions
with defined aliases.

Signed-off-by: Jonathon Jongsma 
---
 src/cpu_map/sync_qemu_models_i386.py | 44 +++-
 1 file changed, 36 insertions(+), 8 deletions(-)

diff --git a/src/cpu_map/sync_qemu_models_i386.py 
b/src/cpu_map/sync_qemu_models_i386.py
index 1c6a2d4d27..956e4700de 100755
--- a/src/cpu_map/sync_qemu_models_i386.py
+++ b/src/cpu_map/sync_qemu_models_i386.py
@@ -322,31 +322,55 @@ def expand_model(model):
 different fields and may have differing versions into several libvirt-
 friendly cpu models."""
 
-result = {
-"name": model.pop(".name"),
+basename = model.pop(".name")
+parent = {
+"name": basename,
+"alias": None,
 "vendor": translate_vendor(model.pop(".vendor")),
 "features": set(),
 "extra": dict()}
 
 if ".family" in model and ".model" in model:
-result["family"] = model.pop(".family")
-result["model"] = model.pop(".model")
+parent["family"] = model.pop(".family")
+parent["model"] = model.pop(".model")
 
 for k in [k for k in model if k.startswith(".features")]:
 v = model.pop(k)
 for feature in v.split():
 translated = translate_feature(feature)
 if translated:
-result["features"].add(translated)
+parent["features"].add(translated)
 
 versions = model.pop(".versions", [])
 for k, v in model.items():
-result["extra"]["model" + k] = v
-yield result
+parent["extra"]["model" + k] = v
+
+result = parent
 
 for version in versions:
+# each version builds on the previous one
 result = copy.deepcopy(result)
-result["name"] = version.pop(".alias", result["name"])
+vnum = int(version.pop(".version"))
+vname = "{}-v{}".format(basename, vnum)
+if vnum == 1:
+# the first version should always be an alias for the parent and
+# should therefore have no extra properties
+if version.items():
+raise RuntimeError("Unexpected properties in version 1")
+# just treat this version as an alias of the parent model and don't
+# generate a new CPU model
+parent["alias"] = vname
+continue
+
+# prefer the 'alias' over the generated the name if it exists since we
+# have already been using these aliases
+alias = version.pop(".alias", None)
+if alias:
+result["name"] = alias
+result["alias"] = vname
+else:
+result["name"] = vname
+result["alias"] = None
 
 props = version.pop(".props", dict())
 for k, v in props:
@@ -367,6 +391,8 @@ def expand_model(model):
 
 yield result
 
+yield parent
+
 
 def output_model(f, model):
 if model["extra"]:
@@ -377,6 +403,8 @@ def output_model(f, model):
 
 f.write("\n")
 f.write("  \n".format(model["name"]))
+if model["alias"]:
+f.write("\n".format(model["alias"]))
 f.write("\n")
 f.write("\n".format(
 model["family"], model["model"]))
-- 
2.41.0
___
Devel mailing list -- devel@lists.libvirt.org
To unsubscribe send an email to devel-le...@lists.libvirt.org


[PATCH v2 4/9] cpu_map: Add versioned Intel Cascadelake CPUs

2023-12-07 Thread Jonathon Jongsma
Signed-off-by: Jonathon Jongsma 
---
 src/cpu_map/index.xml |  3 +
 src/cpu_map/meson.build   |  3 +
 src/cpu_map/x86_Cascadelake-Server-v2.xml | 93 +++
 src/cpu_map/x86_Cascadelake-Server-v4.xml | 91 ++
 src/cpu_map/x86_Cascadelake-Server-v5.xml | 92 ++
 .../x86_64-cpuid-Xeon-Platinum-8268-guest.xml |  9 +-
 .../x86_64-cpuid-Xeon-Platinum-8268-host.xml  |  9 +-
 .../x86_64-cpuid-Xeon-Platinum-9242-guest.xml |  9 +-
 .../x86_64-cpuid-Xeon-Platinum-9242-host.xml  |  9 +-
 .../x86_64-cpuid-Xeon-Platinum-9242-json.xml  |  9 +-
 ..._64-cpuid-baseline-Cascadelake+Icelake.xml |  9 +-
 ...-cpuid-baseline-Cooperlake+Cascadelake.xml |  9 +-
 ...6_64-cpuid-baseline-Cooperlake+Icelake.xml |  9 +-
 .../domaincapsdata/qemu_4.2.0-q35.x86_64.xml  |  1 +
 .../domaincapsdata/qemu_4.2.0-tcg.x86_64.xml  |  1 +
 tests/domaincapsdata/qemu_4.2.0.x86_64.xml|  1 +
 .../domaincapsdata/qemu_5.0.0-q35.x86_64.xml  |  1 +
 .../domaincapsdata/qemu_5.0.0-tcg.x86_64.xml  |  1 +
 tests/domaincapsdata/qemu_5.0.0.x86_64.xml|  1 +
 .../domaincapsdata/qemu_5.1.0-q35.x86_64.xml  |  2 +
 .../domaincapsdata/qemu_5.1.0-tcg.x86_64.xml  |  2 +
 tests/domaincapsdata/qemu_5.1.0.x86_64.xml|  2 +
 .../domaincapsdata/qemu_5.2.0-q35.x86_64.xml  |  2 +
 .../domaincapsdata/qemu_5.2.0-tcg.x86_64.xml  |  2 +
 tests/domaincapsdata/qemu_5.2.0.x86_64.xml|  2 +
 .../domaincapsdata/qemu_6.0.0-q35.x86_64.xml  |  2 +
 .../domaincapsdata/qemu_6.0.0-tcg.x86_64.xml  |  2 +
 tests/domaincapsdata/qemu_6.0.0.x86_64.xml|  2 +
 .../domaincapsdata/qemu_6.1.0-q35.x86_64.xml  |  3 +
 .../domaincapsdata/qemu_6.1.0-tcg.x86_64.xml  |  3 +
 tests/domaincapsdata/qemu_6.1.0.x86_64.xml|  3 +
 .../domaincapsdata/qemu_6.2.0-q35.x86_64.xml  |  3 +
 .../domaincapsdata/qemu_6.2.0-tcg.x86_64.xml  |  3 +
 tests/domaincapsdata/qemu_6.2.0.x86_64.xml|  3 +
 .../domaincapsdata/qemu_7.0.0-q35.x86_64.xml  |  3 +
 .../domaincapsdata/qemu_7.0.0-tcg.x86_64.xml  |  3 +
 tests/domaincapsdata/qemu_7.0.0.x86_64.xml|  3 +
 .../domaincapsdata/qemu_7.1.0-q35.x86_64.xml  |  3 +
 .../domaincapsdata/qemu_7.1.0-tcg.x86_64.xml  |  3 +
 tests/domaincapsdata/qemu_7.1.0.x86_64.xml|  3 +
 .../domaincapsdata/qemu_7.2.0-q35.x86_64.xml  |  3 +
 .../qemu_7.2.0-tcg.x86_64+hvf.xml |  3 +
 .../domaincapsdata/qemu_7.2.0-tcg.x86_64.xml  |  3 +
 tests/domaincapsdata/qemu_7.2.0.x86_64.xml|  3 +
 .../domaincapsdata/qemu_8.0.0-q35.x86_64.xml  |  3 +
 .../domaincapsdata/qemu_8.0.0-tcg.x86_64.xml  |  3 +
 tests/domaincapsdata/qemu_8.0.0.x86_64.xml|  3 +
 .../domaincapsdata/qemu_8.1.0-q35.x86_64.xml  |  3 +
 .../domaincapsdata/qemu_8.1.0-tcg.x86_64.xml  |  3 +
 tests/domaincapsdata/qemu_8.1.0.x86_64.xml|  3 +
 .../domaincapsdata/qemu_8.2.0-q35.x86_64.xml  |  3 +
 .../domaincapsdata/qemu_8.2.0-tcg.x86_64.xml  |  3 +
 tests/domaincapsdata/qemu_8.2.0.x86_64.xml|  3 +
 53 files changed, 399 insertions(+), 54 deletions(-)
 create mode 100644 src/cpu_map/x86_Cascadelake-Server-v2.xml
 create mode 100644 src/cpu_map/x86_Cascadelake-Server-v4.xml
 create mode 100644 src/cpu_map/x86_Cascadelake-Server-v5.xml

diff --git a/src/cpu_map/index.xml b/src/cpu_map/index.xml
index a4fe2ec781..ad6361ee51 100644
--- a/src/cpu_map/index.xml
+++ b/src/cpu_map/index.xml
@@ -53,6 +53,9 @@
 
 
 
+
+
+
 
 
 
diff --git a/src/cpu_map/meson.build b/src/cpu_map/meson.build
index f6b95863b3..7a3712280a 100644
--- a/src/cpu_map/meson.build
+++ b/src/cpu_map/meson.build
@@ -29,6 +29,9 @@ cpumap_data = [
   'x86_Broadwell-noTSX.xml',
   'x86_Broadwell.xml',
   'x86_Cascadelake-Server-noTSX.xml',
+  'x86_Cascadelake-Server-v2.xml',
+  'x86_Cascadelake-Server-v4.xml',
+  'x86_Cascadelake-Server-v5.xml',
   'x86_Cascadelake-Server.xml',
   'x86_Conroe.xml',
   'x86_Cooperlake.xml',
diff --git a/src/cpu_map/x86_Cascadelake-Server-v2.xml 
b/src/cpu_map/x86_Cascadelake-Server-v2.xml
new file mode 100644
index 00..5152f0390b
--- /dev/null
+++ b/src/cpu_map/x86_Cascadelake-Server-v2.xml
@@ -0,0 +1,93 @@
+
+
+  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  
+
diff --git a/src/cpu_map/x86_Cascadelake-Server-v4.xml 
b/src/cpu_map/x86_Cascadelake-Server-v4.xml
new file mode 100644
index 00..b2173d1308
--- /dev/null
+++ b/src/cpu_map/x86_Cascadelake-Server-v4.xml
@@ -0,0 +1,91

  1   2   >