[libvirt PATCH] nss: Use shared_library() for nss_libvirt_lib

2021-12-10 Thread Andrea Bolognani
shared_module() is intended for shared objects that are
loaded at runtime using dlopen() whereas NSS plugins need to
be full-fledged shared libraries with, among other things, a
proper SONAME.

Meson seems to have become more strict about this recently,
because libnss_libvirt.so.2 gets a SONAME when I build it with
Meson 0.59.4 on Fedora 34 but doesn't when I use Meson 0.60.2
on Debian testing instead.

Either way, shared_library() was always the right function
to use for NSS plugins.

Fixes: 36780c931900555706fd6db9fc2ce2b4cabf9045
Signed-off-by: Andrea Bolognani 
---
 tools/nss/meson.build | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/nss/meson.build b/tools/nss/meson.build
index 198936f3d4..f77309ebca 100644
--- a/tools/nss/meson.build
+++ b/tools/nss/meson.build
@@ -59,7 +59,7 @@ nss_libvirt_guest_syms = '@0@@1@'.format(
   meson.current_source_dir() / nss_guest_sym_file,
 )
 
-nss_libvirt_lib = shared_module(
+nss_libvirt_lib = shared_library(
   'nss_libvirt',
   name_prefix: nss_prefix,
   name_suffix: 'so.@0@'.format(nss_so_ver),
-- 
2.31.1



Re: [libvirt PATCH 3/6] virt-ssh-helper: Add manual page

2021-12-10 Thread Ján Tomko

On a Friday in 2021, Andrea Bolognani wrote:

On Fri, Dec 10, 2021 at 06:23:22PM +0100, Ján Tomko wrote:

On a Friday in 2021, Andrea Bolognani wrote:
> docs/manpages/meson.build |  1 +
> docs/manpages/virt-ssh-helper.rst | 96 +++
> libvirt.spec.in   |  1 +
> 3 files changed, 98 insertions(+)
> create mode 100644 docs/manpages/virt-ssh-helper.rst


Sorry, I mistakenly thought you had R-b'd the entire series so I have
already pushed it! :(



Oh no, I can't have my name associated with that patch.

I'll push the revert if the pipeline succeeds, probably on Monday:
https://gitlab.com/janotomko/libvirt/-/pipelines/427288272

Jano


I'm not convinced we need a manual page for an internal tool.

We don't have one for any other -helper binaries and qemu-bridge-helper
also comes without a man page.


The difference between the other helpers and virt-ssh-helper is that
the latter is installed in the default $PATH.

So a random user is likely to see the name when using shell
completion after typing "virt-" and wonder what the tool is all
about. I think that justifies having a brief manual page for it.

--
Andrea Bolognani / Red Hat / Virtualization



signature.asc
Description: PGP signature


Re: [libvirt PATCH v2 03/17] ch_domain: fix indentation in ch_domain

2021-12-10 Thread Praveen K Paladugu




On 12/3/2021 11:28 AM, Ján Tomko wrote:

On a Thursday in 2021, Praveen K Paladugu wrote:

Signed-off-by: Praveen K Paladugu 
---
src/ch/ch_domain.c | 130 ++---
1 file changed, 64 insertions(+), 66 deletions(-)

diff --git a/src/ch/ch_domain.c b/src/ch/ch_domain.c
index dd4de9e1ea..44f7d26ca4 100644
--- a/src/ch/ch_domain.c
+++ b/src/ch/ch_domain.c
@@ -30,16 +30,12 @@

static int
-virCHDomainObjInitJob(virCHDomainObjPrivate *priv)
+virCHDomainObjInitJob(virCHDomainObjPrivate * priv)


The prevailing style in libvirt codebase is no space after the '*'


Fixed in v3



{
    memset(>job, 0, sizeof(priv->job));




[...]

-    if (def->nserials && def->serials[0]->source->type != 
VIR_DOMAIN_CHR_TYPE_PTY) {

+    if (def->nserials
+    && def->serials[0]->source->type != VIR_DOMAIN_CHR_TYPE_PTY) {
    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
   _("Serial can only be enabled for a PTY"));
    return -1;


80 columns is not a hard limit, there's no need to touch this.


Addressed in v3


Jano


--
2.27.0




--
Regards,
Praveen K Paladugu




Re: [libvirt PATCH v2 02/17] util: Helper functions to get process info

2021-12-10 Thread Praveen K Paladugu




On 12/3/2021 11:26 AM, Ján Tomko wrote:

On a Thursday in 2021, Praveen K Paladugu wrote:

Signed-off-by: Praveen K Paladugu 


It would be helpful to say in the commit message that the functions are
being moved, not newly introduced.


Fixed in v3


Jano


---
src/libvirt_private.syms |   2 +
src/qemu/qemu_driver.c   | 116 ++-
src/util/virprocess.c    | 108 
src/util/virprocess.h    |   5 ++
4 files changed, 120 insertions(+), 111 deletions(-)



--
Regards,
Praveen K Paladugu




Re: [libvirt PATCH v2 11/17] qemu, hypervisor: refactor some cgroup mgmt methods

2021-12-10 Thread Praveen K Paladugu




On 12/3/2021 11:38 AM, Ján Tomko wrote:

On a Thursday in 2021, Praveen K Paladugu wrote:

Refactor some cgroup management methods from qemu into hypervisor.
These methods will be shared by ch driver for cgroup management.



The QEMU driver fails to compile after this patch - it seems
qemu_process.c needs to include the header with the functions.

To get a build coverage for most of our supported platforms,
you can push into your private fork of the libvirt repo on gitlab.
The pipeline should run automatically.

Thanks for the pointer Jano. I fixed the build issue and also confirmed 
majority of the builds pass in gitlab's CI.



Jano


Signed-off-by: Praveen K Paladugu 
---
src/hypervisor/domain_cgroup.c | 426 -
src/hypervisor/domain_cgroup.h |  52 
src/libvirt_private.syms   |  10 +
src/qemu/qemu_cgroup.c | 410 +--
src/qemu/qemu_cgroup.h |  11 -
src/qemu/qemu_driver.c |  14 +-
src/qemu/qemu_hotplug.c    |   4 +-
src/qemu/qemu_process.c    |  17 +-
8 files changed, 515 insertions(+), 429 deletions(-)



--
Regards,
Praveen K Paladugu




[libvirt PATCH v3 11/13] ch_driver: add numatune callbacks for CH driver

2021-12-10 Thread Praveen K Paladugu
From: Vineeth Pillai 

Signed-off-by: Vineeth Pillai 
Signed-off-by: Praveen K Paladugu 
---
 src/ch/ch_driver.c | 273 +
 1 file changed, 273 insertions(+)

diff --git a/src/ch/ch_driver.c b/src/ch/ch_driver.c
index 03db6b2bc8..d7008ef011 100644
--- a/src/ch/ch_driver.c
+++ b/src/ch/ch_driver.c
@@ -43,6 +43,7 @@
 #include "viruri.h"
 #include "virutil.h"
 #include "viruuid.h"
+#include "virnuma.h"
 
 #define VIR_FROM_THIS VIR_FROM_CH
 
@@ -1296,6 +1297,276 @@ chDomainPinVcpu(virDomainPtr dom,
   VIR_DOMAIN_AFFECT_LIVE);
 }
 
+#define CH_NB_NUMA_PARAM 2
+
+static int
+chDomainGetNumaParameters(virDomainPtr dom,
+  virTypedParameterPtr params,
+  int *nparams,
+  unsigned int flags)
+{
+size_t i;
+virDomainObj *vm = NULL;
+virDomainNumatuneMemMode tmpmode = VIR_DOMAIN_NUMATUNE_MEM_STRICT;
+virCHDomainObjPrivate *priv;
+g_autofree char *nodeset = NULL;
+int ret = -1;
+virDomainDef *def = NULL;
+bool live = false;
+virBitmap *autoNodeset = NULL;
+
+virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
+  VIR_DOMAIN_AFFECT_CONFIG |
+  VIR_TYPED_PARAM_STRING_OKAY, -1);
+
+if (!(vm = virCHDomainObjFromDomain(dom)))
+return -1;
+priv = vm->privateData;
+
+if (virDomainGetNumaParametersEnsureACL(dom->conn, vm->def) < 0)
+goto cleanup;
+
+if (!(def = virDomainObjGetOneDefState(vm, flags, )))
+goto cleanup;
+
+if (live)
+autoNodeset = priv->autoNodeset;
+
+if ((*nparams) == 0) {
+*nparams = CH_NB_NUMA_PARAM;
+ret = 0;
+goto cleanup;
+}
+
+for (i = 0; i < CH_NB_NUMA_PARAM && i < *nparams; i++) {
+virMemoryParameterPtr param = [i];
+
+switch (i) {
+case 0: /* fill numa mode here */
+ignore_value(virDomainNumatuneGetMode(def->numa, -1, ));
+
+if (virTypedParameterAssign(param, VIR_DOMAIN_NUMA_MODE,
+VIR_TYPED_PARAM_INT, tmpmode) < 0)
+goto cleanup;
+
+break;
+
+case 1: /* fill numa nodeset here */
+nodeset = virDomainNumatuneFormatNodeset(def->numa, autoNodeset, 
-1);
+
+if (!nodeset ||
+virTypedParameterAssign(param, VIR_DOMAIN_NUMA_NODESET,
+VIR_TYPED_PARAM_STRING, nodeset) < 0)
+goto cleanup;
+
+nodeset = NULL;
+break;
+
+/* coverity[dead_error_begin] */
+default:
+break;
+/* should not hit here */
+}
+}
+
+if (*nparams > CH_NB_NUMA_PARAM)
+*nparams = CH_NB_NUMA_PARAM;
+ret = 0;
+
+ cleanup:
+virDomainObjEndAPI();
+return ret;
+}
+
+static int
+chDomainSetNumaParamsLive(virDomainObj *vm,
+  virBitmap *nodeset)
+{
+g_autoptr(virCgroup) cgroup_temp = NULL;
+virCHDomainObjPrivate *priv = vm->privateData;
+g_autofree char *nodeset_str = NULL;
+virDomainNumatuneMemMode mode;
+size_t i = 0;
+
+
+if (virDomainNumatuneGetMode(vm->def->numa, -1, ) == 0 &&
+mode != VIR_DOMAIN_NUMATUNE_MEM_STRICT) {
+virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+   _("change of nodeset for running domain requires strict 
numa mode"));
+return -1;
+}
+
+if (!virNumaNodesetIsAvailable(nodeset))
+return -1;
+
+/* Ensure the cpuset string is formatted before passing to cgroup */
+if (!(nodeset_str = virBitmapFormat(nodeset)))
+return -1;
+
+if (virCgroupNewThread(priv->cgroup, VIR_CGROUP_THREAD_EMULATOR, 0,
+   false, _temp) < 0 ||
+virCgroupSetCpusetMems(cgroup_temp, nodeset_str) < 0)
+return -1;
+
+
+for (i = 0; i < virDomainDefGetVcpusMax(vm->def); i++) {
+virDomainVcpuDef *vcpu = virDomainDefGetVcpu(vm->def, i);
+
+if (!vcpu->online)
+continue;
+
+if (virCgroupNewThread(priv->cgroup, VIR_CGROUP_THREAD_VCPU, i,
+   false, _temp) < 0 ||
+virCgroupSetCpusetMems(cgroup_temp, nodeset_str) < 0)
+return -1;
+
+return 0;
+}
+
+for (i = 0; i < vm->def->niothreadids; i++) {
+if (virCgroupNewThread(priv->cgroup, VIR_CGROUP_THREAD_IOTHREAD,
+   vm->def->iothreadids[i]->iothread_id,
+   false, _temp) < 0 ||
+virCgroupSetCpusetMems(cgroup_temp, nodeset_str) < 0)
+return -1;
+}
+
+/* set nodeset for root cgroup */
+if (virCgroupSetCpusetMems(priv->cgroup, nodeset_str) < 0)
+return -1;
+
+return 0;
+}
+
+static int
+chDomainSetNumaParameters(virDomainPtr dom,
+  virTypedParameterPtr params,
+  int nparams,
+ 

[libvirt PATCH v3 04/13] ch_driver, ch_domain: vcpu info getter callbacks

2021-12-10 Thread Praveen K Paladugu
Signed-off-by: Vineeth Pillai 
Signed-off-by: Praveen K Paladugu 
---
 src/ch/ch_domain.c |  25 +
 src/ch/ch_domain.h |   4 ++
 src/ch/ch_driver.c | 134 +
 3 files changed, 163 insertions(+)

diff --git a/src/ch/ch_domain.c b/src/ch/ch_domain.c
index 36333a8a3f..3f34e87e04 100644
--- a/src/ch/ch_domain.c
+++ b/src/ch/ch_domain.c
@@ -336,3 +336,28 @@ virCHDomainGetMonitor(virDomainObj *vm)
 {
 return CH_DOMAIN_PRIVATE(vm)->monitor;
 }
+
+pid_t
+virCHDomainGetVcpuPid(virDomainObj *vm, unsigned int vcpuid)
+{
+virDomainVcpuDef *vcpu = virDomainDefGetVcpu(vm->def, vcpuid);
+
+return CH_DOMAIN_VCPU_PRIVATE(vcpu)->tid;
+}
+
+bool
+virCHDomainHasVcpuPids(virDomainObj *vm)
+{
+size_t i;
+size_t maxvcpus = virDomainDefGetVcpusMax(vm->def);
+virDomainVcpuDef *vcpu;
+
+for (i = 0; i < maxvcpus; i++) {
+vcpu = virDomainDefGetVcpu(vm->def, i);
+
+if (CH_DOMAIN_VCPU_PRIVATE(vcpu)->tid > 0)
+return true;
+}
+
+return false;
+}
diff --git a/src/ch/ch_domain.h b/src/ch/ch_domain.h
index f01c0e5ad0..1ec7643216 100644
--- a/src/ch/ch_domain.h
+++ b/src/ch/ch_domain.h
@@ -82,3 +82,7 @@ virCHDomainObjBeginJob(virDomainObj *obj, enum virCHDomainJob 
job)
 
 void
 virCHDomainObjEndJob(virDomainObj *obj);
+
+int virCHDomainRefreshVcpuInfo(virDomainObj *vm);
+pid_t virCHDomainGetVcpuPid(virDomainObj *vm, unsigned int vcpuid);
+bool virCHDomainHasVcpuPids(virDomainObj *vm);
diff --git a/src/ch/ch_driver.c b/src/ch/ch_driver.c
index 108644e503..31e9de7f6a 100644
--- a/src/ch/ch_driver.c
+++ b/src/ch/ch_driver.c
@@ -942,6 +942,137 @@ static int chStateInitialize(bool privileged,
 return ret;
 }
 
+static int
+chDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags)
+{
+virDomainObj *vm;
+virDomainDef *def;
+int ret = -1;
+
+virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
+  VIR_DOMAIN_AFFECT_CONFIG |
+  VIR_DOMAIN_VCPU_MAXIMUM | VIR_DOMAIN_VCPU_GUEST, -1);
+
+if (!(vm = chDomObjFromDomain(dom)))
+return -1;
+
+if (virDomainGetVcpusFlagsEnsureACL(dom->conn, vm->def, flags) < 0)
+goto cleanup;
+
+if (!(def = virDomainObjGetOneDef(vm, flags)))
+goto cleanup;
+
+if (flags & VIR_DOMAIN_VCPU_MAXIMUM)
+ret = virDomainDefGetVcpusMax(def);
+else
+ret = virDomainDefGetVcpus(def);
+
+
+ cleanup:
+virDomainObjEndAPI();
+return ret;
+}
+
+static int
+chDomainGetMaxVcpus(virDomainPtr dom)
+{
+return chDomainGetVcpusFlags(dom,
+ (VIR_DOMAIN_AFFECT_LIVE |
+  VIR_DOMAIN_VCPU_MAXIMUM));
+}
+
+static int
+chDomainHelperGetVcpus(virDomainObj *vm,
+   virVcpuInfoPtr info,
+   unsigned long long *cpuwait,
+   int maxinfo, unsigned char *cpumaps, int maplen)
+{
+size_t ncpuinfo = 0;
+size_t i;
+
+if (maxinfo == 0)
+return 0;
+
+if (!virCHDomainHasVcpuPids(vm)) {
+virReportError(VIR_ERR_OPERATION_INVALID,
+   "%s", _("cpu affinity is not supported"));
+return -1;
+}
+
+if (info)
+memset(info, 0, sizeof(*info) * maxinfo);
+
+if (cpumaps)
+memset(cpumaps, 0, sizeof(*cpumaps) * maxinfo);
+
+for (i = 0; i < virDomainDefGetVcpusMax(vm->def) && ncpuinfo < maxinfo; 
i++) {
+virDomainVcpuDef *vcpu = virDomainDefGetVcpu(vm->def, i);
+pid_t vcpupid = virCHDomainGetVcpuPid(vm, i);
+virVcpuInfoPtr vcpuinfo = info + ncpuinfo;
+
+if (!vcpu->online)
+continue;
+
+if (info) {
+vcpuinfo->number = i;
+vcpuinfo->state = VIR_VCPU_RUNNING;
+if (virProcessGetStatInfo(>cpuTime,
+  >cpu, NULL,
+  vm->pid, vcpupid) < 0) {
+virReportSystemError(errno, "%s",
+  _("cannot get vCPU placement & pCPU 
time"));
+return -1;
+}
+}
+
+if (cpumaps) {
+unsigned char *cpumap = VIR_GET_CPUMAP(cpumaps, maplen, ncpuinfo);
+g_autoptr(virBitmap) map = NULL;
+
+if (!(map = virProcessGetAffinity(vcpupid)))
+return -1;
+
+virBitmapToDataBuf(map, cpumap, maplen);
+}
+
+if (cpuwait) {
+if (virProcessGetSchedInfo(&(cpuwait[ncpuinfo]), vm->pid, vcpupid) 
< 0)
+return -1;
+}
+
+ncpuinfo++;
+}
+
+return ncpuinfo;
+}
+
+static int
+chDomainGetVcpus(virDomainPtr dom,
+ virVcpuInfoPtr info,
+ int maxinfo, unsigned char *cpumaps, int maplen)
+{
+virDomainObj *vm;
+int ret = -1;
+
+if (!(vm = chDomObjFromDomain(dom)))
+goto cleanup;
+
+if (virDomainGetVcpusEnsureACL(dom->conn, vm->def) < 0)
+goto cleanup;
+
+if 

[libvirt PATCH v3 12/13] ch_process: Setup emulator and iothread settings

2021-12-10 Thread Praveen K Paladugu
using virCHProcessSetupPid

Signed-off-by: Praveen K Paladugu 
---
 src/ch/ch_monitor.c | 60 +++
 src/ch/ch_monitor.h |  2 ++
 src/ch/ch_process.c | 77 -
 3 files changed, 138 insertions(+), 1 deletion(-)

diff --git a/src/ch/ch_monitor.c b/src/ch/ch_monitor.c
index 4de86f3c03..1709c73181 100644
--- a/src/ch/ch_monitor.c
+++ b/src/ch/ch_monitor.c
@@ -921,3 +921,63 @@ virCHMonitorGetInfo(virCHMonitor *mon, virJSONValue **info)
 {
 return virCHMonitorGet(mon, URL_VM_INFO, info);
 }
+
+/**
+ * virCHMonitorGetIOThreads:
+ * @mon: Pointer to the monitor
+ * @iothreads: Location to return array of IOThreadInfo data
+ *
+ * Retrieve the list of iothreads defined/running for the machine
+ *
+ * Returns count of IOThreadInfo structures on success
+ *-1 on error.
+ */
+int virCHMonitorGetIOThreads(virCHMonitor *mon,
+virDomainIOThreadInfo ***iothreads)
+{
+size_t nthreads = 0, niothreads = 0;
+int thd_index;
+virDomainIOThreadInfo **iothreadinfolist = NULL, *iothreadinfo = NULL;
+
+*iothreads = NULL;
+nthreads = virCHMonitorRefreshThreadInfo(mon);
+
+iothreadinfolist = g_new0(virDomainIOThreadInfo*, nthreads);
+
+for (thd_index = 0; thd_index < nthreads; thd_index++) {
+virBitmap *map = NULL;
+if (mon->threads[thd_index].type == virCHThreadTypeIO) {
+iothreadinfo = g_new0(virDomainIOThreadInfo, 1);
+
+iothreadinfo->iothread_id = mon->threads[thd_index].ioInfo.tid;
+
+if (!(map = virProcessGetAffinity(iothreadinfo->iothread_id)))
+goto cleanup;
+
+if (virBitmapToData(map, &(iothreadinfo->cpumap),
+&(iothreadinfo->cpumaplen)) < 0) {
+virBitmapFree(map);
+goto cleanup;
+}
+virBitmapFree(map);
+//Append to iothreadinfolist
+iothreadinfolist[niothreads] = iothreadinfo;
+niothreads++;
+}
+}
+VIR_DELETE_ELEMENT_INPLACE(iothreadinfolist,
+   niothreads, nthreads);
+*iothreads = iothreadinfolist;
+VIR_DEBUG("niothreads = %ld", niothreads);
+return niothreads;
+
+cleanup:
+if (iothreadinfolist) {
+for (thd_index = 0; thd_index < niothreads; thd_index++)
+VIR_FREE(iothreadinfolist[thd_index]);
+VIR_FREE(iothreadinfolist);
+}
+if (iothreadinfo)
+VIR_FREE(iothreadinfo);
+return -1;
+}
diff --git a/src/ch/ch_monitor.h b/src/ch/ch_monitor.h
index f8c3fa75e8..98edb0faf9 100644
--- a/src/ch/ch_monitor.h
+++ b/src/ch/ch_monitor.h
@@ -118,3 +118,5 @@ int virCHMonitorGetCPUInfo(virCHMonitor *mon,
size_t maxvcpus);
 size_t virCHMonitorGetThreadInfo(virCHMonitor *mon, bool refresh,
  virCHMonitorThreadInfo **threads);
+int virCHMonitorGetIOThreads(virCHMonitor *mon,
+virDomainIOThreadInfo ***iothreads);
diff --git a/src/ch/ch_process.c b/src/ch/ch_process.c
index 56c8d4216d..1af89e0d9e 100644
--- a/src/ch/ch_process.c
+++ b/src/ch/ch_process.c
@@ -41,7 +41,6 @@ VIR_LOG_INIT("ch.ch_process");
 #define START_VM_POSTFIX ": starting up vm\n"
 
 
-
 static virCHMonitor *
 virCHProcessConnectMonitor(virCHDriver *driver,
virDomainObj *vm)
@@ -310,6 +309,74 @@ virCHProcessSetupPid(virDomainObj *vm,
 return ret;
 }
 
+static int
+virCHProcessSetupIOThread(virDomainObj *vm,
+ virDomainIOThreadInfo *iothread)
+{
+virCHDomainObjPrivate *priv = vm->privateData;
+return virCHProcessSetupPid(vm, iothread->iothread_id,
+   VIR_CGROUP_THREAD_IOTHREAD,
+   iothread->iothread_id,
+   priv->autoCpuset, // This should be updated 
when CLH supports accepting
+ // iothread settings from input domain 
definition
+   vm->def->cputune.iothread_period,
+   vm->def->cputune.iothread_quota,
+   NULL); // CLH doesn't allow choosing a 
scheduler for iothreads.
+}
+
+static int
+virCHProcessSetupIOThreads(virDomainObj *vm)
+{
+virCHDomainObjPrivate *priv = vm->privateData;
+virDomainIOThreadInfo **iothreads = NULL;
+size_t i;
+size_t  niothreads;
+
+niothreads = virCHMonitorGetIOThreads(priv->monitor, );
+for (i = 0; i < niothreads; i++) {
+VIR_DEBUG("IOThread index = %ld , tid = %d", i, 
iothreads[i]->iothread_id);
+if (virCHProcessSetupIOThread(vm, iothreads[i]) < 0)
+return -1;
+}
+return 0;
+}
+
+
+static int
+virCHProcessSetupEmulatorThread(virDomainObj *vm,
+ virCHMonitorEmuThreadInfo emuthread)
+{
+return virCHProcessSetupPid(vm, 

[libvirt PATCH v3 08/13] ch: methods for cgroup mgmt in ch driver

2021-12-10 Thread Praveen K Paladugu
From: Vineeth Pillai 

Signed-off-by: Vineeth Pillai 
Signed-off-by: Praveen K Paladugu 
---
 src/ch/ch_conf.c|   2 +
 src/ch/ch_conf.h|   4 +-
 src/ch/ch_domain.c  |  34 +
 src/ch/ch_domain.h  |   3 +-
 src/ch/ch_monitor.c |  96 ++
 src/ch/ch_monitor.h |  54 +++-
 src/ch/ch_process.c | 304 ++--
 src/ch/ch_process.h |   3 +
 8 files changed, 483 insertions(+), 17 deletions(-)

diff --git a/src/ch/ch_conf.c b/src/ch/ch_conf.c
index ef6f4b5ba8..cfc1174354 100644
--- a/src/ch/ch_conf.c
+++ b/src/ch/ch_conf.c
@@ -129,6 +129,8 @@ virCHDriverConfigNew(bool privileged)
 if (!(cfg = virObjectNew(virCHDriverConfigClass)))
 return NULL;
 
+cfg->cgroupControllers = -1; /* Auto detect */
+
 if (privileged) {
 if (virGetUserID(CH_USER, >user) < 0)
 return NULL;
diff --git a/src/ch/ch_conf.h b/src/ch/ch_conf.h
index 8fe69c8545..1790295ede 100644
--- a/src/ch/ch_conf.h
+++ b/src/ch/ch_conf.h
@@ -35,11 +35,13 @@ struct _virCHDriverConfig {
 
 char *stateDir;
 char *logDir;
-
+int cgroupControllers;
 uid_t user;
 gid_t group;
 };
 
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(virCHDriverConfig, virObjectUnref);
+
 struct _virCHDriver
 {
 virMutex lock;
diff --git a/src/ch/ch_domain.c b/src/ch/ch_domain.c
index 3a32ac63d9..42cb4e7dcf 100644
--- a/src/ch/ch_domain.c
+++ b/src/ch/ch_domain.c
@@ -324,6 +324,40 @@ chValidateDomainDeviceDef(const virDomainDeviceDef *dev,
_("Serial can only be enabled for a PTY"));
 return -1;
 }
+return 0;
+}
+
+int
+virCHDomainRefreshThreadInfo(virDomainObj *vm)
+{
+size_t maxvcpus = virDomainDefGetVcpusMax(vm->def);
+virCHMonitorThreadInfo *info = NULL;
+size_t nthreads, ncpus = 0;
+size_t i;
+
+nthreads = virCHMonitorGetThreadInfo(virCHDomainGetMonitor(vm),
+ true, );
+
+for (i = 0; i < nthreads; i++) {
+virCHDomainVcpuPrivate *vcpupriv;
+virDomainVcpuDef *vcpu;
+virCHMonitorCPUInfo *vcpuInfo;
+
+if (info[i].type != virCHThreadTypeVcpu)
+continue;
+
+/* TODO: hotplug support */
+vcpuInfo = [i].vcpuInfo;
+vcpu = virDomainDefGetVcpu(vm->def, vcpuInfo->cpuid);
+vcpupriv = CH_DOMAIN_VCPU_PRIVATE(vcpu);
+vcpupriv->tid = vcpuInfo->tid;
+ncpus++;
+}
+
+/* TODO: Remove the warning when hotplug is implemented.*/
+if (ncpus != maxvcpus)
+VIR_WARN("Mismatch in the number of cpus, expected: %ld, actual: %ld",
+ maxvcpus, ncpus);
 
 return 0;
 }
diff --git a/src/ch/ch_domain.h b/src/ch/ch_domain.h
index 4fc6251380..7cffe2b4fb 100644
--- a/src/ch/ch_domain.h
+++ b/src/ch/ch_domain.h
@@ -89,7 +89,8 @@ virCHDomainObjBeginJob(virDomainObj *obj, enum virCHDomainJob 
job)
 void
 virCHDomainObjEndJob(virDomainObj *obj);
 
-int virCHDomainRefreshVcpuInfo(virDomainObj *vm);
+int virCHDomainRefreshThreadInfo(virDomainObj *vm);
+
 pid_t virCHDomainGetVcpuPid(virDomainObj *vm, unsigned int vcpuid);
 bool virCHDomainHasVcpuPids(virDomainObj *vm);
 
diff --git a/src/ch/ch_monitor.c b/src/ch/ch_monitor.c
index d48b057814..f4e0f88817 100644
--- a/src/ch/ch_monitor.c
+++ b/src/ch/ch_monitor.c
@@ -41,6 +41,7 @@ VIR_LOG_INIT("ch.ch_monitor");
 
 static virClass *virCHMonitorClass;
 static void virCHMonitorDispose(void *obj);
+static void virCHMonitorThreadInfoFree(virCHMonitor * mon);
 
 static int virCHMonitorOnceInit(void)
 {
@@ -571,6 +572,7 @@ static void virCHMonitorDispose(void *opaque)
 virCHMonitor *mon = opaque;
 
 VIR_DEBUG("mon=%p", mon);
+virCHMonitorThreadInfoFree(mon);
 virObjectUnref(mon->vm);
 }
 
@@ -736,6 +738,100 @@ virCHMonitorGet(virCHMonitor *mon, const char *endpoint, 
virJSONValue **response
 return ret;
 }
 
+static void
+virCHMonitorThreadInfoFree(virCHMonitor *mon)
+{
+mon->nthreads = 0;
+if (mon->threads)
+VIR_FREE(mon->threads);
+}
+
+static size_t
+virCHMonitorRefreshThreadInfo(virCHMonitor *mon)
+{
+virCHMonitorThreadInfo *info = NULL;
+g_autofree pid_t *tids = NULL;
+virDomainObj *vm = mon->vm;
+size_t ntids = 0;
+size_t i;
+
+
+virCHMonitorThreadInfoFree(mon);
+if (virProcessGetPids(vm->pid, , ) < 0) {
+mon->threads = NULL;
+return 0;
+}
+
+info = g_new0(virCHMonitorThreadInfo, ntids);
+for (i = 0; i < ntids; i++) {
+g_autofree char *proc = NULL;
+g_autofree char *data = NULL;
+
+proc = g_strdup_printf("/proc/%d/task/%d/comm",
+   (int)vm->pid, (int)tids[i]);
+
+if (virFileReadAll(proc, (1 << 16), ) < 0) {
+continue;
+}
+
+VIR_DEBUG("VM PID: %d, TID %d, COMM: %s",
+  (int)vm->pid, (int)tids[i], data);
+if (STRPREFIX(data, "vcpu")) {
+int cpuid;
+char *tmp;
+
+if (virStrToLong_i(data + 4, , 0, ) < 0) {
+  

[libvirt PATCH v3 07/13] qemu, hypervisor: refactor some cgroup mgmt methods

2021-12-10 Thread Praveen K Paladugu
Refactor some cgroup management methods from qemu into hypervisor.
These methods will be shared with ch driver for cgroup management.

Signed-off-by: Praveen K Paladugu 
---
 src/hypervisor/domain_cgroup.c | 426 -
 src/hypervisor/domain_cgroup.h |  52 
 src/libvirt_private.syms   |  13 +
 src/qemu/qemu_cgroup.c | 410 +--
 src/qemu/qemu_cgroup.h |  11 -
 src/qemu/qemu_driver.c |  14 +-
 src/qemu/qemu_hotplug.c|   7 +-
 src/qemu/qemu_process.c|  20 +-
 8 files changed, 522 insertions(+), 431 deletions(-)

diff --git a/src/hypervisor/domain_cgroup.c b/src/hypervisor/domain_cgroup.c
index 61b54f071c..0a1b3867b1 100644
--- a/src/hypervisor/domain_cgroup.c
+++ b/src/hypervisor/domain_cgroup.c
@@ -22,11 +22,12 @@
 
 #include "domain_cgroup.h"
 #include "domain_driver.h"
-
+#include "util/virnuma.h"
+#include "virlog.h"
 #include "virutil.h"
 
 #define VIR_FROM_THIS VIR_FROM_DOMAIN
-
+VIR_LOG_INIT("domain.cgroup");
 
 int
 virDomainCgroupSetupBlkio(virCgroup *cgroup, virDomainBlkiotune blkio)
@@ -269,3 +270,424 @@ virDomainCgroupSetMemoryLimitParameters(virCgroup *cgroup,
 
 return 0;
 }
+
+
+int
+virSetupBlkioCgroup(virDomainObj *vm, virCgroup *cgroup)
+{
+
+if (!virCgroupHasController(cgroup, VIR_CGROUP_CONTROLLER_BLKIO)) {
+if (vm->def->blkio.weight || vm->def->blkio.ndevices) {
+virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+   _("Block I/O tuning is not available on this 
host"));
+return -1;
+} else {
+return 0;
+}
+}
+
+return virDomainCgroupSetupBlkio(cgroup, vm->def->blkio);
+}
+
+
+int
+virSetupMemoryCgroup(virDomainObj *vm, virCgroup *cgroup)
+{
+
+if (!virCgroupHasController(cgroup, VIR_CGROUP_CONTROLLER_MEMORY)) {
+if (virMemoryLimitIsSet(vm->def->mem.hard_limit) ||
+virMemoryLimitIsSet(vm->def->mem.soft_limit) ||
+virMemoryLimitIsSet(vm->def->mem.swap_hard_limit)) {
+virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+   _("Memory cgroup is not available on this host"));
+return -1;
+} else {
+return 0;
+}
+}
+
+return virDomainCgroupSetupMemtune(cgroup, vm->def->mem);
+}
+
+
+int
+virSetupCpusetCgroup(virCgroup *cgroup)
+{
+
+if (!virCgroupHasController(cgroup, VIR_CGROUP_CONTROLLER_CPUSET))
+return 0;
+
+if (virCgroupSetCpusetMemoryMigrate(cgroup, true) < 0)
+return -1;
+
+return 0;
+}
+
+
+int
+virSetupCpuCgroup(virDomainObj *vm, virCgroup *cgroup)
+{
+
+if (!virCgroupHasController(cgroup, VIR_CGROUP_CONTROLLER_CPU)) {
+if (vm->def->cputune.sharesSpecified) {
+virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+   _("CPU tuning is not available on this host"));
+return -1;
+} else {
+return 0;
+}
+}
+
+if (vm->def->cputune.sharesSpecified) {
+
+if (virCgroupSetCpuShares(cgroup, vm->def->cputune.shares) < 0)
+return -1;
+
+}
+
+return 0;
+}
+
+
+int
+virInitCgroup(const char *prefix,
+  virDomainObj * vm,
+  size_t nnicindexes, int *nicindexes,
+  virCgroup * cgroup, int cgroupControllers,
+  unsigned int maxThreadsPerProc,
+  bool privileged, char *machineName)
+{
+if (!privileged)
+return 0;
+
+if (!virCgroupAvailable())
+return 0;
+
+virCgroupFree(cgroup);
+cgroup = NULL;
+
+if (!vm->def->resource)
+vm->def->resource = g_new0(virDomainResourceDef, 1);
+
+if (!vm->def->resource->partition)
+vm->def->resource->partition = g_strdup("/machine");
+
+if (!g_path_is_absolute(vm->def->resource->partition)) {
+virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+   _("Resource partition '%s' must start with '/'"),
+   vm->def->resource->partition);
+return -1;
+}
+
+if (virCgroupNewMachine(machineName,
+prefix,
+vm->def->uuid,
+NULL,
+vm->pid,
+false,
+nnicindexes, nicindexes,
+vm->def->resource->partition,
+cgroupControllers,
+maxThreadsPerProc, ) < 0) {
+if (virCgroupNewIgnoreError())
+return 0;
+
+return -1;
+}
+
+return 0;
+}
+
+
+void
+virRestoreCgroupState(virDomainObj *vm, virCgroup *cgroup)
+{
+g_autofree char *mem_mask = NULL;
+size_t i = 0;
+
+g_autoptr(virBitmap) all_nodes = NULL;
+
+if (!virNumaIsAvailable() ||
+!virCgroupHasController(cgroup, VIR_CGROUP_CONTROLLER_CPUSET))
+return;
+
+if (!(all_nodes = 

[libvirt PATCH v3 02/13] ch_domain: add virCHDomainGetMonitor helper method

2021-12-10 Thread Praveen K Paladugu
From: Vineeth Pillai 

Signed-off-by: Vineeth Pillai 
Signed-off-by: Praveen K Paladugu 
---
 src/ch/ch_domain.c | 6 ++
 src/ch/ch_domain.h | 5 +
 2 files changed, 11 insertions(+)

diff --git a/src/ch/ch_domain.c b/src/ch/ch_domain.c
index dd4de9e1ea..bf4ce83595 100644
--- a/src/ch/ch_domain.c
+++ b/src/ch/ch_domain.c
@@ -290,3 +290,9 @@ virDomainDefParserConfig virCHDriverDomainDefParserConfig = 
{
 .domainPostParseCallback = virCHDomainDefPostParse,
 .deviceValidateCallback = chValidateDomainDeviceDef,
 };
+
+virCHMonitor *
+virCHDomainGetMonitor(virDomainObj *vm)
+{
+return CH_DOMAIN_PRIVATE(vm)->monitor;
+}
diff --git a/src/ch/ch_domain.h b/src/ch/ch_domain.h
index 61b34b0467..c053b25c65 100644
--- a/src/ch/ch_domain.h
+++ b/src/ch/ch_domain.h
@@ -57,6 +57,11 @@ struct _virCHDomainObjPrivate {
  virChrdevs *chrdevs;
 };
 
+#define CH_DOMAIN_PRIVATE(vm) \
+((virCHDomainObjPrivate*)(vm)->privateData)
+
+virCHMonitor *virCHDomainGetMonitor(virDomainObj *vm);
+
 extern virDomainXMLPrivateDataCallbacks virCHDriverPrivateDataCallbacks;
 extern virDomainDefParserConfig virCHDriverDomainDefParserConfig;
 
-- 
2.27.0




[libvirt PATCH v3 00/13] cgroup and thread management in ch driver.

2021-12-10 Thread Praveen K Paladugu
This patchset adds support for cgroup management of ch threads. This version
correctly manages cgroups for vcpu and emulator threads created by ch. cgroup
management for iothreads is not yet supported.

Along with cgroup management, this patchset also enables support for pinning
vcpu and emulator threads to selected host cpus.

v3:
* addrressed all the formatting comments in v2 patch set
* dropped indentation patches are they do not adhere to libvirt coding style
* fixed build issue in qemu driver that was introduced in v2

Praveen K Paladugu (5):
  util: Helper functions to get process info
  ch_driver,ch_domain: vcpu info getter callbacks
  qemu,hypervisor: refactor some cgroup mgmt methods
  ch_process: Setup emulator and iothread settings
  ch_driver: emulator threadinfo & pinning callbacks

Vineeth Pillai (8):
  ch_domain: add virCHDomainGetMonitor helper method
  ch_domain: add methods to manage private vcpu data
  ch_driver: domainGetVcpuPinInfo and nodeGetCPUMap
  ch_monitor: Get nicindexes in prep for cgroup mgmt
  ch: methods for cgroup mgmt in ch driver
  ch_driver,ch_domain: vcpupin callback in ch driver
  ch_driver: enable typed param string for numatune
  ch_driver: add numatune callbacks for CH driver

 src/ch/ch_conf.c   |   2 +
 src/ch/ch_conf.h   |   6 +-
 src/ch/ch_domain.c | 172 ++-
 src/ch/ch_domain.h |  32 +-
 src/ch/ch_driver.c | 789 +
 src/ch/ch_monitor.c| 341 +++---
 src/ch/ch_monitor.h|  60 ++-
 src/ch/ch_process.c| 385 +++-
 src/ch/ch_process.h|   3 +
 src/ch/meson.build |   1 +
 src/hypervisor/domain_cgroup.c | 426 +-
 src/hypervisor/domain_cgroup.h |  52 +++
 src/libvirt_private.syms   |  15 +
 src/qemu/qemu_cgroup.c | 410 +
 src/qemu/qemu_cgroup.h |  11 -
 src/qemu/qemu_driver.c | 130 +-
 src/qemu/qemu_hotplug.c|   7 +-
 src/qemu/qemu_process.c|  20 +-
 src/util/virprocess.c  | 108 +
 src/util/virprocess.h  |   5 +
 20 files changed, 2357 insertions(+), 618 deletions(-)

-- 
2.27.0




[libvirt PATCH v3 09/13] ch_driver, ch_domain: vcpupin callback in ch driver

2021-12-10 Thread Praveen K Paladugu
From: Vineeth Pillai 

Signed-off-by: Vineeth Pillai 
Signed-off-by: Praveen K Paladugu 
---
 src/ch/ch_domain.c  |  30 +
 src/ch/ch_domain.h  |   1 +
 src/ch/ch_driver.c  | 145 
 src/ch/ch_monitor.c |   2 +-
 4 files changed, 177 insertions(+), 1 deletion(-)

diff --git a/src/ch/ch_domain.c b/src/ch/ch_domain.c
index 42cb4e7dcf..524aa330e1 100644
--- a/src/ch/ch_domain.c
+++ b/src/ch/ch_domain.c
@@ -20,6 +20,7 @@
 
 #include 
 
+#include "datatypes.h"
 #include "ch_domain.h"
 #include "domain_driver.h"
 #include "viralloc.h"
@@ -420,3 +421,32 @@ virCHDomainGetMachineName(virDomainObj *vm)
 
 return ret;
 }
+
+/**
+ * virCHDomainObjFromDomain:
+ * @domain: Domain pointer that has to be looked up
+ *
+ * This function looks up @domain and returns the appropriate virDomainObjPtr
+ * that has to be released by calling virDomainObjEndAPI().
+ *
+ * Returns the domain object with incremented reference counter which is locked
+ * on success, NULL otherwise.
+ */
+virDomainObj *
+virCHDomainObjFromDomain(virDomainPtr domain)
+{
+virDomainObj *vm;
+virCHDriver *driver = domain->conn->privateData;
+char uuidstr[VIR_UUID_STRING_BUFLEN];
+
+vm = virDomainObjListFindByUUID(driver->domains, domain->uuid);
+if (!vm) {
+virUUIDFormat(domain->uuid, uuidstr);
+virReportError(VIR_ERR_NO_DOMAIN,
+   _("no domain with matching uuid '%s' (%s)"),
+   uuidstr, domain->name);
+return NULL;
+}
+
+return vm;
+}
diff --git a/src/ch/ch_domain.h b/src/ch/ch_domain.h
index 7cffe2b4fb..b4a245df54 100644
--- a/src/ch/ch_domain.h
+++ b/src/ch/ch_domain.h
@@ -95,3 +95,4 @@ pid_t virCHDomainGetVcpuPid(virDomainObj *vm, unsigned int 
vcpuid);
 bool virCHDomainHasVcpuPids(virDomainObj *vm);
 
 char *virCHDomainGetMachineName(virDomainObj *vm);
+virDomainObj *virCHDomainObjFromDomain(virDomain *domain);
diff --git a/src/ch/ch_driver.c b/src/ch/ch_driver.c
index 97fbd76959..0cc08b6c20 100644
--- a/src/ch/ch_driver.c
+++ b/src/ch/ch_driver.c
@@ -25,6 +25,7 @@
 #include "ch_driver.h"
 #include "ch_monitor.h"
 #include "ch_process.h"
+#include "domain_cgroup.h"
 #include "datatypes.h"
 #include "driver.h"
 #include "viraccessapicheck.h"
@@ -1123,6 +1124,148 @@ chDomainGetVcpus(virDomainPtr dom,
 return ret;
 }
 
+static int
+chDomainPinVcpuLive(virDomainObj *vm,
+virDomainDef *def,
+int vcpu,
+virCHDriver *driver,
+virCHDriverConfig *cfg,
+virBitmap *cpumap)
+{
+g_autoptr(virBitmap) tmpmap = NULL;
+g_autoptr(virCgroup) cgroup_vcpu = NULL;
+virDomainVcpuDef *vcpuinfo;
+virCHDomainObjPrivate *priv = vm->privateData;
+
+g_autofree char *str = NULL;
+
+if (!virCHDomainHasVcpuPids(vm)) {
+virReportError(VIR_ERR_OPERATION_INVALID,
+   "%s", _("cpu affinity is not supported"));
+return -1;
+}
+
+if (!(vcpuinfo = virDomainDefGetVcpu(def, vcpu))) {
+virReportError(VIR_ERR_INVALID_ARG,
+   _("vcpu %d is out of range of live cpu count %d"),
+   vcpu, virDomainDefGetVcpusMax(def));
+return -1;
+}
+
+if (!(tmpmap = virBitmapNewCopy(cpumap)))
+return -1;
+
+if (!(str = virBitmapFormat(cpumap)))
+return -1;
+
+if (vcpuinfo->online) {
+/* Configure the corresponding cpuset cgroup before set affinity. */
+if (virCgroupHasController(priv->cgroup, 
VIR_CGROUP_CONTROLLER_CPUSET)) {
+if (virCgroupNewThread(priv->cgroup, VIR_CGROUP_THREAD_VCPU, vcpu,
+   false, _vcpu) < 0)
+return -1;
+if (virSetupCgroupCpusetCpus(cgroup_vcpu, cpumap) < 0)
+return -1;
+}
+
+if (virProcessSetAffinity(virCHDomainGetVcpuPid(vm, vcpu), cpumap, 
false) < 0)
+return -1;
+}
+
+virBitmapFree(vcpuinfo->cpumask);
+vcpuinfo->cpumask = tmpmap;
+tmpmap = NULL;
+
+if (virDomainObjSave(vm, driver->xmlopt, cfg->stateDir) < 0)
+return -1;
+
+return 0;
+}
+
+
+static int
+chDomainPinVcpuFlags(virDomainPtr dom,
+ unsigned int vcpu,
+ unsigned char *cpumap,
+ int maplen,
+ unsigned int flags)
+{
+virCHDriver *driver = dom->conn->privateData;
+virDomainObj *vm;
+virDomainDef *def;
+virDomainDef *persistentDef;
+int ret = -1;
+virBitmap *pcpumap = NULL;
+virDomainVcpuDef *vcpuinfo = NULL;
+g_autoptr(virCHDriverConfig) cfg = NULL;
+
+virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
+  VIR_DOMAIN_AFFECT_CONFIG, -1);
+
+cfg = virCHDriverGetConfig(driver);
+
+if (!(vm = virCHDomainObjFromDomain(dom)))
+goto cleanup;
+
+if (virDomainPinVcpuFlagsEnsureACL(dom->conn, vm->def, flags) < 0)
+goto cleanup;
+

[libvirt PATCH v3 10/13] ch_driver: enable typed param string for numatune

2021-12-10 Thread Praveen K Paladugu
From: Vineeth Pillai 

Enable support of VIR_DRV_FEATURE_TYPED_PARAM_STRING to enable numatune

Signed-off-by: Vineeth Pillai 
Signed-off-by: Praveen K Paladugu 
---
 src/ch/ch_driver.c | 31 +++
 1 file changed, 31 insertions(+)

diff --git a/src/ch/ch_driver.c b/src/ch/ch_driver.c
index 0cc08b6c20..03db6b2bc8 100644
--- a/src/ch/ch_driver.c
+++ b/src/ch/ch_driver.c
@@ -944,6 +944,36 @@ static int chStateInitialize(bool privileged,
 return ret;
 }
 
+/* Which features are supported by this driver? */
+static int
+chConnectSupportsFeature(virConnectPtr conn, int feature)
+{
+if (virConnectSupportsFeatureEnsureACL(conn) < 0)
+return -1;
+
+switch ((virDrvFeature) feature) {
+case VIR_DRV_FEATURE_TYPED_PARAM_STRING:
+return 1;
+case VIR_DRV_FEATURE_MIGRATION_V2:
+case VIR_DRV_FEATURE_MIGRATION_V3:
+case VIR_DRV_FEATURE_MIGRATION_P2P:
+case VIR_DRV_FEATURE_MIGRATE_CHANGE_PROTECTION:
+case VIR_DRV_FEATURE_FD_PASSING:
+case VIR_DRV_FEATURE_XML_MIGRATABLE:
+case VIR_DRV_FEATURE_MIGRATION_OFFLINE:
+case VIR_DRV_FEATURE_MIGRATION_PARAMS:
+case VIR_DRV_FEATURE_MIGRATION_DIRECT:
+case VIR_DRV_FEATURE_MIGRATION_V1:
+case VIR_DRV_FEATURE_PROGRAM_KEEPALIVE:
+case VIR_DRV_FEATURE_REMOTE:
+case VIR_DRV_FEATURE_REMOTE_CLOSE_CALLBACK:
+case VIR_DRV_FEATURE_REMOTE_EVENT_CALLBACK:
+case VIR_DRV_FEATURE_NETWORK_UPDATE_HAS_CORRECT_ORDER:
+default:
+return 0;
+}
+}
+
 static int
 chDomainGetVcpusFlags(virDomainPtr dom, unsigned int flags)
 {
@@ -1279,6 +1309,7 @@ static virHypervisorDriver chHypervisorDriver = {
 .connectListAllDomains = chConnectListAllDomains,   /* 7.5.0 */
 .connectListDomains = chConnectListDomains, /* 7.5.0 */
 .connectGetCapabilities = chConnectGetCapabilities, /* 7.5.0 */
+.connectSupportsFeature = chConnectSupportsFeature, /* 8.0.0 */
 .domainCreateXML = chDomainCreateXML,   /* 7.5.0 */
 .domainCreate = chDomainCreate, /* 7.5.0 */
 .domainCreateWithFlags = chDomainCreateWithFlags,   /* 7.5.0 */
-- 
2.27.0




[libvirt PATCH v3 06/13] ch_monitor: Get nicindexes in prep for cgroup mgmt

2021-12-10 Thread Praveen K Paladugu
From: Vineeth Pillai 

Signed-off-by: Vineeth Pillai 
Signed-off-by: Praveen K Paladugu 
---
 src/ch/ch_conf.h|   2 +
 src/ch/ch_domain.c  |  27 ++-
 src/ch/ch_domain.h  |   2 +
 src/ch/ch_driver.c  |   1 +
 src/ch/ch_monitor.c | 185 ++--
 src/ch/ch_monitor.h |  14 +++-
 src/ch/ch_process.c |   6 +-
 src/ch/meson.build  |   1 +
 8 files changed, 179 insertions(+), 59 deletions(-)

diff --git a/src/ch/ch_conf.h b/src/ch/ch_conf.h
index 37c36d9a09..8fe69c8545 100644
--- a/src/ch/ch_conf.h
+++ b/src/ch/ch_conf.h
@@ -44,6 +44,8 @@ struct _virCHDriver
 {
 virMutex lock;
 
+bool privileged;
+
 /* Require lock to get a reference on the object,
  * lockless access thereafter */
 virCaps *caps;
diff --git a/src/ch/ch_domain.c b/src/ch/ch_domain.c
index 3f34e87e04..3a32ac63d9 100644
--- a/src/ch/ch_domain.c
+++ b/src/ch/ch_domain.c
@@ -21,10 +21,12 @@
 #include 
 
 #include "ch_domain.h"
+#include "domain_driver.h"
 #include "viralloc.h"
 #include "virchrdev.h"
 #include "virlog.h"
 #include "virtime.h"
+#include "virsystemd.h"
 
 #define VIR_FROM_THIS VIR_FROM_CH
 
@@ -134,7 +136,7 @@ virCHDomainObjEndJob(virDomainObj *obj)
 }
 
 static void *
-virCHDomainObjPrivateAlloc(void *opaque G_GNUC_UNUSED)
+virCHDomainObjPrivateAlloc(void *opaque)
 {
 virCHDomainObjPrivate *priv;
 
@@ -150,6 +152,7 @@ virCHDomainObjPrivateAlloc(void *opaque G_GNUC_UNUSED)
 g_free(priv);
 return NULL;
 }
+priv->driver = opaque;
 
 return priv;
 }
@@ -361,3 +364,25 @@ virCHDomainHasVcpuPids(virDomainObj *vm)
 
 return false;
 }
+
+char *
+virCHDomainGetMachineName(virDomainObj *vm)
+{
+virCHDomainObjPrivate *priv = CH_DOMAIN_PRIVATE(vm);
+virCHDriver *driver = priv->driver;
+char *ret = NULL;
+
+if (vm->pid > 0) {
+ret = virSystemdGetMachineNameByPID(vm->pid);
+if (!ret)
+virResetLastError();
+}
+
+if (!ret)
+ret = virDomainDriverGenerateMachineName("ch",
+ NULL,
+ vm->def->id, vm->def->name,
+ driver->privileged);
+
+return ret;
+}
diff --git a/src/ch/ch_domain.h b/src/ch/ch_domain.h
index c36405808b..4fc6251380 100644
--- a/src/ch/ch_domain.h
+++ b/src/ch/ch_domain.h
@@ -92,3 +92,5 @@ virCHDomainObjEndJob(virDomainObj *obj);
 int virCHDomainRefreshVcpuInfo(virDomainObj *vm);
 pid_t virCHDomainGetVcpuPid(virDomainObj *vm, unsigned int vcpuid);
 bool virCHDomainHasVcpuPids(virDomainObj *vm);
+
+char *virCHDomainGetMachineName(virDomainObj *vm);
diff --git a/src/ch/ch_driver.c b/src/ch/ch_driver.c
index ad7383e96e..97fbd76959 100644
--- a/src/ch/ch_driver.c
+++ b/src/ch/ch_driver.c
@@ -934,6 +934,7 @@ static int chStateInitialize(bool privileged,
 goto cleanup;
 }
 
+ch_driver->privileged = privileged;
 ret = VIR_DRV_STATE_INIT_COMPLETE;
 
  cleanup:
diff --git a/src/ch/ch_monitor.c b/src/ch/ch_monitor.c
index 12c10da874..d48b057814 100644
--- a/src/ch/ch_monitor.c
+++ b/src/ch/ch_monitor.c
@@ -226,7 +226,8 @@ virCHMonitorBuildDisksJson(virJSONValue *content, 
virDomainDef *vmdef)
 }
 
 static int
-virCHMonitorBuildNetJson(virJSONValue *nets, virDomainNetDef *netdef)
+virCHMonitorBuildNetJson(virJSONValue *nets, virDomainNetDef *netdef,
+ size_t *nnicindexes, int **nicindexes)
 {
 virDomainNetType netType = virDomainNetGetActualType(netdef);
 char macaddr[VIR_MAC_STRING_BUFLEN];
@@ -236,59 +237,72 @@ virCHMonitorBuildNetJson(virJSONValue *nets, 
virDomainNetDef *netdef)
 net = virJSONValueNewObject();
 
 switch (netType) {
-case VIR_DOMAIN_NET_TYPE_ETHERNET:
-if (netdef->guestIP.nips == 1) {
-const virNetDevIPAddr *ip = netdef->guestIP.ips[0];
-g_autofree char *addr = NULL;
-virSocketAddr netmask;
-g_autofree char *netmaskStr = NULL;
-if (!(addr = virSocketAddrFormat(>address)))
-return -1;
-if (virJSONValueObjectAppendString(net, "ip", addr) < 0)
-return -1;
+case VIR_DOMAIN_NET_TYPE_ETHERNET:
+if (netdef->guestIP.nips == 1) {
+const virNetDevIPAddr *ip = netdef->guestIP.ips[0];
+g_autofree char *addr = NULL;
+virSocketAddr netmask;
+g_autofree char *netmaskStr = NULL;
+
+if (!(addr = virSocketAddrFormat(>address)))
+return -1;
+if (virJSONValueObjectAppendString(net, "ip", addr) < 0)
+return -1;
+
+if (virSocketAddrPrefixToNetmask(ip->prefix, , 
AF_INET) < 0) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("Failed to translate net prefix %d to 
netmask"),
+   ip->prefix);
+return -1;
+  

[libvirt PATCH v3 01/13] util: Helper functions to get process info

2021-12-10 Thread Praveen K Paladugu
Move qemuGetProcessInfo and qemuGetSchedInfo methods to util and share them
with ch driver.

Signed-off-by: Praveen K Paladugu 
---
 src/libvirt_private.syms |   2 +
 src/qemu/qemu_driver.c   | 116 ++-
 src/util/virprocess.c| 108 
 src/util/virprocess.h|   5 ++
 4 files changed, 120 insertions(+), 111 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index da27ee7b53..56adc192cd 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -3101,8 +3101,10 @@ virProcessGetAffinity;
 virProcessGetMaxMemLock;
 virProcessGetNamespaces;
 virProcessGetPids;
+virProcessGetSchedInfo;
 virProcessGetStartTime;
 virProcessGetStat;
+virProcessGetStatInfo;
 virProcessGroupGet;
 virProcessGroupKill;
 virProcessKill;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index e444ad2d45..ba3efef42b 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1317,113 +1317,6 @@ qemuGetSchedstatDelay(unsigned long long *cpudelay,
 return 0;
 }
 
-
-static int
-qemuGetSchedInfo(unsigned long long *cpuWait,
- pid_t pid, pid_t tid)
-{
-g_autofree char *proc = NULL;
-g_autofree char *data = NULL;
-g_auto(GStrv) lines = NULL;
-size_t i;
-double val;
-
-*cpuWait = 0;
-
-/* In general, we cannot assume pid_t fits in int; but /proc parsing
- * is specific to Linux where int works fine.  */
-if (tid)
-proc = g_strdup_printf("/proc/%d/task/%d/sched", (int)pid, (int)tid);
-else
-proc = g_strdup_printf("/proc/%d/sched", (int)pid);
-if (!proc)
-return -1;
-
-/* The file is not guaranteed to exist (needs CONFIG_SCHED_DEBUG) */
-if (access(proc, R_OK) < 0) {
-return 0;
-}
-
-if (virFileReadAll(proc, (1<<16), ) < 0)
-return -1;
-
-lines = g_strsplit(data, "\n", 0);
-if (!lines)
-return -1;
-
-for (i = 0; lines[i] != NULL; i++) {
-const char *line = lines[i];
-
-/* Needs CONFIG_SCHEDSTATS. The second check
- * is the old name the kernel used in past */
-if (STRPREFIX(line, "se.statistics.wait_sum") ||
-STRPREFIX(line, "se.wait_sum")) {
-line = strchr(line, ':');
-if (!line) {
-virReportError(VIR_ERR_INTERNAL_ERROR,
-   _("Missing separator in sched info '%s'"),
-   lines[i]);
-return -1;
-}
-line++;
-while (*line == ' ')
-line++;
-
-if (virStrToDouble(line, NULL, ) < 0) {
-virReportError(VIR_ERR_INTERNAL_ERROR,
-   _("Unable to parse sched info value '%s'"),
-   line);
-return -1;
-}
-
-*cpuWait = (unsigned long long)(val * 100);
-break;
-}
-}
-
-return 0;
-}
-
-
-static int
-qemuGetProcessInfo(unsigned long long *cpuTime, int *lastCpu, long *vm_rss,
-   pid_t pid, pid_t tid)
-{
-g_auto(GStrv) proc_stat = virProcessGetStat(pid, tid);
-unsigned long long usertime = 0, systime = 0;
-long rss = 0;
-int cpu = 0;
-
-if (!proc_stat ||
-virStrToLong_ullp(proc_stat[VIR_PROCESS_STAT_UTIME], NULL, 10, 
) < 0 ||
-virStrToLong_ullp(proc_stat[VIR_PROCESS_STAT_STIME], NULL, 10, 
) < 0 ||
-virStrToLong_l(proc_stat[VIR_PROCESS_STAT_RSS], NULL, 10, ) < 0 ||
-virStrToLong_i(proc_stat[VIR_PROCESS_STAT_PROCESSOR], NULL, 10, ) 
< 0) {
-VIR_WARN("cannot parse process status data");
-}
-
-/* We got jiffies
- * We want nanoseconds
- * _SC_CLK_TCK is jiffies per second
- * So calculate thus
- */
-if (cpuTime)
-*cpuTime = 1000ull * 1000ull * 1000ull * (usertime + systime)
-/ (unsigned long long)sysconf(_SC_CLK_TCK);
-if (lastCpu)
-*lastCpu = cpu;
-
-if (vm_rss)
-*vm_rss = rss * virGetSystemPageSizeKB();
-
-
-VIR_DEBUG("Got status for %d/%d user=%llu sys=%llu cpu=%d rss=%ld",
-  (int)pid, tid, usertime, systime, cpu, rss);
-
-return 0;
-}
-
-
 static int
 qemuDomainHelperGetVcpus(virDomainObj *vm,
  virVcpuInfoPtr info,
@@ -1463,7 +1356,7 @@ qemuDomainHelperGetVcpus(virDomainObj *vm,
 vcpuinfo->number = i;
 vcpuinfo->state = VIR_VCPU_RUNNING;
 
-if (qemuGetProcessInfo(>cpuTime,
+if (virProcessGetStatInfo(>cpuTime,
>cpu, NULL,
vm->pid, vcpupid) < 0) {
 virReportSystemError(errno, "%s",
@@ -1483,7 +1376,7 @@ qemuDomainHelperGetVcpus(virDomainObj *vm,
 }
 
 if (cpuwait) {
-if (qemuGetSchedInfo(&(cpuwait[ncpuinfo]), vm->pid, vcpupid) < 0)
+if 

[libvirt PATCH v3 03/13] ch_domain: add methods to manage private vcpu data

2021-12-10 Thread Praveen K Paladugu
From: Vineeth Pillai 

Signed-off-by: Vineeth Pillai 
Signed-off-by: Praveen K Paladugu 
---
 src/ch/ch_domain.c | 50 +-
 src/ch/ch_domain.h | 11 ++
 2 files changed, 56 insertions(+), 5 deletions(-)

diff --git a/src/ch/ch_domain.c b/src/ch/ch_domain.c
index bf4ce83595..36333a8a3f 100644
--- a/src/ch/ch_domain.c
+++ b/src/ch/ch_domain.c
@@ -164,11 +164,6 @@ virCHDomainObjPrivateFree(void *data)
 g_free(priv);
 }
 
-virDomainXMLPrivateDataCallbacks virCHDriverPrivateDataCallbacks = {
-.alloc = virCHDomainObjPrivateAlloc,
-.free = virCHDomainObjPrivateFree,
-};
-
 static int
 virCHDomainDefPostParseBasic(virDomainDef *def,
  void *opaque G_GNUC_UNUSED)
@@ -185,6 +180,45 @@ virCHDomainDefPostParseBasic(virDomainDef *def,
 return 0;
 }
 
+static virClass *virCHDomainVcpuPrivateClass;
+static void virCHDomainVcpuPrivateDispose(void *obj);
+
+static int
+virCHDomainVcpuPrivateOnceInit(void)
+{
+if (!VIR_CLASS_NEW(virCHDomainVcpuPrivate, virClassForObject()))
+return -1;
+
+return 0;
+}
+
+VIR_ONCE_GLOBAL_INIT(virCHDomainVcpuPrivate);
+
+static virObject *
+virCHDomainVcpuPrivateNew(void)
+{
+virCHDomainVcpuPrivate *priv;
+
+if (virCHDomainVcpuPrivateInitialize() < 0)
+return NULL;
+
+if (!(priv = virObjectNew(virCHDomainVcpuPrivateClass)))
+return NULL;
+
+return (virObject *) priv;
+}
+
+
+static void
+virCHDomainVcpuPrivateDispose(void *obj)
+{
+virCHDomainVcpuPrivate *priv = obj;
+
+priv->tid = 0;
+
+return;
+}
+
 static int
 virCHDomainDefPostParse(virDomainDef *def,
 unsigned int parseFlags G_GNUC_UNUSED,
@@ -203,6 +237,12 @@ virCHDomainDefPostParse(virDomainDef *def,
 return 0;
 }
 
+virDomainXMLPrivateDataCallbacks virCHDriverPrivateDataCallbacks = {
+.alloc = virCHDomainObjPrivateAlloc,
+.free = virCHDomainObjPrivateFree,
+.vcpuNew = virCHDomainVcpuPrivateNew,
+};
+
 static int
 chValidateDomainDeviceDef(const virDomainDeviceDef *dev,
   const virDomainDef *def G_GNUC_UNUSED,
diff --git a/src/ch/ch_domain.h b/src/ch/ch_domain.h
index c053b25c65..f01c0e5ad0 100644
--- a/src/ch/ch_domain.h
+++ b/src/ch/ch_domain.h
@@ -62,6 +62,17 @@ struct _virCHDomainObjPrivate {
 
 virCHMonitor *virCHDomainGetMonitor(virDomainObj *vm);
 
+typedef struct _virCHDomainVcpuPrivate virCHDomainVcpuPrivate;
+struct _virCHDomainVcpuPrivate {
+virObject parent;
+
+pid_t tid; /* vcpu thread id */
+virTristateBool halted;
+};
+
+#define CH_DOMAIN_VCPU_PRIVATE(vcpu) \
+((virCHDomainVcpuPrivate *) (vcpu)->privateData)
+
 extern virDomainXMLPrivateDataCallbacks virCHDriverPrivateDataCallbacks;
 extern virDomainDefParserConfig virCHDriverDomainDefParserConfig;
 
-- 
2.27.0




[libvirt PATCH v3 13/13] ch_driver: emulator threadinfo & pinning callbacks

2021-12-10 Thread Praveen K Paladugu
Signed-off-by: Praveen K Paladugu 
---
 src/ch/ch_driver.c | 154 +
 1 file changed, 154 insertions(+)

diff --git a/src/ch/ch_driver.c b/src/ch/ch_driver.c
index d7008ef011..1f40f6561a 100644
--- a/src/ch/ch_driver.c
+++ b/src/ch/ch_driver.c
@@ -1297,6 +1297,158 @@ chDomainPinVcpu(virDomainPtr dom,
   VIR_DOMAIN_AFFECT_LIVE);
 }
 
+
+
+static int
+chDomainGetEmulatorPinInfo(virDomainPtr dom,
+ unsigned char *cpumaps,
+ int maplen,
+ unsigned int flags)
+{
+virDomainObj *vm = NULL;
+virDomainDef *def;
+virCHDomainObjPrivate *priv;
+bool live;
+int ret = -1;
+virBitmap *cpumask = NULL;
+g_autoptr(virBitmap) bitmap = NULL;
+virBitmap *autoCpuset = NULL;
+
+virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
+  VIR_DOMAIN_AFFECT_CONFIG, -1);
+
+if (!(vm = chDomObjFromDomain(dom)))
+goto cleanup;
+
+if (virDomainGetEmulatorPinInfoEnsureACL(dom->conn, vm->def) < 0)
+goto cleanup;
+
+if (!(def = virDomainObjGetOneDefState(vm, flags, )))
+goto cleanup;
+
+if (live) {
+priv = vm->privateData;
+autoCpuset = priv->autoCpuset;
+}
+if (def->cputune.emulatorpin) {
+cpumask = def->cputune.emulatorpin;
+} else if (def->cpumask) {
+cpumask = def->cpumask;
+} else if (vm->def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO &&
+   autoCpuset) {
+cpumask = autoCpuset;
+} else {
+if (!(bitmap = virHostCPUGetAvailableCPUsBitmap()))
+goto cleanup;
+cpumask = bitmap;
+}
+
+virBitmapToDataBuf(cpumask, cpumaps, maplen);
+
+ret = 1;
+
+ cleanup:
+virDomainObjEndAPI();
+return ret;
+}
+
+static int
+chDomainPinEmulator(virDomainPtr dom,
+  unsigned char *cpumap,
+  int maplen,
+  unsigned int flags)
+{
+virCHDriver *driver = dom->conn->privateData;
+virDomainObj *vm;
+virCgroup *cgroup_emulator = NULL;
+virDomainDef *def;
+virDomainDef *persistentDef;
+int ret = -1;
+virCHDomainObjPrivate *priv;
+virBitmap *pcpumap = NULL;
+g_autoptr(virCHDriverConfig) cfg = NULL;
+g_autofree char *str = NULL;
+virTypedParameterPtr eventParams = NULL;
+int eventNparams = 0;
+int eventMaxparams = 0;
+
+virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
+  VIR_DOMAIN_AFFECT_CONFIG, -1);
+
+cfg = virCHDriverGetConfig(driver);
+
+if (!(vm = chDomObjFromDomain(dom)))
+goto cleanup;
+
+if (virDomainPinEmulatorEnsureACL(dom->conn, vm->def, flags) < 0)
+goto cleanup;
+
+if (virCHDomainObjBeginJob(vm, CH_JOB_MODIFY) < 0)
+goto cleanup;
+
+if (virDomainObjGetDefs(vm, flags, , ) < 0)
+goto endjob;
+
+priv = vm->privateData;
+
+if (!(pcpumap = virBitmapNewData(cpumap, maplen)))
+goto endjob;
+
+if (virBitmapIsAllClear(pcpumap)) {
+virReportError(VIR_ERR_INVALID_ARG, "%s",
+   _("Empty cpu list for pinning"));
+goto endjob;
+}
+
+if (def) {
+if (virCgroupHasController(priv->cgroup, 
VIR_CGROUP_CONTROLLER_CPUSET)) {
+if (virCgroupNewThread(priv->cgroup, VIR_CGROUP_THREAD_EMULATOR,
+   0, false, _emulator) < 0)
+goto endjob;
+
+if (virSetupCgroupCpusetCpus(cgroup_emulator, pcpumap) < 0) {
+virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+   _("failed to set cpuset.cpus in cgroup"
+ " for emulator threads"));
+goto endjob;
+}
+}
+
+if (virProcessSetAffinity(vm->pid, pcpumap, false) < 0)
+goto endjob;
+
+virBitmapFree(def->cputune.emulatorpin);
+def->cputune.emulatorpin = NULL;
+
+if (!(def->cputune.emulatorpin = virBitmapNewCopy(pcpumap)))
+goto endjob;
+
+if (virDomainObjSave(vm, driver->xmlopt, cfg->stateDir) < 0)
+goto endjob;
+
+str = virBitmapFormat(pcpumap);
+if (virTypedParamsAddString(, ,
+,
+VIR_DOMAIN_TUNABLE_CPU_EMULATORPIN,
+str) < 0)
+goto endjob;
+
+}
+
+
+ret = 0;
+
+endjob:
+virCHDomainObjEndJob(vm);
+
+cleanup:
+if (cgroup_emulator)
+virCgroupFree(cgroup_emulator);
+virBitmapFree(pcpumap);
+virDomainObjEndAPI();
+return ret;
+}
+
 #define CH_NB_NUMA_PARAM 2
 
 static int
@@ -1610,6 +1762,8 @@ static virHypervisorDriver chHypervisorDriver = {
 .domainGetVcpuPinInfo = chDomainGetVcpuPinInfo, /* 8.0.0 */
 .domainPinVcpu = chDomainPinVcpu,   /* 8.0.0 */
 

[libvirt PATCH v3 05/13] ch_driver: domainGetVcpuPinInfo and nodeGetCPUMap

2021-12-10 Thread Praveen K Paladugu
From: Vineeth Pillai 

Add domainGetVcpuPinInfo and nodeGetCPUMap callbacks to ch driver

Signed-off-by: Vineeth Pillai 
Signed-off-by: Praveen K Paladugu 
---
 src/ch/ch_domain.h | 10 +++--
 src/ch/ch_driver.c | 51 ++
 2 files changed, 59 insertions(+), 2 deletions(-)

diff --git a/src/ch/ch_domain.h b/src/ch/ch_domain.h
index 1ec7643216..c36405808b 100644
--- a/src/ch/ch_domain.h
+++ b/src/ch/ch_domain.h
@@ -23,6 +23,7 @@
 #include "ch_conf.h"
 #include "ch_monitor.h"
 #include "virchrdev.h"
+#include "vircgroup.h"
 
 /* Give up waiting for mutex after 30 seconds */
 #define CH_JOB_WAIT_TIME (1000ull * 30)
@@ -52,9 +53,14 @@ typedef struct _virCHDomainObjPrivate virCHDomainObjPrivate;
 struct _virCHDomainObjPrivate {
 struct virCHDomainJobObj job;
 
+virChrdevs *chrdevs;
+virCgroup *cgroup;
+virCHDriver *driver;
 virCHMonitor *monitor;
-
- virChrdevs *chrdevs;
+char *machineName;
+virBitmap *autoNodeset;
+virBitmap *autoCpuset;
+virChrdevs *devs;
 };
 
 #define CH_DOMAIN_PRIVATE(vm) \
diff --git a/src/ch/ch_driver.c b/src/ch/ch_driver.c
index 31e9de7f6a..ad7383e96e 100644
--- a/src/ch/ch_driver.c
+++ b/src/ch/ch_driver.c
@@ -981,6 +981,55 @@ chDomainGetMaxVcpus(virDomainPtr dom)
   VIR_DOMAIN_VCPU_MAXIMUM));
 }
 
+static int
+chDomainGetVcpuPinInfo(virDomain *dom,
+   int ncpumaps,
+   unsigned char *cpumaps, int maplen, unsigned int flags)
+{
+virDomainObj *vm = NULL;
+virDomainDef *def;
+bool live;
+int ret = -1;
+
+g_autoptr(virBitmap) hostcpus = NULL;
+virBitmap *autoCpuset = NULL;
+
+virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG, -1);
+
+if (!(vm = chDomObjFromDomain(dom)))
+goto cleanup;
+
+if (virDomainGetVcpuPinInfoEnsureACL(dom->conn, vm->def) < 0)
+goto cleanup;
+
+if (!(def = virDomainObjGetOneDefState(vm, flags, )))
+goto cleanup;
+
+if (!(hostcpus = virHostCPUGetAvailableCPUsBitmap()))
+goto cleanup;
+
+if (live)
+autoCpuset = CH_DOMAIN_PRIVATE(vm)->autoCpuset;
+
+ret = virDomainDefGetVcpuPinInfoHelper(def, maplen, ncpumaps, cpumaps,
+   hostcpus, autoCpuset);
+ cleanup:
+virDomainObjEndAPI();
+return ret;
+}
+
+static int
+chNodeGetCPUMap(virConnectPtr conn,
+unsigned char **cpumap,
+unsigned int *online, unsigned int flags)
+{
+if (virNodeGetCPUMapEnsureACL(conn) < 0)
+return -1;
+
+return virHostCPUGetMap(cpumap, online, flags);
+}
+
+
 static int
 chDomainHelperGetVcpus(virDomainObj *vm,
virVcpuInfoPtr info,
@@ -1112,6 +1161,8 @@ static virHypervisorDriver chHypervisorDriver = {
 .domainGetVcpus = chDomainGetVcpus, /* 8.0.0 */
 .domainGetVcpusFlags = chDomainGetVcpusFlags,   /* 8.0.0 */
 .domainGetMaxVcpus = chDomainGetMaxVcpus,   /* 8.0.0 */
+.domainGetVcpuPinInfo = chDomainGetVcpuPinInfo, /* 8.0.0 */
+.nodeGetCPUMap = chNodeGetCPUMap,   /* 8.0.0 */
 };
 
 static virConnectDriver chConnectDriver = {
-- 
2.27.0




Re: [libvirt PATCH 3/6] virt-ssh-helper: Add manual page

2021-12-10 Thread Andrea Bolognani
On Fri, Dec 10, 2021 at 06:23:22PM +0100, Ján Tomko wrote:
> On a Friday in 2021, Andrea Bolognani wrote:
> > docs/manpages/meson.build |  1 +
> > docs/manpages/virt-ssh-helper.rst | 96 +++
> > libvirt.spec.in   |  1 +
> > 3 files changed, 98 insertions(+)
> > create mode 100644 docs/manpages/virt-ssh-helper.rst

Sorry, I mistakenly thought you had R-b'd the entire series so I have
already pushed it! :(

> I'm not convinced we need a manual page for an internal tool.
>
> We don't have one for any other -helper binaries and qemu-bridge-helper
> also comes without a man page.

The difference between the other helpers and virt-ssh-helper is that
the latter is installed in the default $PATH.

So a random user is likely to see the name when using shell
completion after typing "virt-" and wonder what the tool is all
about. I think that justifies having a brief manual page for it.

-- 
Andrea Bolognani / Red Hat / Virtualization




Re: [libvirt PATCH 5/6] virt-qemu-run: Improve manual page

2021-12-10 Thread Andrea Bolognani
On Fri, Dec 10, 2021 at 06:16:06PM +0100, Ján Tomko wrote:
> On a Friday in 2021, Andrea Bolognani wrote:
> > -``virt-qemu-run [OPTIONS...] [GUEST-XML]``
> > +``virt-qemu-run`` [*OPTIONS...*] *GUEST-XML-FILE*
> > +``virt-qemu-run`` *OPTION*
>
> This puts them both on the same line in the resulting man page.

So it does! Great catch, I don't know how I failed to notice.

> Prefixing both lines with '|' fixed that for me:
>
> -``virt-qemu-run`` [*OPTIONS...*] *GUEST-XML-FILE*
> -``virt-qemu-run`` *OPTION*
> +| ``virt-qemu-run`` [*OPTIONS...*] *GUEST-XML-FILE*
> +| ``virt-qemu-run`` *OPTION*

I ended up adopting a slightly different approach: since the only
situations in which you would not pass some mandatory ARGUMENT to the
commands is for '--version' and '--help', which are extremely
widespread and well understood, I've just changed the usage to

  ``command`` [*OPTION*]... *ARGUMENT*

in all manual pages. I think this is a good solution, but if you'd
rather see the version with two separate lines just let me know and I
will prepare a follow-up patch.

Thank you for the review! :)

-- 
Andrea Bolognani / Red Hat / Virtualization




Re: [libvirt PATCH 3/6] virt-ssh-helper: Add manual page

2021-12-10 Thread Ján Tomko

On a Friday in 2021, Andrea Bolognani wrote:

Signed-off-by: Andrea Bolognani 
---
docs/manpages/meson.build |  1 +
docs/manpages/virt-ssh-helper.rst | 96 +++
libvirt.spec.in   |  1 +
3 files changed, 98 insertions(+)
create mode 100644 docs/manpages/virt-ssh-helper.rst



I'm not convinced we need a manual page for an internal tool.

We don't have one for any other -helper binaries and qemu-bridge-helper
also comes without a man page.

Jano


signature.asc
Description: PGP signature


Re: [libvirt PATCH 6/6] virt-pki-query-dn: Add manual page

2021-12-10 Thread Ján Tomko

On a Friday in 2021, Andrea Bolognani wrote:

Signed-off-by: Andrea Bolognani 
---
docs/manpages/meson.build   |  1 +
docs/manpages/virt-pki-query-dn.rst | 91 +
libvirt.spec.in |  1 +
3 files changed, 93 insertions(+)
create mode 100644 docs/manpages/virt-pki-query-dn.rst

diff --git a/docs/manpages/meson.build b/docs/manpages/meson.build
index e80fff48c8..bf6fc730e0 100644
--- a/docs/manpages/meson.build
+++ b/docs/manpages/meson.build
@@ -16,6 +16,7 @@ docs_man_files = [
  { 'name': 'virt-admin', 'section': '1', 'install': true },
  { 'name': 'virt-host-validate', 'section': '1', 'install': 
conf.has('WITH_HOST_VALIDATE') },
  { 'name': 'virt-login-shell', 'section': '1', 'install': 
conf.has('WITH_LOGIN_SHELL') },
+  { 'name': 'virt-pki-query-dn', 'section': '1', 'install': true },
  { 'name': 'virt-pki-validate', 'section': '1', 'install': true },
  { 'name': 'virt-qemu-run', 'section': '1', 'install': conf.has('WITH_QEMU') },
  { 'name': 'virt-ssh-helper', 'section': '1', 'install': true },
diff --git a/docs/manpages/virt-pki-query-dn.rst 
b/docs/manpages/virt-pki-query-dn.rst
new file mode 100644
index 00..0e162d6dc5
--- /dev/null
+++ b/docs/manpages/virt-pki-query-dn.rst
@@ -0,0 +1,91 @@
+=
+virt-pki-query-dn
+=
+
+-
+extract Distinguished Name from a PEM certificate
+-
+
+:Manual section: 1
+:Manual group: Virtualization Support
+
+.. contents::
+
+
+SYNOPSIS
+
+
+``virt-pki-query-dn`` *FILE*
+``virt-pki-query-dn`` *OPTION*
+
+


Same issue as with virt-qemu-run man page.

Reviewed-by: Ján Tomko 

Jano


signature.asc
Description: PGP signature


Re: [libvirt PATCH 5/6] virt-qemu-run: Improve manual page

2021-12-10 Thread Ján Tomko

On a Friday in 2021, Andrea Bolognani wrote:

Specifically:

 * use the correct notation and markup for commands, options
   and arguments;
 * rename arguments meta-variables;
 * document '--help' and '--version' options;
 * use consistent vertical spacing;
 * fix a typo.

Signed-off-by: Andrea Bolognani 
---
docs/manpages/virt-qemu-run.rst | 53 +++--
1 file changed, 31 insertions(+), 22 deletions(-)

diff --git a/docs/manpages/virt-qemu-run.rst b/docs/manpages/virt-qemu-run.rst
index 470de93168..a755b7fda9 100644
--- a/docs/manpages/virt-qemu-run.rst
+++ b/docs/manpages/virt-qemu-run.rst
@@ -11,10 +11,13 @@ Run a standalone QEMU guest

.. contents::

+
SYNOPSIS


-``virt-qemu-run [OPTIONS...] [GUEST-XML]``
+``virt-qemu-run`` [*OPTIONS...*] *GUEST-XML-FILE*
+``virt-qemu-run`` *OPTION*
+


This puts them both on the same line in the resulting man page.

Prefixing both lines with '|' fixed that for me:
diff --git a/docs/manpages/virt-qemu-run.rst b/docs/manpages/virt-qemu-run.rst
index a755b7fda9..1bc1a7f6f7 100644
--- a/docs/manpages/virt-qemu-run.rst
+++ b/docs/manpages/virt-qemu-run.rst
@@ -15,8 +15,8 @@ Run a standalone QEMU guest
 SYNOPSIS
 

-``virt-qemu-run`` [*OPTIONS...*] *GUEST-XML-FILE*
-``virt-qemu-run`` *OPTION*
+| ``virt-qemu-run`` [*OPTIONS...*] *GUEST-XML-FILE*
+| ``virt-qemu-run`` *OPTION*


 DESCRIPTION



Reviewed-by: Ján Tomko 

Jano


signature.asc
Description: PGP signature


Re: [libvirt PATCH 4/6] virt-qemu-run: Improve usage information

2021-12-10 Thread Ján Tomko

On a Friday in 2021, Andrea Bolognani wrote:

Specifically, include non-option argument 'GUEST-XML-FILE'
in usage summary.

Signed-off-by: Andrea Bolognani 
---
src/qemu/qemu_shim.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)



Reviewed-by: Ján Tomko 

Jano


signature.asc
Description: PGP signature


Re: [libvirt PATCH 2/6] virt-ssh-helper: Improve usage information

2021-12-10 Thread Ján Tomko

On a Friday in 2021, Andrea Bolognani wrote:

Specifically:

 * include non-option argument 'URI' in usage summary;
 * mention that it's an internal tool not meant to be
   called directly;
 * exit earlier if required arguments are absent.

Signed-off-by: Andrea Bolognani 
---
src/remote/remote_ssh_helper.c | 16 ++--
1 file changed, 10 insertions(+), 6 deletions(-)



Reviewed-by: Ján Tomko 

Jano


signature.asc
Description: PGP signature


Re: [libvirt PATCH 1/6] virt-ssh-helper: Don't use optind

2021-12-10 Thread Ján Tomko

On a Friday in 2021, Andrea Bolognani wrote:

It's a getopt interface and we're not using getopt, at least
directly, so even though it works relying on it feels wrong.

GOption takes care of removing any trace of the arguments it
consumes from argc and argv, leaving behind only non-option
arguments, so we can just use those standard variables.

Signed-off-by: Andrea Bolognani 
---
src/remote/remote_ssh_helper.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)



Reviewed-by: Ján Tomko 

Jano


signature.asc
Description: PGP signature


[libvirt PATCH v3 12/13] qemu: probe for sev-guest.kernel-hashes property

2021-12-10 Thread Daniel P . Berrangé
This sev-guest object property indicates whether QEMU should
expose the kernel, ramdisk, cmdline hashes to the firmware
for measurement.

The 6.2.0 capabilities are hacked to look as if they were
generated with sev-guest support.

Reviewed-by: Peter Krempa 
Signed-off-by: Daniel P. Berrangé 
---
 src/qemu/qemu_capabilities.c  |   8 ++
 src/qemu/qemu_capabilities.h  |   1 +
 .../domaincapsdata/qemu_6.2.0-q35.x86_64.xml  |   7 +-
 .../domaincapsdata/qemu_6.2.0-tcg.x86_64.xml  |   7 +-
 tests/domaincapsdata/qemu_6.2.0.x86_64.xml|   7 +-
 .../caps_2.12.0.x86_64.replies|  97 
 .../caps_3.0.0.x86_64.replies |  97 
 .../caps_3.1.0.x86_64.replies |  97 
 .../caps_4.0.0.x86_64.replies |  97 
 .../caps_4.1.0.x86_64.replies |  89 ++
 .../caps_4.2.0.x86_64.replies |  89 ++
 .../caps_5.0.0.x86_64.replies |  89 ++
 .../caps_5.1.0.x86_64.replies |  89 ++
 .../caps_5.2.0.x86_64.replies |  89 ++
 .../caps_6.0.0.x86_64.replies |  89 ++
 .../caps_6.1.0.x86_64.replies |  89 ++
 .../caps_6.2.0.x86_64.replies | 109 ++
 .../caps_6.2.0.x86_64.xml |   8 ++
 18 files changed, 895 insertions(+), 263 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index ddd61ecfc9..9553e6e5b8 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -652,6 +652,7 @@ VIR_ENUM_IMPL(virQEMUCaps,
   "device.json", /* QEMU_CAPS_DEVICE_JSON */
   "query-dirty-rate", /* QEMU_CAPS_QUERY_DIRTY_RATE */
   "rbd-encryption", /* QEMU_CAPS_RBD_ENCRYPTION */
+  "sev-guest-kernel-hashes", /* QEMU_CAPS_SEV_GUEST_KERNEL_HASHES 
*/
 );
 
 
@@ -1718,6 +1719,10 @@ static struct virQEMUCapsStringFlags 
virQEMUCapsObjectPropsMaxCPU[] = {
 { "migratable", QEMU_CAPS_CPU_MIGRATABLE },
 };
 
+static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsSEVGuest[] = {
+{ "kernel-hashes", QEMU_CAPS_SEV_GUEST_KERNEL_HASHES },
+};
+
 static virQEMUCapsObjectTypeProps virQEMUCapsObjectProps[] = {
 { "memory-backend-file", virQEMUCapsObjectPropsMemoryBackendFile,
   G_N_ELEMENTS(virQEMUCapsObjectPropsMemoryBackendFile),
@@ -1731,6 +1736,9 @@ static virQEMUCapsObjectTypeProps 
virQEMUCapsObjectProps[] = {
 { "max-arm-cpu", virQEMUCapsObjectPropsMaxCPU,
   G_N_ELEMENTS(virQEMUCapsObjectPropsMaxCPU),
   QEMU_CAPS_ARM_MAX_CPU },
+{ "sev-guest", virQEMUCapsObjectPropsSEVGuest,
+  G_N_ELEMENTS(virQEMUCapsObjectPropsSEVGuest),
+  QEMU_CAPS_SEV_GUEST },
 };
 
 static struct virQEMUCapsStringFlags virQEMUCapsMachinePropsPSeries[] = {
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 716e09123c..aaac20a834 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -631,6 +631,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for 
syntax-check */
 QEMU_CAPS_DEVICE_JSON, /* -device accepts JSON */
 QEMU_CAPS_QUERY_DIRTY_RATE, /* accepts query-dirty-rate */
 QEMU_CAPS_RBD_ENCRYPTION, /* Ceph RBD encryption support */
+QEMU_CAPS_SEV_GUEST_KERNEL_HASHES, /* sev-guest.kernel-hashes= */
 
 QEMU_CAPS_LAST /* this must always be the last item */
 } virQEMUCapsFlags;
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 9d68c0a404..b5f700c119 100644
--- a/tests/domaincapsdata/qemu_6.2.0-q35.x86_64.xml
+++ b/tests/domaincapsdata/qemu_6.2.0-q35.x86_64.xml
@@ -225,6 +225,11 @@
 
 
 
-
+
+  47
+  1
+  59
+  450
+
   
 
diff --git a/tests/domaincapsdata/qemu_6.2.0-tcg.x86_64.xml 
b/tests/domaincapsdata/qemu_6.2.0-tcg.x86_64.xml
index 8db840faac..c2c22d5775 100644
--- a/tests/domaincapsdata/qemu_6.2.0-tcg.x86_64.xml
+++ b/tests/domaincapsdata/qemu_6.2.0-tcg.x86_64.xml
@@ -231,6 +231,11 @@
 
 
 
-
+
+  47
+  1
+  59
+  450
+
   
 
diff --git a/tests/domaincapsdata/qemu_6.2.0.x86_64.xml 
b/tests/domaincapsdata/qemu_6.2.0.x86_64.xml
index 0f89790b60..17207394dd 100644
--- a/tests/domaincapsdata/qemu_6.2.0.x86_64.xml
+++ b/tests/domaincapsdata/qemu_6.2.0.x86_64.xml
@@ -225,6 +225,11 @@
 
 
 
-
+
+  47
+  1
+  59
+  450
+
   
 
diff --git a/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.replies 
b/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.replies
index 5fefbc64ab..c5bdd5398b 100644
--- a/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.replies
+++ b/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.replies
@@ -17361,10 +17361,59 @@
 }
 
 {
-  "execute": "query-machines",
+  "execute": "qom-list-properties",
+  

[libvirt PATCH v3 13/13] qemu: format sev-guest.kernel-hashes property

2021-12-10 Thread Daniel P . Berrangé
Set the kernel-hashes property on the sev-guest object if
the config asked for it explicitly. While QEMU machine
types currently default to having this setting off, it
is not guaranteed to remain this way.

Signed-off-by: Daniel P. Berrangé 
---
 src/qemu/qemu_command.c   |  1 +
 src/qemu/qemu_validate.c  |  7 
 ...unch-security-sev-direct.x86_64-6.2.0.args | 40 +++
 .../launch-security-sev-direct.xml| 39 ++
 tests/qemuxml2argvtest.c  |  1 +
 5 files changed, 88 insertions(+)
 create mode 100644 
tests/qemuxml2argvdata/launch-security-sev-direct.x86_64-6.2.0.args
 create mode 100644 tests/qemuxml2argvdata/launch-security-sev-direct.xml

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 613f7a5d2a..dfbf4973f5 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -9894,6 +9894,7 @@ qemuBuildSEVCommandLine(virDomainObj *vm, virCommand *cmd,
  "u:policy", sev->policy,
  "S:dh-cert-file", dhpath,
  "S:session-file", sessionpath,
+ "T:kernel-hashes", sev->kernel_hashes,
  NULL) < 0)
 return -1;
 
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index 29b01495ad..c0dc1f7b53 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -1200,6 +1200,13 @@ qemuValidateDomainDef(const virDomainDef *def,
  "this QEMU binary"));
 return -1;
 }
+
+if (def->sec->data.sev.kernel_hashes == VIR_TRISTATE_BOOL_YES &&
+!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SEV_GUEST_KERNEL_HASHES)) {
+virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+   _("SEV measured direct kernel boot is not 
supported with this QEMU binary"));
+return -1;
+}
 break;
 case VIR_DOMAIN_LAUNCH_SECURITY_PV:
 if (!virQEMUCapsGet(qemuCaps, 
QEMU_CAPS_MACHINE_CONFIDENTAL_GUEST_SUPPORT) ||
diff --git 
a/tests/qemuxml2argvdata/launch-security-sev-direct.x86_64-6.2.0.args 
b/tests/qemuxml2argvdata/launch-security-sev-direct.x86_64-6.2.0.args
new file mode 100644
index 00..0062faa06c
--- /dev/null
+++ b/tests/qemuxml2argvdata/launch-security-sev-direct.x86_64-6.2.0.args
@@ -0,0 +1,40 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/tmp/lib/domain--1-QEMUGuest1 \
+USER=test \
+LOGNAME=test \
+XDG_DATA_HOME=/tmp/lib/domain--1-QEMUGuest1/.local/share \
+XDG_CACHE_HOME=/tmp/lib/domain--1-QEMUGuest1/.cache \
+XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest1/.config \
+/usr/bin/qemu-system-x86_64 \
+-name guest=QEMUGuest1,debug-threads=on \
+-S \
+-object 
'{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/tmp/lib/domain--1-QEMUGuest1/master-key.aes"}'
 \
+-machine 
pc-i440fx-6.2,usb=off,dump-guest-core=off,confidential-guest-support=lsec0,memory-backend=pc.ram
 \
+-accel kvm \
+-cpu qemu64 \
+-m 214 \
+-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 \
+-display none \
+-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-shutdown \
+-no-acpi \
+-boot strict=on \
+-kernel /vmlinuz \
+-initrd /initrd \
+-append runme \
+-device 
'{"driver":"piix3-usb-uhci","id":"usb","bus":"pci.0","addr":"0x1.0x2"}' \
+-blockdev 
'{"driver":"host_device","filename":"/dev/HostVG/QEMUGuest1","node-name":"libvirt-1-storage","auto-read-only":true,"discard":"unmap"}'
 \
+-blockdev 
'{"node-name":"libvirt-1-format","read-only":false,"driver":"raw","file":"libvirt-1-storage"}'
 \
+-device 
'{"driver":"ide-hd","bus":"ide.0","unit":0,"drive":"libvirt-1-format","id":"ide0-0-0","bootindex":1}'
 \
+-audiodev '{"id":"audio1","driver":"none"}' \
+-object 
'{"qom-type":"sev-guest","id":"lsec0","cbitpos":47,"reduced-phys-bits":1,"policy":1,"dh-cert-file":"/tmp/lib/domain--1-QEMUGuest1/dh_cert.base64","session-file":"/tmp/lib/domain--1-QEMUGuest1/session.base64","kernel-hashes":true}'
 \
+-sandbox 
on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
+-msg timestamp=on
diff --git a/tests/qemuxml2argvdata/launch-security-sev-direct.xml 
b/tests/qemuxml2argvdata/launch-security-sev-direct.xml
new file mode 100644
index 00..80ce6412dd
--- /dev/null
+++ b/tests/qemuxml2argvdata/launch-security-sev-direct.xml
@@ -0,0 +1,39 @@
+
+  QEMUGuest1
+  c7a5fdbd-edaf-9455-926a-d65c16db1809
+  219100
+  219100
+  1
+  
+hvm
+/vmlinuz
+/initrd
+runme
+  
+  
+  destroy
+  restart
+  destroy
+  
+/usr/bin/qemu-system-x86_64
+
+  
+  
+  
+  
+
+
+
+

[libvirt PATCH v3 11/13] conf: add support for setting SEV kernel hashes

2021-12-10 Thread Daniel P . Berrangé
Normally the SEV measurement only covers the firmware
loader contents. When doing a direct kernel boot, however,
with new enough OVMF it is possible to ask for the
measurement to cover the kernel, ramdisk and command line.

It can't be done automatically as that would break existing
guests using direct kernel boot with old firmware, so there
is a new XML setting allowing this behaviour to be toggled.

Reviewed-by: Peter Krempa 
Signed-off-by: Daniel P. Berrangé 
---
 docs/formatdomain.rst | 7 ++-
 docs/schemas/domaincommon.rng | 5 +
 src/conf/domain_conf.c| 8 
 src/conf/domain_conf.h| 1 +
 4 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index eb8c973cf1..c6e1f2226a 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -8191,7 +8191,7 @@ spec 
`__
 

  ...
- 
+ 
0x0001
47
1
@@ -8201,6 +8201,11 @@ spec 
`__
  ...

 
+``kernelHashes``
+   The optional ``kernelHashes`` attribute indicates whether the
+   hashes of the kernel, ramdisk and command line should be included
+   in the measurement done by the firmware. This is only valid if
+   using direct kernel boot. :since:`Since 8.0.0`
 ``cbitpos``
The required ``cbitpos`` element provides the C-bit (aka encryption bit)
location in guest page table entry. The value of ``cbitpos`` is hypervisor
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index f01b7a6470..8fe6134935 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -499,6 +499,11 @@
 
   sev
 
+
+  
+
+  
+
 
   
 
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index c634e7dd41..15e52eeed8 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -14793,6 +14793,10 @@ virDomainSEVDefParseXML(virDomainSEVDef *def,
 unsigned long policy;
 int rc;
 
+if (virXMLPropTristateBool(ctxt->node, "kernelHashes", VIR_XML_PROP_NONE,
+   >kernel_hashes) < 0)
+return -1;
+
 if (virXPathULongHex("string(./policy)", ctxt, ) < 0) {
 virReportError(VIR_ERR_XML_ERROR, "%s",
_("failed to get launch security policy"));
@@ -27052,6 +27056,10 @@ virDomainSecDefFormat(virBuffer *buf, virDomainSecDef 
*sec)
 case VIR_DOMAIN_LAUNCH_SECURITY_SEV: {
 virDomainSEVDef *sev = >data.sev;
 
+if (sev->kernel_hashes != VIR_TRISTATE_BOOL_ABSENT)
+virBufferAsprintf(, " kernelHashes='%s'",
+  virTristateBoolTypeToString(sev->kernel_hashes));
+
 if (sev->haveCbitpos)
 virBufferAsprintf(, "%d\n", 
sev->cbitpos);
 
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index c0c07ea6ba..8e576c00f8 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2692,6 +2692,7 @@ struct _virDomainSEVDef {
 unsigned int cbitpos;
 bool haveReducedPhysBits;
 unsigned int reduced_phys_bits;
+virTristateBool kernel_hashes;
 };
 
 struct _virDomainSecDef {
-- 
2.33.1



[libvirt PATCH v3 10/13] qemu: report max number of SEV guests

2021-12-10 Thread Daniel P . Berrangé
Different CPU generations have different limits on the number
of SEV/SEV-ES guests that can be run. Since both limits come
from the same overall set, there is typically also BIOS config
to set the tradeoff betweeen SEV and SEV-ES guest limits.

This is important information to expose for a mgmt application
scheduling guests to hosts.

Signed-off-by: Daniel P. Berrangé 
---
 src/qemu/qemu_capabilities.c  | 39 +++
 src/qemu/qemu_driver.c| 10 +
 .../domaincapsdata/qemu_2.12.0-q35.x86_64.xml |  4 +-
 .../domaincapsdata/qemu_2.12.0-tcg.x86_64.xml |  4 +-
 tests/domaincapsdata/qemu_2.12.0.x86_64.xml   |  4 +-
 .../domaincapsdata/qemu_6.0.0-q35.x86_64.xml  |  4 +-
 .../domaincapsdata/qemu_6.0.0-tcg.x86_64.xml  |  4 +-
 tests/domaincapsdata/qemu_6.0.0.x86_64.xml|  4 +-
 tests/testutilsqemu.c | 21 ++
 9 files changed, 82 insertions(+), 12 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 4ffd0a98a2..ddd61ecfc9 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -1897,6 +1897,8 @@ virQEMUCapsSEVInfoCopy(virSEVCapability **dst,
 
 tmp->cbitpos = src->cbitpos;
 tmp->reduced_phys_bits = src->reduced_phys_bits;
+tmp->max_guests = src->max_guests;
+tmp->max_es_guests = src->max_es_guests;
 
 *dst = g_steal_pointer();
 return 0;
@@ -3286,6 +3288,31 @@ virQEMUCapsProbeQMPGICCapabilities(virQEMUCaps *qemuCaps,
 }
 
 
+static void
+virQEMUCapsGetSEVMaxGuests(virSEVCapability *caps)
+{
+/*
+ * From Secure Encrypted Virtualization API v0.24, section 6.19.1
+ *
+ * If the guest is SEV-ES enabled, then the ASID must be at least
+ * 1h and at most (MIN_SEV_ASID-1). If the guest is not SEV-ES
+ * enabled, then the ASID must be at least MIN_SEV_ASID and at
+ * most the maximum SEV ASID available. The MIN_SEV_ASID value
+ * is discovered by CPUID Fn8000_001F[EDX]. The maximum SEV ASID
+ * available is discovered by CPUID Fn8000_001F[ECX].
+ */
+uint32_t min_asid, max_asid;
+virHostCPUX86GetCPUID(0x801F, 0, NULL, NULL,
+  _asid, _asid);
+
+if (max_asid != 0 && min_asid != 0) {
+caps->max_guests = max_asid - min_asid + 1;
+caps->max_es_guests = min_asid - 1;
+} else {
+caps->max_guests = caps->max_es_guests = 0;
+}
+}
+
 static int
 virQEMUCapsProbeQMPSEVCapabilities(virQEMUCaps *qemuCaps,
qemuMonitor *mon)
@@ -3305,6 +3332,8 @@ virQEMUCapsProbeQMPSEVCapabilities(virQEMUCaps *qemuCaps,
 return 0;
 }
 
+virQEMUCapsGetSEVMaxGuests(caps);
+
 virSEVCapabilitiesFree(qemuCaps->sevCapabilities);
 qemuCaps->sevCapabilities = caps;
 return 0;
@@ -4084,6 +4113,14 @@ virQEMUCapsParseSEVInfo(virQEMUCaps *qemuCaps, 
xmlXPathContextPtr ctxt)
 return -1;
 }
 
+
+/* We probe this every time because the values
+ * can change on every reboot via firmware
+ * config tunables. It is cheap to query so
+ * lack of caching is a non-issue
+ */
+virQEMUCapsGetSEVMaxGuests(sev);
+
 qemuCaps->sevCapabilities = g_steal_pointer();
 return 0;
 }
@@ -6344,6 +6381,8 @@ virQEMUCapsFillDomainFeatureSEVCaps(virQEMUCaps *qemuCaps,
 domCaps->sev->cert_chain = g_strdup(cap->cert_chain);
 domCaps->sev->cbitpos = cap->cbitpos;
 domCaps->sev->reduced_phys_bits = cap->reduced_phys_bits;
+domCaps->sev->max_guests = cap->max_guests;
+domCaps->sev->max_es_guests = cap->max_es_guests;
 }
 
 
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index ee23e10543..8ee0939295 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -19918,6 +19918,16 @@ qemuGetSEVInfoToParams(virQEMUCaps *qemuCaps,
 sev->reduced_phys_bits) < 0)
 goto cleanup;
 
+if (virTypedParamsAddUInt(, , ,
+VIR_NODE_SEV_MAX_GUESTS,
+sev->max_guests) < 0)
+goto cleanup;
+
+if (virTypedParamsAddUInt(, , ,
+VIR_NODE_SEV_MAX_ES_GUESTS,
+sev->max_es_guests) < 0)
+goto cleanup;
+
 *params = g_steal_pointer();
 *nparams = n;
 return 0;
diff --git a/tests/domaincapsdata/qemu_2.12.0-q35.x86_64.xml 
b/tests/domaincapsdata/qemu_2.12.0-q35.x86_64.xml
index 26816ff066..0dc5995c09 100644
--- a/tests/domaincapsdata/qemu_2.12.0-q35.x86_64.xml
+++ b/tests/domaincapsdata/qemu_2.12.0-q35.x86_64.xml
@@ -205,8 +205,8 @@
 
   47
   1
-  0
-  0
+  59
+  450
 
   
 
diff --git a/tests/domaincapsdata/qemu_2.12.0-tcg.x86_64.xml 
b/tests/domaincapsdata/qemu_2.12.0-tcg.x86_64.xml
index 5840a8b921..575506d852 100644
--- a/tests/domaincapsdata/qemu_2.12.0-tcg.x86_64.xml
+++ b/tests/domaincapsdata/qemu_2.12.0-tcg.x86_64.xml
@@ -215,8 +215,8 @@
 
   47
   1
-  0
-  0
+  59
+  450
 
   
 
diff --git 

[libvirt PATCH v3 06/13] tools: add 'nodesevinfo' virsh command

2021-12-10 Thread Daniel P . Berrangé
While some SEV info is reported in the domain capabilities,
for reasons of size, this excludes the certificates. The
nodesevinfo command provides the full set of information.

Reviewed-by: Peter Krempa 
Signed-off-by: Daniel P. Berrangé 
---
 docs/manpages/virsh.rst | 14 +
 tools/virsh-host.c  | 45 +
 2 files changed, 59 insertions(+)

diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst
index 1a74217625..e828f7ef68 100644
--- a/docs/manpages/virsh.rst
+++ b/docs/manpages/virsh.rst
@@ -479,6 +479,20 @@ Returns memory stats of the node.
 If *cell* is specified, this will print the specified cell statistics only.
 
 
+nodesevinfo
+---
+
+**Syntax:**
+
+::
+
+   nodesevinfo
+
+Reports information about the AMD SEV launch security features for
+the node, if any. Some of this information is also reported in the
+domain capabilities XML document.
+
+
 nodesuspend
 ---
 
diff --git a/tools/virsh-host.c b/tools/virsh-host.c
index 5da1346a9c..5ee3834de2 100644
--- a/tools/virsh-host.c
+++ b/tools/virsh-host.c
@@ -888,6 +888,45 @@ cmdNodeMemStats(vshControl *ctl, const vshCmd *cmd)
 return true;
 }
 
+/*
+ * "nodesevinfo" command
+ */
+static const vshCmdInfo info_nodesevinfo[] = {
+{.name = "help",
+ .data = N_("node SEV information")
+},
+{.name = "desc",
+ .data = N_("Returns basic SEV information about the node.")
+},
+{.name = NULL}
+};
+
+static bool
+cmdNodeSEVInfo(vshControl *ctl, const vshCmd *cmd G_GNUC_UNUSED)
+{
+virshControl *priv = ctl->privData;
+size_t i;
+int nparams = 0;
+virTypedParameterPtr params = NULL;
+bool ret = false;
+
+if (virNodeGetSEVInfo(priv->conn, , , 0) != 0) {
+vshError(ctl, "%s", _("Unable to get host SEV information"));
+goto cleanup;
+}
+
+for (i = 0; i < nparams; i++) {
+g_autofree char *str = vshGetTypedParamValue(ctl, [i]);
+vshPrint(ctl, "%-18s: %s\n", params[i].field, str);
+}
+
+ret = true;
+
+ cleanup:
+virTypedParamsFree(params, nparams);
+return ret;
+}
+
 /*
  * "nodesuspend" command
  */
@@ -1828,6 +1867,12 @@ const vshCmdDef hostAndHypervisorCmds[] = {
  .info = info_nodememstats,
  .flags = 0
 },
+{.name = "nodesevinfo",
+ .handler = cmdNodeSEVInfo,
+ .opts = NULL,
+ .info = info_nodesevinfo,
+ .flags = 0
+},
 {.name = "nodesuspend",
  .handler = cmdNodeSuspend,
  .opts = opts_node_suspend,
-- 
2.33.1



[libvirt PATCH v3 07/13] conf: extend domain capabilities for max SEV guest count

2021-12-10 Thread Daniel P . Berrangé
There are limits on the number of SEV/SEV-ES guests that can
be run on machines, which may be influenced by firmware
settings. This is important to expose to users.

Reviewed-by: Peter Krempa 
Signed-off-by: Daniel P. Berrangé 
---
 docs/formatdomaincaps.html.in   | 6 ++
 docs/schemas/domaincaps.rng | 6 ++
 src/conf/domain_capabilities.c  | 4 
 src/conf/domain_capabilities.h  | 2 ++
 tests/domaincapsdata/qemu_2.12.0-q35.x86_64.xml | 2 ++
 tests/domaincapsdata/qemu_2.12.0-tcg.x86_64.xml | 2 ++
 tests/domaincapsdata/qemu_2.12.0.x86_64.xml | 2 ++
 tests/domaincapsdata/qemu_6.0.0-q35.x86_64.xml  | 2 ++
 tests/domaincapsdata/qemu_6.0.0-tcg.x86_64.xml  | 2 ++
 tests/domaincapsdata/qemu_6.0.0.x86_64.xml  | 2 ++
 10 files changed, 30 insertions(+)

diff --git a/docs/formatdomaincaps.html.in b/docs/formatdomaincaps.html.in
index 915ece8e3e..35b8bf3def 100644
--- a/docs/formatdomaincaps.html.in
+++ b/docs/formatdomaincaps.html.in
@@ -681,6 +681,12 @@
   reducedPhysBits
   When memory encryption is enabled, we lose certain bits in physical
   address space. The number of bits we lose is hypervisor dependent.
+  maxGuests
+  The maximum number of SEV guests that can be launched on the host.
+  This value may be configurable in the firmware for some hosts.
+  maxESGuests
+  The maximum number of SEV-ES guests that can be launched on the host.
+  This value may be configurable in the firmware for some hosts.
 
 
   
diff --git a/docs/schemas/domaincaps.rng b/docs/schemas/domaincaps.rng
index 1b6122507f..b40ee0f35a 100644
--- a/docs/schemas/domaincaps.rng
+++ b/docs/schemas/domaincaps.rng
@@ -323,6 +323,12 @@
 
   
 
+
+  
+
+
+  
+
   
 
   
diff --git a/src/conf/domain_capabilities.c b/src/conf/domain_capabilities.c
index fef1326190..c394a7a390 100644
--- a/src/conf/domain_capabilities.c
+++ b/src/conf/domain_capabilities.c
@@ -597,6 +597,10 @@ virDomainCapsFeatureSEVFormat(virBuffer *buf,
 virBufferAsprintf(buf, "%d\n", sev->cbitpos);
 virBufferAsprintf(buf, "%d\n",
   sev->reduced_phys_bits);
+virBufferAsprintf(buf, "%d\n",
+  sev->max_guests);
+virBufferAsprintf(buf, "%d\n",
+  sev->max_es_guests);
 virBufferAdjustIndent(buf, -2);
 virBufferAddLit(buf, "\n");
 }
diff --git a/src/conf/domain_capabilities.h b/src/conf/domain_capabilities.h
index 2fcad87fd8..1d2f4ac7a5 100644
--- a/src/conf/domain_capabilities.h
+++ b/src/conf/domain_capabilities.h
@@ -187,6 +187,8 @@ struct _virSEVCapability {
 char *cert_chain;
 unsigned int cbitpos;
 unsigned int reduced_phys_bits;
+unsigned int max_guests;
+unsigned int max_es_guests;
 };
 
 typedef enum {
diff --git a/tests/domaincapsdata/qemu_2.12.0-q35.x86_64.xml 
b/tests/domaincapsdata/qemu_2.12.0-q35.x86_64.xml
index 9f41dfaf2b..26816ff066 100644
--- a/tests/domaincapsdata/qemu_2.12.0-q35.x86_64.xml
+++ b/tests/domaincapsdata/qemu_2.12.0-q35.x86_64.xml
@@ -205,6 +205,8 @@
 
   47
   1
+  0
+  0
 
   
 
diff --git a/tests/domaincapsdata/qemu_2.12.0-tcg.x86_64.xml 
b/tests/domaincapsdata/qemu_2.12.0-tcg.x86_64.xml
index d5f9d8ebe3..5840a8b921 100644
--- a/tests/domaincapsdata/qemu_2.12.0-tcg.x86_64.xml
+++ b/tests/domaincapsdata/qemu_2.12.0-tcg.x86_64.xml
@@ -215,6 +215,8 @@
 
   47
   1
+  0
+  0
 
   
 
diff --git a/tests/domaincapsdata/qemu_2.12.0.x86_64.xml 
b/tests/domaincapsdata/qemu_2.12.0.x86_64.xml
index dc2c3ec4dd..21d1b6946e 100644
--- a/tests/domaincapsdata/qemu_2.12.0.x86_64.xml
+++ b/tests/domaincapsdata/qemu_2.12.0.x86_64.xml
@@ -205,6 +205,8 @@
 
   47
   1
+  0
+  0
 
   
 
diff --git a/tests/domaincapsdata/qemu_6.0.0-q35.x86_64.xml 
b/tests/domaincapsdata/qemu_6.0.0-q35.x86_64.xml
index 90acb29775..3415d44019 100644
--- a/tests/domaincapsdata/qemu_6.0.0-q35.x86_64.xml
+++ b/tests/domaincapsdata/qemu_6.0.0-q35.x86_64.xml
@@ -227,6 +227,8 @@
 
   47
   1
+  0
+  0
 
   
 
diff --git a/tests/domaincapsdata/qemu_6.0.0-tcg.x86_64.xml 
b/tests/domaincapsdata/qemu_6.0.0-tcg.x86_64.xml
index 768cba5a41..f58be3af6c 100644
--- a/tests/domaincapsdata/qemu_6.0.0-tcg.x86_64.xml
+++ b/tests/domaincapsdata/qemu_6.0.0-tcg.x86_64.xml
@@ -233,6 +233,8 @@
 
   47
   1
+  0
+  0
 
   
 
diff --git a/tests/domaincapsdata/qemu_6.0.0.x86_64.xml 
b/tests/domaincapsdata/qemu_6.0.0.x86_64.xml
index 7a95c530f9..0a2615c519 100644
--- a/tests/domaincapsdata/qemu_6.0.0.x86_64.xml
+++ b/tests/domaincapsdata/qemu_6.0.0.x86_64.xml
@@ -227,6 +227,8 @@
 
   47
   1
+  0
+  0
 
   
 
-- 
2.33.1



[libvirt PATCH v3 09/13] util: pull CPUID helper function out of CPU driver

2021-12-10 Thread Daniel P . Berrangé
This will be needed directly in the QEMU driver in a later patch.

Signed-off-by: Daniel P. Berrangé 
---
 src/cpu/cpu_x86.c| 34 +--
 src/libvirt_private.syms |  1 +
 src/util/virhostcpu.c| 58 
 src/util/virhostcpu.h|  7 +
 4 files changed, 72 insertions(+), 28 deletions(-)

diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
index 0b2ff82d40..5cb9caef8a 100644
--- a/src/cpu/cpu_x86.c
+++ b/src/cpu/cpu_x86.c
@@ -2377,34 +2377,12 @@ virCPUx86DataCheckFeature(const virCPUData *data,
 static inline void
 cpuidCall(virCPUx86CPUID *cpuid)
 {
-# if __x86_64__
-asm("xor %%ebx, %%ebx;" /* clear the other registers as some cpuid */
-"xor %%edx, %%edx;" /* functions may use them as additional arguments 
*/
-"cpuid;"
-: "=a" (cpuid->eax),
-  "=b" (cpuid->ebx),
-  "=c" (cpuid->ecx),
-  "=d" (cpuid->edx)
-: "a" (cpuid->eax_in),
-  "c" (cpuid->ecx_in));
-# else
-/* we need to avoid direct use of ebx for CPUID output as it is used
- * for global offset table on i386 with -fPIC
- */
-asm("push %%ebx;"
-"xor %%ebx, %%ebx;" /* clear the other registers as some cpuid */
-"xor %%edx, %%edx;" /* functions may use them as additional arguments 
*/
-"cpuid;"
-"mov %%ebx, %1;"
-"pop %%ebx;"
-: "=a" (cpuid->eax),
-  "=r" (cpuid->ebx),
-  "=c" (cpuid->ecx),
-  "=d" (cpuid->edx)
-: "a" (cpuid->eax_in),
-  "c" (cpuid->ecx_in)
-: "cc");
-# endif
+virHostCPUX86GetCPUID(cpuid->eax_in,
+  cpuid->ecx_in,
+  >eax,
+  >ebx,
+  >ecx,
+  >edx);
 }
 
 
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index da27ee7b53..53262e25b7 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2417,6 +2417,7 @@ virHostCPUGetThreadsPerSubcore;
 virHostCPUHasBitmap;
 virHostCPUReadSignature;
 virHostCPUStatsAssign;
+virHostCPUX86GetCPUID;
 
 
 # util/virhostmem.h
diff --git a/src/util/virhostcpu.c b/src/util/virhostcpu.c
index 54e2462a95..a07c00a0e9 100644
--- a/src/util/virhostcpu.c
+++ b/src/util/virhostcpu.c
@@ -1583,3 +1583,61 @@ virHostCPUGetHaltPollTime(pid_t pid,
 
 return 0;
 }
+
+void
+virHostCPUX86GetCPUID(uint32_t leaf G_GNUC_UNUSED,
+  uint32_t extended G_GNUC_UNUSED,
+  uint32_t *eax,
+  uint32_t *ebx,
+  uint32_t *ecx,
+  uint32_t *edx)
+{
+#if defined(__i386__) || defined(__x86_64__)
+uint32_t out[4];
+# if __x86_64__
+asm("xor %%ebx, %%ebx;" /* clear the other registers as some cpuid */
+"xor %%edx, %%edx;" /* functions may use them as additional arguments 
*/
+"cpuid;"
+: "=a" (out[0]),
+  "=b" (out[1]),
+  "=c" (out[2]),
+  "=d" (out[3])
+: "a" (leaf),
+  "c" (extended));
+# else
+/* we need to avoid direct use of ebx for CPUID output as it is used
+ * for global offset table on i386 with -fPIC
+ */
+asm("push %%ebx;"
+"xor %%ebx, %%ebx;" /* clear the other registers as some cpuid */
+"xor %%edx, %%edx;" /* functions may use them as additional arguments 
*/
+"cpuid;"
+"mov %%ebx, %1;"
+"pop %%ebx;"
+: "=a" (out[0]),
+  "=r" (out[1]),
+  "=c" (out[2]),
+  "=d" (out[3])
+: "a" (leaf),
+  "c" (extended)
+: "cc");
+# endif
+if (eax)
+*eax = out[0];
+if (ebx)
+*ebx = out[1];
+if (ecx)
+*ecx = out[2];
+if (edx)
+*edx = out[3];
+#else
+if (eax)
+*eax = 0;
+if (ebx)
+*ebx = 0;
+if (ecx)
+*ecx = 0;
+if (edx)
+*edx = 0;
+#endif
+}
diff --git a/src/util/virhostcpu.h b/src/util/virhostcpu.h
index a96dd5afba..86a231daa2 100644
--- a/src/util/virhostcpu.h
+++ b/src/util/virhostcpu.h
@@ -89,3 +89,10 @@ int virHostCPUGetSignature(char **signature);
 int virHostCPUGetHaltPollTime(pid_t pid,
   unsigned long long *haltPollSuccess,
   unsigned long long *haltPollFail);
+
+void virHostCPUX86GetCPUID(uint32_t leaf,
+   uint32_t extended,
+   uint32_t *eax,
+   uint32_t *ebx,
+   uint32_t *ecx,
+   uint32_t *edx);
-- 
2.33.1



[libvirt PATCH v3 08/13] include: define parameters for reporting SEV guest limits

2021-12-10 Thread Daniel P . Berrangé
There are limits on the number of SEV/SEV-ES guests that can
be run on machines, which may be influenced by firmware
settings. This is important to expose to users.

Reviewed-by: Peter Krempa 
Signed-off-by: Daniel P. Berrangé 
---
 include/libvirt/libvirt-host.h | 16 
 1 file changed, 16 insertions(+)

diff --git a/include/libvirt/libvirt-host.h b/include/libvirt/libvirt-host.h
index 4caed94a77..1dc4b8a147 100644
--- a/include/libvirt/libvirt-host.h
+++ b/include/libvirt/libvirt-host.h
@@ -472,6 +472,22 @@ typedef virNodeMemoryStats *virNodeMemoryStatsPtr;
  */
 # define VIR_NODE_SEV_REDUCED_PHYS_BITS "reduced-phys-bits"
 
+/**
+ * VIR_NODE_SEV_MAX_GUESTS:
+ *
+ * Macro represents the number of SEV guests that can
+ * be run on the host, as a VIR_TYPED_PARAM_UINT.
+ */
+# define VIR_NODE_SEV_MAX_GUESTS "max-guests"
+
+/**
+ * VIR_NODE_SEV_MAX_ES_GUESTS:
+ *
+ * Macro represents the number of SEV-ES guests that can
+ * be run on the host, as a VIR_TYPED_PARAM_UINT.
+ */
+# define VIR_NODE_SEV_MAX_ES_GUESTS "max-es-guests"
+
 int virNodeGetSEVInfo (virConnectPtr conn,
virTypedParameterPtr *params,
int *nparams,
-- 
2.33.1



[libvirt PATCH v3 04/13] qemu: report new launch security parameters

2021-12-10 Thread Daniel P . Berrangé
Report extra info about the SEV setup, returning those fields
that are required to calculate the expected launch measurement

 HMAC(0x04 || API_MAJOR || API_MINOR || BUILD ||
  GCTX.POLICY || GCTX.LD || MNONCE; GCTX.TIK)

specified in section 6.5.1 of AMD Secure Encrypted
Virtualization API.

Reviewed-by: Peter Krempa 
Signed-off-by: Daniel P. Berrangé 
---
 src/qemu/qemu_driver.c | 43 +++---
 1 file changed, 36 insertions(+), 7 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index f28d703512..ee23e10543 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -19961,14 +19961,19 @@ qemuNodeGetSEVInfo(virConnectPtr conn,
 
 
 static int
-qemuDomainGetSEVMeasurement(virQEMUDriver *driver,
-virDomainObj *vm,
-virTypedParameterPtr *params,
-int *nparams,
-unsigned int flags)
+qemuDomainGetSEVInfo(virQEMUDriver *driver,
+ virDomainObj *vm,
+ virTypedParameterPtr *params,
+ int *nparams,
+ unsigned int flags)
 {
 int ret = -1;
+int rv;
 g_autofree char *tmp = NULL;
+unsigned int apiMajor = 0;
+unsigned int apiMinor = 0;
+unsigned int buildID = 0;
+unsigned int policy = 0;
 int maxpar = 0;
 
 virCheckFlags(VIR_TYPED_PARAM_STRING_OKAY, -1);
@@ -19985,15 +19990,39 @@ qemuDomainGetSEVMeasurement(virQEMUDriver *driver,
 qemuDomainObjEnterMonitor(driver, vm);
 tmp = qemuMonitorGetSEVMeasurement(QEMU_DOMAIN_PRIVATE(vm)->mon);
 
+
+if (!tmp) {
+qemuDomainObjExitMonitor(driver, vm);
+goto endjob;
+}
+
+rv = qemuMonitorGetSEVInfo(QEMU_DOMAIN_PRIVATE(vm)->mon,
+   , , , );
 qemuDomainObjExitMonitor(driver, vm);
 
-if (!tmp)
+if (rv < 0)
 goto endjob;
 
 if (virTypedParamsAddString(params, nparams, ,
 VIR_DOMAIN_LAUNCH_SECURITY_SEV_MEASUREMENT,
 tmp) < 0)
 goto endjob;
+if (virTypedParamsAddUInt(params, nparams, ,
+  VIR_DOMAIN_LAUNCH_SECURITY_SEV_API_MAJOR,
+  apiMajor) < 0)
+goto endjob;
+if (virTypedParamsAddUInt(params, nparams, ,
+  VIR_DOMAIN_LAUNCH_SECURITY_SEV_API_MINOR,
+  apiMinor) < 0)
+goto endjob;
+if (virTypedParamsAddUInt(params, nparams, ,
+  VIR_DOMAIN_LAUNCH_SECURITY_SEV_BUILD_ID,
+  buildID) < 0)
+goto endjob;
+if (virTypedParamsAddUInt(params, nparams, ,
+  VIR_DOMAIN_LAUNCH_SECURITY_SEV_POLICY,
+  policy) < 0)
+goto endjob;
 
 ret = 0;
 
@@ -20021,7 +20050,7 @@ qemuDomainGetLaunchSecurityInfo(virDomainPtr domain,
 
 if (vm->def->sec &&
 vm->def->sec->sectype == VIR_DOMAIN_LAUNCH_SECURITY_SEV) {
-if (qemuDomainGetSEVMeasurement(driver, vm, params, nparams, flags) < 
0)
+if (qemuDomainGetSEVInfo(driver, vm, params, nparams, flags) < 0)
 goto cleanup;
 }
 
-- 
2.33.1



[libvirt PATCH v3 03/13] qemu: add monitor APIs for query-sev

2021-12-10 Thread Daniel P . Berrangé
We're only returning the set of fields needed to perform an
attestation, per the SEV API docs.

Reviewed-by: Peter Krempa 
Signed-off-by: Daniel P. Berrangé 
---
 src/qemu/qemu_monitor.c  | 13 ++
 src/qemu/qemu_monitor.h  |  9 +++
 src/qemu/qemu_monitor_json.c | 46 
 src/qemu/qemu_monitor_json.h |  9 +++
 tests/qemumonitorjsontest.c  | 43 +
 5 files changed, 120 insertions(+)

diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 75e0e4ed92..dda6ae9796 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -4366,6 +4366,19 @@ qemuMonitorGetSEVMeasurement(qemuMonitor *mon)
 }
 
 
+int
+qemuMonitorGetSEVInfo(qemuMonitor *mon,
+  unsigned int *apiMajor,
+  unsigned int *apiMinor,
+  unsigned int *buildID,
+  unsigned int *policy)
+{
+QEMU_CHECK_MONITOR(mon);
+
+return qemuMonitorJSONGetSEVInfo(mon, apiMajor, apiMinor, buildID, policy);
+}
+
+
 int
 qemuMonitorGetPRManagerInfo(qemuMonitor *mon,
 GHashTable **retinfo)
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index edc2b01a66..29746f0b8e 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -1445,6 +1445,15 @@ int qemuMonitorBlockdevMediumInsert(qemuMonitor *mon,
 char *
 qemuMonitorGetSEVMeasurement(qemuMonitor *mon);
 
+int
+qemuMonitorGetSEVInfo(qemuMonitor *mon,
+  unsigned int *apiMajor,
+  unsigned int *apiMinor,
+  unsigned int *buildID,
+  unsigned int *policy)
+ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
+ATTRIBUTE_NONNULL(4) ATTRIBUTE_NONNULL(5);
+
 typedef struct _qemuMonitorPRManagerInfo qemuMonitorPRManagerInfo;
 struct _qemuMonitorPRManagerInfo {
 bool connected;
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index e00d785c20..a3d6eca569 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -8216,6 +8216,52 @@ qemuMonitorJSONGetSEVMeasurement(qemuMonitor *mon)
 }
 
 
+/**
+ * Retrive info about the SEV setup, returning those fields that
+ * are required to do a launch attestation, as per
+ *
+ * HMAC(0x04 || API_MAJOR || API_MINOR || BUILD || GCTX.POLICY || GCTX.LD || 
MNONCE; GCTX.TIK)
+ *
+ * specified in section 6.5.1 of AMD Secure Encrypted
+ * Virtualization API.
+ *
+ *  { "execute": "query-sev" }
+ *  { "return": { "enabled": true, "api-major" : 0, "api-minor" : 0,
+ *"build-id" : 0, "policy" : 0, "state" : "running",
+ *"handle" : 1 } }
+ */
+int
+qemuMonitorJSONGetSEVInfo(qemuMonitor *mon,
+  unsigned int *apiMajor,
+  unsigned int *apiMinor,
+  unsigned int *buildID,
+  unsigned int *policy)
+{
+g_autoptr(virJSONValue) cmd = NULL;
+g_autoptr(virJSONValue) reply = NULL;
+virJSONValue *data;
+
+if (!(cmd = qemuMonitorJSONMakeCommand("query-sev", NULL)))
+return -1;
+
+if (qemuMonitorJSONCommand(mon, cmd, ) < 0)
+return -1;
+
+if (qemuMonitorJSONCheckReply(cmd, reply, VIR_JSON_TYPE_OBJECT) < 0)
+return -1;
+
+data = virJSONValueObjectGetObject(reply, "return");
+
+if (virJSONValueObjectGetNumberUint(data, "api-major", apiMajor) < 0 ||
+virJSONValueObjectGetNumberUint(data, "api-minor", apiMinor) < 0 ||
+virJSONValueObjectGetNumberUint(data, "build-id", buildID) < 0 ||
+virJSONValueObjectGetNumberUint(data, "policy", policy) < 0)
+return -1;
+
+return 0;
+}
+
+
 /*
  * Example return data
  *
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index 64064b0519..e88dfc9d50 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -459,6 +459,15 @@ qemuMonitorJSONSystemWakeup(qemuMonitor *mon);
 char *
 qemuMonitorJSONGetSEVMeasurement(qemuMonitor *mon);
 
+int
+qemuMonitorJSONGetSEVInfo(qemuMonitor *mon,
+  unsigned int *apiMajor,
+  unsigned int *apiMinor,
+  unsigned int *buildID,
+  unsigned int *policy)
+ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
+ATTRIBUTE_NONNULL(4) ATTRIBUTE_NONNULL(5);
+
 int
 qemuMonitorJSONGetVersion(qemuMonitor *mon,
   int *major,
diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c
index 1ad2912b08..1b0bd0870d 100644
--- a/tests/qemumonitorjsontest.c
+++ b/tests/qemumonitorjsontest.c
@@ -2884,6 +2884,48 @@ 
testQemuMonitorJSONqemuMonitorJSONGetCPUModelBaseline(const void *opaque)
 }
 
 
+static int
+testQemuMonitorJSONGetSEVInfo(const void *opaque)
+{
+const testGenericData *data = opaque;
+virDomainXMLOption *xmlopt = data->xmlopt;
+

[libvirt PATCH v3 05/13] tools: add 'domlaunchsecinfo' virsh command

2021-12-10 Thread Daniel P . Berrangé
This command reports the launch security parameters for
a guest, allowing an external tool to perform a launch
attestation.

Reviewed-by: Peter Krempa 
Signed-off-by: Daniel P. Berrangé 
---
 docs/manpages/virsh.rst | 17 +
 tools/virsh-domain.c| 53 +
 2 files changed, 70 insertions(+)

diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst
index 275f416090..1a74217625 100644
--- a/docs/manpages/virsh.rst
+++ b/docs/manpages/virsh.rst
@@ -2057,6 +2057,23 @@ destination hosts have synchronized time (i.e., NTP 
daemon is running
 on both of them).
 
 
+domlaunchsecinfo
+
+
+**Syntax:**
+
+::
+
+   domlaunchsecinfo domain
+
+Returns information about the launch security parameters associated
+with a running domain.
+
+The set of parameters reported will vary depending on which type of
+launch security protection is active. If none is active, no parameters
+will be reported.
+
+
 dommemstat
 --
 
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 2338d6522a..c748fe2ba9 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -9523,6 +9523,53 @@ cmdNumatune(vshControl * ctl, const vshCmd * cmd)
 goto cleanup;
 }
 
+/*
+ * "domlaunchsecinfo" command
+ */
+static const vshCmdInfo info_domlaunchsecinfo[] = {
+{.name = "help",
+ .data = N_("Get domain launch security info")
+},
+{.name = "desc",
+ .data = N_("Get the launch security parameters for a guest domain")
+},
+{.name = NULL}
+};
+
+static const vshCmdOptDef opts_domlaunchsecinfo[] = {
+VIRSH_COMMON_OPT_DOMAIN_FULL(0),
+{.name = NULL}
+};
+
+static bool
+cmdDomLaunchSecInfo(vshControl * ctl, const vshCmd * cmd)
+{
+g_autoptr(virshDomain) dom = NULL;
+size_t i;
+int nparams = 0;
+virTypedParameterPtr params = NULL;
+bool ret = false;
+
+if (!(dom = virshCommandOptDomain(ctl, cmd, NULL)))
+return false;
+
+if (virDomainGetLaunchSecurityInfo(dom, , , 0) != 0) {
+vshError(ctl, "%s", _("Unable to get launch security parameters"));
+goto cleanup;
+}
+
+for (i = 0; i < nparams; i++) {
+g_autofree char *str = vshGetTypedParamValue(ctl, [i]);
+vshPrint(ctl, "%-15s: %s\n", params[i].field, str);
+}
+
+ret = true;
+
+ cleanup:
+virTypedParamsFree(params, nparams);
+return ret;
+}
+
 /*
  * "qemu-monitor-command" command
  */
@@ -14542,6 +14589,12 @@ const vshCmdDef domManagementCmds[] = {
  .info = info_domjobinfo,
  .flags = 0
 },
+{.name = "domlaunchsecinfo",
+ .handler = cmdDomLaunchSecInfo,
+ .opts = opts_domlaunchsecinfo,
+ .info = info_domlaunchsecinfo,
+ .flags = 0
+},
 {.name = "domname",
  .handler = cmdDomname,
  .opts = opts_domname,
-- 
2.33.1



[libvirt PATCH v3 00/13] Improve AMD SEV support

2021-12-10 Thread Daniel P . Berrangé
This addresses a few issues in the AMD SEV support

 - Neither host or domain level SEV metadata is
   exposed in virsh commands
 - The domain launch security parameters don't expose
   enough info to validate the measurement
 - Support verified direct kernel boot
 - Report max SEV/SEV-ES guest counts

The second point was the initial purpose of my work. Per the
SEV API guide to calculate the measurement we need

measurement = HMAC(0x04 || API_MAJOR || API_MINOR || BUILD ||
 GCTX.POLICY || GCTX.LD || MNONCE; GCTX.TIK)

The API_MINOR, API_MAJOR, BUILD values are things that are
available from 'query-sev' QMP command  and libvirt does
not expose this info. This patch series adds them to
virDomainGetLaunchSecurityParams alongside the measurement
that we already report.

So now the client can fetch this info and calculate an expected
measurement to compare with the actual measurement they got.

They will thus know if the guest is safe to inject secrets into,
which is where Jim's recent patches come into play.

In v3:

 - Refactor CPUID code so and mock it in test suite

Daniel P. Berrangé (13):
  include: add new launch security parameters
  qemu: report error querying launch params for inactive guest
  qemu: add monitor APIs for query-sev
  qemu: report new launch security parameters
  tools: add 'domlaunchsecinfo' virsh command
  tools: add 'nodesevinfo' virsh command
  conf: extend domain capabilities for max SEV guest count
  include: define parameters for reporting SEV guest limits
  util: pull CPUID helper function out of CPU driver
  qemu: report max number of SEV guests
  conf: add support for setting SEV kernel hashes
  qemu: probe for sev-guest.kernel-hashes property
  qemu: format sev-guest.kernel-hashes property

 docs/formatdomain.rst |   7 +-
 docs/formatdomaincaps.html.in |   6 +
 docs/manpages/virsh.rst   |  31 +
 docs/schemas/domaincaps.rng   |   6 +
 docs/schemas/domaincommon.rng |   5 +
 include/libvirt/libvirt-domain.h  |  32 +
 include/libvirt/libvirt-host.h|  16 +++
 src/conf/domain_capabilities.c|   4 +
 src/conf/domain_capabilities.h|   2 +
 src/conf/domain_conf.c|   8 ++
 src/conf/domain_conf.h|   1 +
 src/cpu/cpu_x86.c |  34 +-
 src/libvirt_private.syms  |   1 +
 src/qemu/qemu_capabilities.c  |  47 
 src/qemu/qemu_capabilities.h  |   1 +
 src/qemu/qemu_command.c   |   1 +
 src/qemu/qemu_driver.c|  59 --
 src/qemu/qemu_monitor.c   |  13 +++
 src/qemu/qemu_monitor.h   |   9 ++
 src/qemu/qemu_monitor_json.c  |  46 
 src/qemu/qemu_monitor_json.h  |   9 ++
 src/qemu/qemu_validate.c  |   7 ++
 src/util/virhostcpu.c |  58 ++
 src/util/virhostcpu.h |   7 ++
 .../domaincapsdata/qemu_2.12.0-q35.x86_64.xml |   2 +
 .../domaincapsdata/qemu_2.12.0-tcg.x86_64.xml |   2 +
 tests/domaincapsdata/qemu_2.12.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.2.0-q35.x86_64.xml  |   7 +-
 .../domaincapsdata/qemu_6.2.0-tcg.x86_64.xml  |   7 +-
 tests/domaincapsdata/qemu_6.2.0.x86_64.xml|   7 +-
 .../caps_2.12.0.x86_64.replies|  97 
 .../caps_3.0.0.x86_64.replies |  97 
 .../caps_3.1.0.x86_64.replies |  97 
 .../caps_4.0.0.x86_64.replies |  97 
 .../caps_4.1.0.x86_64.replies |  89 ++
 .../caps_4.2.0.x86_64.replies |  89 ++
 .../caps_5.0.0.x86_64.replies |  89 ++
 .../caps_5.1.0.x86_64.replies |  89 ++
 .../caps_5.2.0.x86_64.replies |  89 ++
 .../caps_6.0.0.x86_64.replies |  89 ++
 .../caps_6.1.0.x86_64.replies |  89 ++
 .../caps_6.2.0.x86_64.replies | 109 ++
 .../caps_6.2.0.x86_64.xml |   8 ++
 tests/qemumonitorjsontest.c   |  43 +++
 ...unch-security-sev-direct.x86_64-6.2.0.args |  40 +++
 .../launch-security-sev-direct.xml|  39 +++
 tests/qemuxml2argvtest.c  |   1 +
 tests/testutilsqemu.c |  21 
 tools/virsh-domain.c  |  53 +
 tools/virsh-host.c|  45 
 53 files changed, 1514 insertions(+), 299 

[libvirt PATCH v3 02/13] qemu: report error querying launch params for inactive guest

2021-12-10 Thread Daniel P . Berrangé
Querying launch params on a inactive guest currently triggers
a warning about the monitor being NULL.

https://bugzilla.redhat.com/show_bug.cgi?id=2030437

Reviewed-by: Peter Krempa 
Signed-off-by: Daniel P. Berrangé 
---
 src/qemu/qemu_driver.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index e444ad2d45..f28d703512 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -19976,6 +19976,12 @@ qemuDomainGetSEVMeasurement(virQEMUDriver *driver,
 if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0)
 return -1;
 
+if (!virDomainObjIsActive(vm)) {
+virReportError(VIR_ERR_OPERATION_INVALID,
+   "%s", _("domain is not running"));
+goto endjob;
+}
+
 qemuDomainObjEnterMonitor(driver, vm);
 tmp = qemuMonitorGetSEVMeasurement(QEMU_DOMAIN_PRIVATE(vm)->mon);
 
-- 
2.33.1



[libvirt PATCH v3 01/13] include: add new launch security parameters

2021-12-10 Thread Daniel P . Berrangé
Three more parameters are required in order that clients can
perform a launch attestation on the SEV guest.

Reviewed-by: Peter Krempa 
Signed-off-by: Daniel P. Berrangé 
---
 include/libvirt/libvirt-domain.h | 32 
 1 file changed, 32 insertions(+)

diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index d0dd11ab01..5d3e15766e 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -5101,6 +5101,38 @@ int virDomainSetLifecycleAction(virDomainPtr domain,
  */
 # define VIR_DOMAIN_LAUNCH_SECURITY_SEV_MEASUREMENT "sev-measurement"
 
+/**
+ * VIR_DOMAIN_LAUNCH_SECURITY_SEV_API_MAJOR:
+ *
+ * Macro represents the API major version of the SEV host,
+ * as VIR_TYPED_PARAM_UINT.
+ */
+# define VIR_DOMAIN_LAUNCH_SECURITY_SEV_API_MAJOR "sev-api-major"
+
+/**
+ * VIR_DOMAIN_LAUNCH_SECURITY_SEV_API_MINOR:
+ *
+ * Macro represents the API minor version of the SEV guest,
+ * as VIR_TYPED_PARAM_UINT.
+ */
+# define VIR_DOMAIN_LAUNCH_SECURITY_SEV_API_MINOR "sev-api-minor"
+
+/**
+ * VIR_DOMAIN_LAUNCH_SECURITY_SEV_BUILD_ID:
+ *
+ * Macro represents the build ID of the SEV host,
+ * as VIR_TYPED_PARAM_UINT.
+ */
+# define VIR_DOMAIN_LAUNCH_SECURITY_SEV_BUILD_ID "sev-build-id"
+
+/**
+ * VIR_DOMAIN_LAUNCH_SECURITY_SEV_POLICY:
+ *
+ * Macro represents the policy of the SEV guest,
+ * as VIR_TYPED_PARAM_UINT.
+ */
+# define VIR_DOMAIN_LAUNCH_SECURITY_SEV_POLICY "sev-policy"
+
 int virDomainGetLaunchSecurityInfo(virDomainPtr domain,
virTypedParameterPtr *params,
int *nparams,
-- 
2.33.1



[libvirt PATCH 8/8] Remove empty cleanup sections

2021-12-10 Thread Ján Tomko
After recent cleanups, there are some pointless cleanup sections.

Clean them up.

Signed-off-by: Ján Tomko 
---
 src/bhyve/bhyve_driver.c   | 19 +---
 src/ch/ch_conf.c   |  9 +++-
 src/hyperv/hyperv_driver.c |  5 +
 src/libxl/libxl_capabilities.c |  9 +++-
 src/libxl/libxl_conf.c | 11 +++--
 src/libxl/xen_common.c |  8 ++-
 src/libxl/xen_xl.c | 32 +-
 src/lxc/lxc_conf.c | 13 +--
 src/lxc/lxc_container.c| 12 --
 src/lxc/lxc_driver.c   | 12 --
 src/lxc/lxc_native.c   | 41 --
 src/lxc/lxc_process.c  | 19 +---
 src/test/test_driver.c |  9 +++-
 src/util/vircgroup.c   | 12 --
 src/util/virfirmware.c | 18 +--
 src/vz/vz_driver.c | 15 +
 tests/qemucaps2xmltest.c   |  9 +++-
 tests/vboxsnapshotxmltest.c|  8 ++-
 tests/virconftest.c| 24 +---
 tests/virfiletest.c| 14 +---
 tests/virstringtest.c  | 16 +
 21 files changed, 106 insertions(+), 209 deletions(-)

diff --git a/src/bhyve/bhyve_driver.c b/src/bhyve/bhyve_driver.c
index cb1544665e..21407a3957 100644
--- a/src/bhyve/bhyve_driver.c
+++ b/src/bhyve/bhyve_driver.c
@@ -141,7 +141,6 @@ bhyveConnectGetCapabilities(virConnectPtr conn)
 {
 struct _bhyveConn *privconn = conn->privateData;
 g_autoptr(virCaps) caps = NULL;
-char *xml = NULL;
 
 if (virConnectGetCapabilitiesEnsureACL(conn) < 0)
 return NULL;
@@ -149,14 +148,10 @@ bhyveConnectGetCapabilities(virConnectPtr conn)
 if (!(caps = bhyveDriverGetCapabilities(privconn))) {
 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to get Capabilities"));
-goto cleanup;
+return NULL;
 }
 
-if (!(xml = virCapabilitiesFormatXML(caps)))
-goto cleanup;
-
- cleanup:
-return xml;
+return virCapabilitiesFormatXML(caps);
 }
 
 static virDomainObj *
@@ -1558,7 +1553,6 @@ bhyveConnectDomainXMLFromNative(virConnectPtr conn,
 const char *nativeConfig,
 unsigned int flags)
 {
-char *xml = NULL;
 g_autoptr(virDomainDef) def = NULL;
 struct _bhyveConn *privconn = conn->privateData;
 unsigned bhyveCaps = bhyveDriverGetBhyveCaps(privconn);
@@ -1571,18 +1565,15 @@ bhyveConnectDomainXMLFromNative(virConnectPtr conn,
 if (STRNEQ(nativeFormat, BHYVE_CONFIG_FORMAT_ARGV)) {
 virReportError(VIR_ERR_INVALID_ARG,
_("unsupported config type %s"), nativeFormat);
-goto cleanup;
+return NULL;
 }
 
 def = bhyveParseCommandLineString(nativeConfig, bhyveCaps,
   privconn->xmlopt);
 if (def == NULL)
-goto cleanup;
+return NULL;
 
-xml = virDomainDefFormat(def, privconn->xmlopt, 0);
-
- cleanup:
-return xml;
+return virDomainDefFormat(def, privconn->xmlopt, 0);
 }
 
 static char *
diff --git a/src/ch/ch_conf.c b/src/ch/ch_conf.c
index a9cbbca560..98f1e89003 100644
--- a/src/ch/ch_conf.c
+++ b/src/ch/ch_conf.c
@@ -57,13 +57,13 @@ virCaps *virCHDriverCapsInit(void)
 
 if ((caps = virCapabilitiesNew(virArchFromHost(),
false, false)) == NULL)
-goto cleanup;
+return NULL;
 
 if (!(caps->host.numa = virCapabilitiesHostNUMANewHost()))
-goto cleanup;
+return NULL;
 
 if (virCapabilitiesInitCaches(caps) < 0)
-goto cleanup;
+return NULL;
 
 guest = virCapabilitiesAddGuest(caps, VIR_DOMAIN_OSTYPE_HVM,
 caps->host.arch, NULL, NULL, 0, NULL);
@@ -71,9 +71,6 @@ virCaps *virCHDriverCapsInit(void)
 virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_KVM,
   NULL, NULL, 0, NULL);
 return g_steal_pointer();
-
- cleanup:
-return NULL;
 }
 
 /**
diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c
index 4d938f4d7f..3327f0132e 100644
--- a/src/hyperv/hyperv_driver.c
+++ b/src/hyperv/hyperv_driver.c
@@ -271,7 +271,7 @@ hypervCapsInit(hypervPrivate *priv)
 return NULL;
 
 if (hypervLookupHostSystemBiosUuid(priv, caps->host.host_uuid) < 0)
-goto error;
+return NULL;
 
 /* i686 caps */
 guest = virCapabilitiesAddGuest(caps, VIR_DOMAIN_OSTYPE_HVM, VIR_ARCH_I686,
@@ -288,9 +288,6 @@ hypervCapsInit(hypervPrivate *priv)
   NULL, NULL, 0, NULL);
 
 return g_steal_pointer();
-
- error:
-return NULL;
 }
 
 
diff --git a/src/libxl/libxl_capabilities.c b/src/libxl/libxl_capabilities.c
index 9084dacb40..970ad37306 100644
--- a/src/libxl/libxl_capabilities.c
+++ b/src/libxl/libxl_capabilities.c
@@ -645,18 +645,15 @@ libxlMakeCapabilities(libxl_ctx 

[libvirt PATCH 7/8] bhyve: bhyveConnectCompareCPU: remove cleanup label

2021-12-10 Thread Ján Tomko
Return the desired values directly and clean up the redundant
else branches.

Signed-off-by: Ján Tomko 
---
 src/bhyve/bhyve_driver.c | 18 +++---
 1 file changed, 7 insertions(+), 11 deletions(-)

diff --git a/src/bhyve/bhyve_driver.c b/src/bhyve/bhyve_driver.c
index e445c8cadf..cb1544665e 100644
--- a/src/bhyve/bhyve_driver.c
+++ b/src/bhyve/bhyve_driver.c
@@ -1431,7 +1431,6 @@ bhyveConnectCompareCPU(virConnectPtr conn,
unsigned int flags)
 {
 struct _bhyveConn *driver = conn->privateData;
-int ret = VIR_CPU_COMPARE_ERROR;
 g_autoptr(virCaps) caps = NULL;
 bool failIncompatible;
 bool validateXML;
@@ -1441,30 +1440,27 @@ bhyveConnectCompareCPU(virConnectPtr conn,
   VIR_CPU_COMPARE_ERROR);
 
 if (virConnectCompareCPUEnsureACL(conn) < 0)
-goto cleanup;
+return VIR_CPU_COMPARE_ERROR;
 
 failIncompatible = !!(flags & VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE);
 validateXML = !!(flags & VIR_CONNECT_COMPARE_CPU_VALIDATE_XML);
 
 if (!(caps = bhyveDriverGetCapabilities(driver)))
-goto cleanup;
+return VIR_CPU_COMPARE_ERROR;
 
 if (!caps->host.cpu ||
 !caps->host.cpu->model) {
 if (failIncompatible) {
 virReportError(VIR_ERR_CPU_INCOMPATIBLE, "%s",
_("cannot get host CPU capabilities"));
-} else {
-VIR_WARN("cannot get host CPU capabilities");
-ret = VIR_CPU_COMPARE_INCOMPATIBLE;
+return VIR_CPU_COMPARE_ERROR;
 }
-} else {
-ret = virCPUCompareXML(caps->host.arch, caps->host.cpu,
-   xmlDesc, failIncompatible, validateXML);
+VIR_WARN("cannot get host CPU capabilities");
+return VIR_CPU_COMPARE_INCOMPATIBLE;
 }
 
- cleanup:
-return ret;
+return virCPUCompareXML(caps->host.arch, caps->host.cpu,
+xmlDesc, failIncompatible, validateXML);
 }
 
 static int
-- 
2.31.1



[libvirt PATCH 6/8] lxc: remove cleanup from lxcNodeGetSecurityModel

2021-12-10 Thread Ján Tomko
Return the values directly.

Signed-off-by: Ján Tomko 
---
 src/lxc/lxc_driver.c | 24 
 1 file changed, 8 insertions(+), 16 deletions(-)

diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index 0d438de4a5..aa4bdd68ac 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -1220,32 +1220,26 @@ static int lxcNodeGetSecurityModel(virConnectPtr conn,
 {
 virLXCDriver *driver = conn->privateData;
 g_autoptr(virCaps) caps = NULL;
-int ret = 0;
 
 memset(secmodel, 0, sizeof(*secmodel));
 
-if (virNodeGetSecurityModelEnsureACL(conn) < 0) {
-ret = -1;
-goto cleanup;
-}
+if (virNodeGetSecurityModelEnsureACL(conn) < 0)
+return -1;
 
-if (!(caps = virLXCDriverGetCapabilities(driver, false))) {
-ret = -1;
-goto cleanup;
-}
+if (!(caps = virLXCDriverGetCapabilities(driver, false)))
+return -1;
 
 /* we treat no driver as success, but simply return no data in *secmodel */
 if (caps->host.nsecModels == 0
 || caps->host.secModels[0].model == NULL)
-goto cleanup;
+return 0;
 
 if (virStrcpy(secmodel->model, caps->host.secModels[0].model,
   VIR_SECURITY_MODEL_BUFLEN) < 0) {
 virReportError(VIR_ERR_INTERNAL_ERROR,
_("security model string exceeds max %d bytes"),
VIR_SECURITY_MODEL_BUFLEN - 1);
-ret = -1;
-goto cleanup;
+return -1;
 }
 
 if (virStrcpy(secmodel->doi, caps->host.secModels[0].doi,
@@ -1253,12 +1247,10 @@ static int lxcNodeGetSecurityModel(virConnectPtr conn,
 virReportError(VIR_ERR_INTERNAL_ERROR,
_("security DOI string exceeds max %d bytes"),
VIR_SECURITY_DOI_BUFLEN-1);
-ret = -1;
-goto cleanup;
+return -1;
 }
 
- cleanup:
-return ret;
+return 0;
 }
 
 
-- 
2.31.1



[libvirt PATCH 0/8] Use g_auto for virCaps and LXCDriverConfig (glib chronicles)

2021-12-10 Thread Ján Tomko
Pipeline in progress: https://gitlab.com/janotomko/libvirt/-/pipelines/427100328

Ján Tomko (8):
  lxc: fix error value of lxcNodeGetSecurityModel
  Use g_auto for freeing virCaps
  Use g_auto for stealing virCaps
  lxc: define cleanup function for virLXCDriverConfig
  lxc: use g_auto for virLXCDriverGetConfig
  lxc: remove cleanup from lxcNodeGetSecurityModel
  bhyve: bhyveConnectCompareCPU: remove cleanup label
  Remove empty cleanup sections

 src/bhyve/bhyve_driver.c   | 46 ++--
 src/ch/ch_conf.c   | 14 ++---
 src/ch/ch_driver.c |  3 +-
 src/hyperv/hyperv_driver.c | 10 ++--
 src/libxl/libxl_capabilities.c | 14 ++---
 src/libxl/libxl_conf.c | 11 ++--
 src/libxl/xen_common.c |  8 +--
 src/libxl/xen_xl.c | 32 ---
 src/lxc/lxc_conf.c | 18 +++
 src/lxc/lxc_conf.h |  2 +
 src/lxc/lxc_container.c| 12 ++---
 src/lxc/lxc_driver.c   | 97 --
 src/lxc/lxc_native.c   | 41 +-
 src/lxc/lxc_process.c  | 44 +--
 src/test/test_driver.c | 14 ++---
 src/util/vircgroup.c   | 12 ++---
 src/util/virfirmware.c | 18 +++
 src/vmware/vmware_conf.c   |  5 +-
 src/vz/vz_driver.c | 20 +++
 tests/qemucaps2xmltest.c   | 14 ++---
 tests/testutilsxen.c   |  5 +-
 tests/vboxsnapshotxmltest.c|  8 +--
 tests/virconftest.c| 24 -
 tests/virfiletest.c| 14 ++---
 tests/virstringtest.c  | 16 +++---
 25 files changed, 174 insertions(+), 328 deletions(-)

-- 
2.31.1



[libvirt PATCH 6/6] virt-pki-query-dn: Add manual page

2021-12-10 Thread Andrea Bolognani
Signed-off-by: Andrea Bolognani 
---
 docs/manpages/meson.build   |  1 +
 docs/manpages/virt-pki-query-dn.rst | 91 +
 libvirt.spec.in |  1 +
 3 files changed, 93 insertions(+)
 create mode 100644 docs/manpages/virt-pki-query-dn.rst

diff --git a/docs/manpages/meson.build b/docs/manpages/meson.build
index e80fff48c8..bf6fc730e0 100644
--- a/docs/manpages/meson.build
+++ b/docs/manpages/meson.build
@@ -16,6 +16,7 @@ docs_man_files = [
   { 'name': 'virt-admin', 'section': '1', 'install': true },
   { 'name': 'virt-host-validate', 'section': '1', 'install': 
conf.has('WITH_HOST_VALIDATE') },
   { 'name': 'virt-login-shell', 'section': '1', 'install': 
conf.has('WITH_LOGIN_SHELL') },
+  { 'name': 'virt-pki-query-dn', 'section': '1', 'install': true },
   { 'name': 'virt-pki-validate', 'section': '1', 'install': true },
   { 'name': 'virt-qemu-run', 'section': '1', 'install': conf.has('WITH_QEMU') 
},
   { 'name': 'virt-ssh-helper', 'section': '1', 'install': true },
diff --git a/docs/manpages/virt-pki-query-dn.rst 
b/docs/manpages/virt-pki-query-dn.rst
new file mode 100644
index 00..0e162d6dc5
--- /dev/null
+++ b/docs/manpages/virt-pki-query-dn.rst
@@ -0,0 +1,91 @@
+=
+virt-pki-query-dn
+=
+
+-
+extract Distinguished Name from a PEM certificate
+-
+
+:Manual section: 1
+:Manual group: Virtualization Support
+
+.. contents::
+
+
+SYNOPSIS
+
+
+``virt-pki-query-dn`` *FILE*
+``virt-pki-query-dn`` *OPTION*
+
+
+DESCRIPTION
+===
+
+Extract Distinguished Name from a PEM certificate.
+
+The output is meant to be used in the ``tls_allowed_dn_list``
+configuration option in the ``libvirtd.conf`` file.
+
+
+OPTIONS
+===
+
+``-h``, ``--help``
+
+Display command line help usage then exit.
+
+``-V``, ``--version``
+
+Display version information then exit.
+
+
+EXIT STATUS
+===
+
+The exit status will be zero on success, non-zero on failure.
+
+
+AUTHOR
+==
+
+Martin Kletzander
+
+
+BUGS
+
+
+Please report all bugs you discover.  This should be done via either:
+
+#. the mailing list
+
+   `https://libvirt.org/contact.html `_
+
+#. the bug tracker
+
+   `https://libvirt.org/bugs.html `_
+
+Alternatively, you may report bugs to your software distributor / vendor.
+
+
+COPYRIGHT
+=
+
+Copyright (C) 2021 Red Hat, Inc.
+
+
+LICENSE
+===
+
+``virt-pki-query-dn`` is distributed under the terms of the GNU GPL v2+.
+This is free software; see the source for copying conditions. There
+is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE.
+
+
+SEE ALSO
+
+
+virsh(1), virt-pki-validate(1),
+`online PKI setup instructions `_,
+`https://www.libvirt.org/ `_
diff --git a/libvirt.spec.in b/libvirt.spec.in
index 9cf1046604..22a15c7d23 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -1986,6 +1986,7 @@ exit 0
 %files client
 %{_mandir}/man1/virsh.1*
 %{_mandir}/man1/virt-xml-validate.1*
+%{_mandir}/man1/virt-pki-query-dn.1*
 %{_mandir}/man1/virt-pki-validate.1*
 %{_bindir}/virsh
 %{_bindir}/virt-xml-validate
-- 
2.31.1



[libvirt PATCH 3/6] virt-ssh-helper: Add manual page

2021-12-10 Thread Andrea Bolognani
Signed-off-by: Andrea Bolognani 
---
 docs/manpages/meson.build |  1 +
 docs/manpages/virt-ssh-helper.rst | 96 +++
 libvirt.spec.in   |  1 +
 3 files changed, 98 insertions(+)
 create mode 100644 docs/manpages/virt-ssh-helper.rst

diff --git a/docs/manpages/meson.build b/docs/manpages/meson.build
index cafe29a545..e80fff48c8 100644
--- a/docs/manpages/meson.build
+++ b/docs/manpages/meson.build
@@ -18,6 +18,7 @@ docs_man_files = [
   { 'name': 'virt-login-shell', 'section': '1', 'install': 
conf.has('WITH_LOGIN_SHELL') },
   { 'name': 'virt-pki-validate', 'section': '1', 'install': true },
   { 'name': 'virt-qemu-run', 'section': '1', 'install': conf.has('WITH_QEMU') 
},
+  { 'name': 'virt-ssh-helper', 'section': '1', 'install': true },
   { 'name': 'virt-xml-validate', 'section': '1', 'install': true },
 
   { 'name': 'libvirtd', 'section': '8', 'install': conf.has('WITH_LIBVIRTD') },
diff --git a/docs/manpages/virt-ssh-helper.rst 
b/docs/manpages/virt-ssh-helper.rst
new file mode 100644
index 00..be3f7db243
--- /dev/null
+++ b/docs/manpages/virt-ssh-helper.rst
@@ -0,0 +1,96 @@
+===
+virt-ssh-helper
+===
+
+
+libvirt socket proxy
+
+
+:Manual section: 1
+:Manual group: Virtualization Support
+
+.. contents::
+
+
+SYNOPSIS
+
+
+``virt-ssh-helper`` [*OPTIONS*...] *URI*
+``virt-ssh-helper`` *OPTION*
+
+
+DESCRIPTION
+===
+
+``virt-ssh-helper`` is an internal tool used to handle connections
+coming from remote clients, and it's not intended to be called
+directly by the user.
+
+
+OPTIONS
+===
+
+*URI*
+
+Local libvirt URI to connect the remote client to.
+
+``-r``, ``--readonly``
+
+Make the connection read-only.
+
+``-h``, ``--help``
+
+Display command line help usage then exit.
+
+``-V``, ``--version``
+
+Display version information then exit.
+
+
+EXIT STATUS
+===
+
+The exit status will be zero on success, non-zero on failure.
+
+
+AUTHOR
+==
+
+Daniel P. Berrangé
+
+
+BUGS
+
+
+Please report all bugs you discover.  This should be done via either:
+
+#. the mailing list
+
+   `https://libvirt.org/contact.html `_
+
+#. the bug tracker
+
+   `https://libvirt.org/bugs.html `_
+
+Alternatively, you may report bugs to your software distributor / vendor.
+
+
+COPYRIGHT
+=
+
+Copyright (C) 2020 Red Hat, Inc.
+
+
+LICENSE
+===
+
+``virt-ssh-helper`` is distributed under the terms of the GNU LGPL v2+.
+This is free software; see the source for copying conditions. There
+is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE.
+
+
+SEE ALSO
+
+
+virsh(1), `https://libvirt.org/ `_
diff --git a/libvirt.spec.in b/libvirt.spec.in
index 5a079cdaf3..9cf1046604 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -1697,6 +1697,7 @@ exit 0
 
 %{_mandir}/man1/virt-admin.1*
 %{_mandir}/man1/virt-host-validate.1*
+%{_mandir}/man1/virt-ssh-helper.1*
 %{_mandir}/man8/libvirtd.8*
 %{_mandir}/man8/virtlogd.8*
 %{_mandir}/man8/virtlockd.8*
-- 
2.31.1



[libvirt PATCH 2/6] virt-ssh-helper: Improve usage information

2021-12-10 Thread Andrea Bolognani
Specifically:

  * include non-option argument 'URI' in usage summary;
  * mention that it's an internal tool not meant to be
called directly;
  * exit earlier if required arguments are absent.

Signed-off-by: Andrea Bolognani 
---
 src/remote/remote_ssh_helper.c | 16 ++--
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/src/remote/remote_ssh_helper.c b/src/remote/remote_ssh_helper.c
index 092676dd74..4f4dbff7d0 100644
--- a/src/remote/remote_ssh_helper.c
+++ b/src/remote/remote_ssh_helper.c
@@ -369,7 +369,10 @@ int main(int argc, char **argv)
 };
 unsigned int flags;
 
-context = g_option_context_new("- libvirt socket proxy");
+context = g_option_context_new("URI - libvirt socket proxy");
+g_option_context_set_summary(context,
+ "Internal tool used to handle connections 
coming from remote\n"
+ "clients. Not intended to be called directly 
by the user.");
 g_option_context_add_main_entries(context, entries, PACKAGE);
 if (!g_option_context_parse(context, , , )) {
 g_printerr(_("option parsing failed: %s\n"), error->message);
@@ -381,6 +384,12 @@ int main(int argc, char **argv)
 exit(EXIT_SUCCESS);
 }
 
+if (argc != 2) {
+g_autofree char *help = g_option_context_get_help(context, TRUE, NULL);
+g_printerr("%s", help);
+exit(EXIT_FAILURE);
+}
+
 virSetErrorFunc(NULL, NULL);
 virSetErrorLogPriorityFunc(NULL);
 
@@ -395,11 +404,6 @@ int main(int argc, char **argv)
 /* Initialize the log system */
 virLogSetFromEnv();
 
-if (argc != 2) {
-g_printerr("%s: expected a URI\n", argv[0]);
-exit(EXIT_FAILURE);
-}
-
 uri_str = argv[1];
 VIR_DEBUG("Using URI %s", uri_str);
 
-- 
2.31.1



[libvirt PATCH 1/6] virt-ssh-helper: Don't use optind

2021-12-10 Thread Andrea Bolognani
It's a getopt interface and we're not using getopt, at least
directly, so even though it works relying on it feels wrong.

GOption takes care of removing any trace of the arguments it
consumes from argc and argv, leaving behind only non-option
arguments, so we can just use those standard variables.

Signed-off-by: Andrea Bolognani 
---
 src/remote/remote_ssh_helper.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/remote/remote_ssh_helper.c b/src/remote/remote_ssh_helper.c
index 0945b90331..092676dd74 100644
--- a/src/remote/remote_ssh_helper.c
+++ b/src/remote/remote_ssh_helper.c
@@ -395,12 +395,12 @@ int main(int argc, char **argv)
 /* Initialize the log system */
 virLogSetFromEnv();
 
-if (optind != (argc - 1)) {
+if (argc != 2) {
 g_printerr("%s: expected a URI\n", argv[0]);
 exit(EXIT_FAILURE);
 }
 
-uri_str = argv[optind];
+uri_str = argv[1];
 VIR_DEBUG("Using URI %s", uri_str);
 
 if (!(uri = virURIParse(uri_str))) {
-- 
2.31.1



[libvirt PATCH 0/6] Improve usage information and manual pages

2021-12-10 Thread Andrea Bolognani
Each of the tools we ship as part of libvirt should display
reasonable usage information when called without arguments and have
an associated manual page.

Andrea Bolognani (6):
  virt-ssh-helper: Don't use optind
  virt-ssh-helper: Improve usage information
  virt-ssh-helper: Add manual page
  virt-qemu-run: Improve usage information
  virt-qemu-run: Improve manual page
  virt-pki-query-dn: Add manual page

 docs/manpages/meson.build   |  2 +
 docs/manpages/virt-pki-query-dn.rst | 91 +++
 docs/manpages/virt-qemu-run.rst | 53 +---
 docs/manpages/virt-ssh-helper.rst   | 96 +
 libvirt.spec.in |  2 +
 src/qemu/qemu_shim.c|  2 +-
 src/remote/remote_ssh_helper.c  | 18 +++---
 7 files changed, 234 insertions(+), 30 deletions(-)
 create mode 100644 docs/manpages/virt-pki-query-dn.rst
 create mode 100644 docs/manpages/virt-ssh-helper.rst

-- 
2.31.1




[libvirt PATCH 5/8] lxc: use g_auto for virLXCDriverGetConfig

2021-12-10 Thread Ján Tomko
Signed-off-by: Ján Tomko 
---
 src/lxc/lxc_driver.c  | 48 +++
 src/lxc/lxc_process.c | 22 +++-
 2 files changed, 23 insertions(+), 47 deletions(-)

diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index 92ae22ef2b..0d438de4a5 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -403,7 +403,7 @@ lxcDomainDefineXMLFlags(virConnectPtr conn, const char 
*xml, unsigned int flags)
 virDomainPtr dom = NULL;
 virObjectEvent *event = NULL;
 g_autoptr(virDomainDef) oldDef = NULL;
-virLXCDriverConfig *cfg = virLXCDriverGetConfig(driver);
+g_autoptr(virLXCDriverConfig) cfg = virLXCDriverGetConfig(driver);
 g_autoptr(virCaps) caps = NULL;
 unsigned int parse_flags = VIR_DOMAIN_DEF_PARSE_INACTIVE;
 
@@ -458,7 +458,6 @@ lxcDomainDefineXMLFlags(virConnectPtr conn, const char 
*xml, unsigned int flags)
  cleanup:
 virDomainObjEndAPI();
 virObjectEventStateQueue(driver->domainEventState, event);
-virObjectUnref(cfg);
 return dom;
 }
 
@@ -475,7 +474,7 @@ static int lxcDomainUndefineFlags(virDomainPtr dom,
 virDomainObj *vm;
 virObjectEvent *event = NULL;
 int ret = -1;
-virLXCDriverConfig *cfg = virLXCDriverGetConfig(driver);
+g_autoptr(virLXCDriverConfig) cfg = virLXCDriverGetConfig(driver);
 
 virCheckFlags(0, -1);
 
@@ -510,7 +509,6 @@ static int lxcDomainUndefineFlags(virDomainPtr dom,
  cleanup:
 virDomainObjEndAPI();
 virObjectEventStateQueue(driver->domainEventState, event);
-virObjectUnref(cfg);
 return ret;
 }
 
@@ -638,7 +636,7 @@ static int lxcDomainSetMemoryFlags(virDomainPtr dom, 
unsigned long newmem,
 int ret = -1;
 virLXCDomainObjPrivate *priv;
 virLXCDriver *driver = dom->conn->privateData;
-virLXCDriverConfig *cfg = NULL;
+g_autoptr(virLXCDriverConfig) cfg = NULL;
 
 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
   VIR_DOMAIN_AFFECT_CONFIG |
@@ -719,7 +717,6 @@ static int lxcDomainSetMemoryFlags(virDomainPtr dom, 
unsigned long newmem,
 
  cleanup:
 virDomainObjEndAPI();
-virObjectUnref(cfg);
 return ret;
 }
 
@@ -743,7 +740,7 @@ lxcDomainSetMemoryParameters(virDomainPtr dom,
 virDomainDef *persistentDef = NULL;
 virDomainObj *vm = NULL;
 virLXCDomainObjPrivate *priv = NULL;
-virLXCDriverConfig *cfg = NULL;
+g_autoptr(virLXCDriverConfig) cfg = NULL;
 virLXCDriver *driver = dom->conn->privateData;
 int ret = -1;
 
@@ -804,7 +801,6 @@ lxcDomainSetMemoryParameters(virDomainPtr dom,
 
  cleanup:
 virDomainObjEndAPI();
-virObjectUnref(cfg);
 return ret;
 }
 
@@ -975,7 +971,7 @@ static int lxcDomainCreateWithFiles(virDomainPtr dom,
 virDomainObj *vm;
 virObjectEvent *event = NULL;
 int ret = -1;
-virLXCDriverConfig *cfg = virLXCDriverGetConfig(driver);
+g_autoptr(virLXCDriverConfig) cfg = virLXCDriverGetConfig(driver);
 
 virCheckFlags(VIR_DOMAIN_START_AUTODESTROY, -1);
 
@@ -1022,7 +1018,6 @@ static int lxcDomainCreateWithFiles(virDomainPtr dom,
  cleanup:
 virDomainObjEndAPI();
 virObjectEventStateQueue(driver->domainEventState, event);
-virObjectUnref(cfg);
 virNWFilterUnlockFilterUpdates();
 return ret;
 }
@@ -1078,7 +1073,7 @@ lxcDomainCreateXMLWithFiles(virConnectPtr conn,
 g_autoptr(virDomainDef) def = NULL;
 virDomainPtr dom = NULL;
 virObjectEvent *event = NULL;
-virLXCDriverConfig *cfg = virLXCDriverGetConfig(driver);
+g_autoptr(virLXCDriverConfig) cfg = virLXCDriverGetConfig(driver);
 g_autoptr(virCaps) caps = NULL;
 unsigned int parse_flags = VIR_DOMAIN_DEF_PARSE_INACTIVE;
 
@@ -1147,7 +1142,6 @@ lxcDomainCreateXMLWithFiles(virConnectPtr conn,
  cleanup:
 virDomainObjEndAPI();
 virObjectEventStateQueue(driver->domainEventState, event);
-virObjectUnref(cfg);
 virNWFilterUnlockFilterUpdates();
 return dom;
 }
@@ -1592,7 +1586,7 @@ static void lxcNotifyLoadDomain(virDomainObj *vm, int 
newVM, void *opaque)
 static int
 lxcStateReload(void)
 {
-virLXCDriverConfig *cfg = NULL;
+g_autoptr(virLXCDriverConfig) cfg = NULL;
 
 if (!lxc_driver)
 return 0;
@@ -1604,7 +1598,6 @@ lxcStateReload(void)
cfg->autostartDir, false,
lxc_driver->xmlopt,
lxcNotifyLoadDomain, lxc_driver);
-virObjectUnref(cfg);
 return 0;
 }
 
@@ -1811,7 +1804,7 @@ lxcDomainSetSchedulerParametersFlags(virDomainPtr dom,
 int ret = -1;
 int rc;
 virLXCDomainObjPrivate *priv;
-virLXCDriverConfig *cfg = virLXCDriverGetConfig(driver);
+g_autoptr(virLXCDriverConfig) cfg = virLXCDriverGetConfig(driver);
 
 virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
   VIR_DOMAIN_AFFECT_CONFIG, -1);
@@ -1920,7 +1913,6 @@ lxcDomainSetSchedulerParametersFlags(virDomainPtr dom,
 
  cleanup:
 virDomainObjEndAPI();
-virObjectUnref(cfg);
 return ret;
 }
 
@@ 

[libvirt PATCH 3/8] Use g_auto for stealing virCaps

2021-12-10 Thread Ján Tomko
Convert all the functions that generate virCaps to use g_auto
and g_steal_pointer.

Signed-off-by: Ján Tomko 
---
 src/ch/ch_conf.c   | 5 ++---
 src/hyperv/hyperv_driver.c | 5 ++---
 src/libxl/libxl_capabilities.c | 5 ++---
 src/lxc/lxc_conf.c | 5 ++---
 src/test/test_driver.c | 5 ++---
 src/vmware/vmware_conf.c   | 5 ++---
 src/vz/vz_driver.c | 5 ++---
 tests/qemucaps2xmltest.c   | 5 ++---
 tests/testutilsxen.c   | 5 ++---
 9 files changed, 18 insertions(+), 27 deletions(-)

diff --git a/src/ch/ch_conf.c b/src/ch/ch_conf.c
index ef6f4b5ba8..a9cbbca560 100644
--- a/src/ch/ch_conf.c
+++ b/src/ch/ch_conf.c
@@ -52,7 +52,7 @@ VIR_ONCE_GLOBAL_INIT(virCHConfig);
 /* Functions */
 virCaps *virCHDriverCapsInit(void)
 {
-virCaps *caps;
+g_autoptr(virCaps) caps = NULL;
 virCapsGuest *guest;
 
 if ((caps = virCapabilitiesNew(virArchFromHost(),
@@ -70,10 +70,9 @@ virCaps *virCHDriverCapsInit(void)
 
 virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_KVM,
   NULL, NULL, 0, NULL);
-return caps;
+return g_steal_pointer();
 
  cleanup:
-virObjectUnref(caps);
 return NULL;
 }
 
diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c
index bafec27a88..4d938f4d7f 100644
--- a/src/hyperv/hyperv_driver.c
+++ b/src/hyperv/hyperv_driver.c
@@ -262,7 +262,7 @@ hypervLookupHostSystemBiosUuid(hypervPrivate *priv, 
unsigned char *uuid)
 static virCaps *
 hypervCapsInit(hypervPrivate *priv)
 {
-virCaps *caps = NULL;
+g_autoptr(virCaps) caps = NULL;
 virCapsGuest *guest = NULL;
 
 caps = virCapabilitiesNew(VIR_ARCH_X86_64, 1, 1);
@@ -287,10 +287,9 @@ hypervCapsInit(hypervPrivate *priv)
 virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_HYPERV,
   NULL, NULL, 0, NULL);
 
-return caps;
+return g_steal_pointer();
 
  error:
-virObjectUnref(caps);
 return NULL;
 }
 
diff --git a/src/libxl/libxl_capabilities.c b/src/libxl/libxl_capabilities.c
index 6263b5c8b5..9084dacb40 100644
--- a/src/libxl/libxl_capabilities.c
+++ b/src/libxl/libxl_capabilities.c
@@ -635,7 +635,7 @@ libxlMakeDomainDeviceHostdevCaps(virDomainCapsDeviceHostdev 
*dev)
 virCaps *
 libxlMakeCapabilities(libxl_ctx *ctx)
 {
-virCaps *caps;
+g_autoptr(virCaps) caps = NULL;
 
 #ifdef LIBXL_HAVE_NO_SUSPEND_RESUME
 if ((caps = virCapabilitiesNew(virArchFromHost(), false, false)) == NULL)
@@ -653,10 +653,9 @@ libxlMakeCapabilities(libxl_ctx *ctx)
 if (libxlCapsInitGuests(ctx, caps) < 0)
 goto error;
 
-return caps;
+return g_steal_pointer();
 
  error:
-virObjectUnref(caps);
 return NULL;
 }
 
diff --git a/src/lxc/lxc_conf.c b/src/lxc/lxc_conf.c
index 73156f15a3..e9186b879e 100644
--- a/src/lxc/lxc_conf.c
+++ b/src/lxc/lxc_conf.c
@@ -58,7 +58,7 @@ VIR_ONCE_GLOBAL_INIT(virLXCConfig);
 /* Functions */
 virCaps *virLXCDriverCapsInit(virLXCDriver *driver)
 {
-virCaps *caps;
+g_autoptr(virCaps) caps = NULL;
 virCapsGuest *guest;
 virArch altArch;
 g_autofree char *lxc_path = NULL;
@@ -138,10 +138,9 @@ virCaps *virLXCDriverCapsInit(virLXCDriver *driver)
 VIR_INFO("No driver, not initializing security driver");
 }
 
-return caps;
+return g_steal_pointer();
 
  error:
-virObjectUnref(caps);
 return NULL;
 }
 
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index 995e63b004..020a9e5df0 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -291,7 +291,7 @@ static virCaps *
 testBuildCapabilities(virConnectPtr conn)
 {
 testDriver *privconn = conn->privateData;
-virCaps *caps;
+g_autoptr(virCaps) caps = NULL;
 virCapsGuest *guest;
 int guest_types[] = { VIR_DOMAIN_OSTYPE_HVM,
   VIR_DOMAIN_OSTYPE_XEN };
@@ -361,10 +361,9 @@ testBuildCapabilities(virConnectPtr conn)
 
 caps->host.secModels[0].doi = g_strdup("");
 
-return caps;
+return g_steal_pointer();
 
  error:
-virObjectUnref(caps);
 return NULL;
 }
 
diff --git a/src/vmware/vmware_conf.c b/src/vmware/vmware_conf.c
index 8c8ecc8120..3f6b51ac44 100644
--- a/src/vmware/vmware_conf.c
+++ b/src/vmware/vmware_conf.c
@@ -64,7 +64,7 @@ vmwareFreeDriver(struct vmware_driver *driver)
 virCaps *
 vmwareCapsInit(void)
 {
-virCaps *caps = NULL;
+g_autoptr(virCaps) caps = NULL;
 virCapsGuest *guest = NULL;
 
 if ((caps = virCapabilitiesNew(virArchFromHost(),
@@ -106,11 +106,10 @@ vmwareCapsInit(void)
 guest = NULL;
 }
 
-return caps;
+return g_steal_pointer();
 
  error:
 virCapabilitiesFreeGuest(guest);
-virObjectUnref(caps);
 return NULL;
 }
 
diff --git a/src/vz/vz_driver.c b/src/vz/vz_driver.c
index 83ff119dd9..1353efa6ab 100644
--- a/src/vz/vz_driver.c
+++ b/src/vz/vz_driver.c
@@ -94,7 +94,7 @@ vzCapsAddGuestDomain(virCaps *caps,
 static virCaps *
 vzBuildCapabilities(void)
 {
-virCaps *caps = NULL;
+

[libvirt PATCH 5/6] virt-qemu-run: Improve manual page

2021-12-10 Thread Andrea Bolognani
Specifically:

  * use the correct notation and markup for commands, options
and arguments;
  * rename arguments meta-variables;
  * document '--help' and '--version' options;
  * use consistent vertical spacing;
  * fix a typo.

Signed-off-by: Andrea Bolognani 
---
 docs/manpages/virt-qemu-run.rst | 53 +++--
 1 file changed, 31 insertions(+), 22 deletions(-)

diff --git a/docs/manpages/virt-qemu-run.rst b/docs/manpages/virt-qemu-run.rst
index 470de93168..a755b7fda9 100644
--- a/docs/manpages/virt-qemu-run.rst
+++ b/docs/manpages/virt-qemu-run.rst
@@ -11,10 +11,13 @@ Run a standalone QEMU guest
 
 .. contents::
 
+
 SYNOPSIS
 
 
-``virt-qemu-run [OPTIONS...] [GUEST-XML]``
+``virt-qemu-run`` [*OPTIONS...*] *GUEST-XML-FILE*
+``virt-qemu-run`` *OPTION*
+
 
 DESCRIPTION
 ===
@@ -26,50 +29,54 @@ directory tree. When the guest is run with this tool it is 
invisible
 to libvirtd and thus also invisible to other libvirt tools such as
 virsh.
 
-The virt-qemu-run program will run the QEMU virtual machine, and then
-block until the guest OS shuts down, at which point it will exit.
+The ``virt-qemu-run`` program will run the QEMU virtual machine, and
+then block until the guest OS shuts down, at which point it will
+exit.
 
-If the virt-qemu-run program is interrupted (eg Ctrl-C) it will
-immediately terminate the virtual machine without giving the guest
-OS any opportunity to gracefully shutdown.
+If the ``virt-qemu-run`` program is interrupted (eg Ctrl-C) it will
+immediately terminate the virtual machine without giving the guest OS
+any opportunity to gracefully shutdown.
 
 **NOTE: this tool is currently considered experimental.** Its
 usage and behaviour is still subject to change in future libvirt
 releases. For further information on its usage consult the
 `QEMU driver documentation 
`_.
 
+
 OPTIONS
 ===
 
-``GUEST-XML``
+*GUEST-XML-FILE*
 
 The full path to the XML file describing the guest virtual machine
 to be booted.
 
-``-h``, ``--help``
-
-Display the command line help
-
-``-v``, ``--verbose``
-
-Display verbose information about startup
-
-``-r DIR``, ``--root=DIR``
+``-r`` *DIR*, ``--root``\ =\ *DIR*
 
 Specify the root directory to use for storing state associated with
 the virtual machine. The caller is responsible for deleting this
 directory when it is no longer required.
 
 If this parameter is omitted, then a random temporary directory
-will be created, and its contents be automaticlaly deleted at
+will be created, and its contents be automatically deleted at
 VM shutdown.
 
-``-s XML-FILE,VALUE-FILE``, ``--secret=XML-FILE,VALUE-FILE``
+``-s`` *SECRET-XML-FILE*\ ,\ *SECRET-VALUE-FILE*,
+``--secret``\ =\ *SECRET-XML-FILE*\ ,\ *SECRET-VALUE-FILE*
+
+Specify a secret to be loaded into the secret driver.
+*SECRET-XML-FILE* is a path to the XML description of the secret,
+whose UUID should match a secret referenced in the guest domain XML.
+*SECRET-VALUE-FILE* is a path containing the raw value of the secret.
+
+``-h``, ``--help``
+
+Display the command line help
+
+``-v``, ``--verbose``
+
+Display verbose information about startup
 
-Specify a secret to be loaded into the secret driver. The ``XML-FILE``
-is a path to the XML description of the secret, whose UUID should
-match a secret referenced in the guest domain XML. The ``VALUE-FILE``
-is a path containing the raw value of the secret.
 
 EXIT STATUS
 ===
@@ -77,6 +84,7 @@ EXIT STATUS
 Upon successful shutdown, an exit status of 0 will be set. Upon
 failure a non-zero status will be set.
 
+
 AUTHOR
 ==
 
@@ -113,6 +121,7 @@ This is free software; see the source for copying 
conditions. There
 is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
 PURPOSE
 
+
 SEE ALSO
 
 
-- 
2.31.1



[libvirt PATCH 4/6] virt-qemu-run: Improve usage information

2021-12-10 Thread Andrea Bolognani
Specifically, include non-option argument 'GUEST-XML-FILE'
in usage summary.

Signed-off-by: Andrea Bolognani 
---
 src/qemu/qemu_shim.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/qemu/qemu_shim.c b/src/qemu/qemu_shim.c
index 8b3afd0324..a06869a406 100644
--- a/src/qemu/qemu_shim.c
+++ b/src/qemu/qemu_shim.c
@@ -163,7 +163,7 @@ int main(int argc, char **argv)
 
 #define deltams() ((long long)g_get_monotonic_time() - start)
 
-ctx = g_option_context_new("- run a standalone QEMU process");
+ctx = g_option_context_new("GUEST-XML-FILE - run a standalone QEMU 
process");
 g_option_context_add_main_entries(ctx, entries, PACKAGE);
 if (!g_option_context_parse(ctx, , , )) {
 g_printerr("%s: option parsing failed: %s\n",
-- 
2.31.1



[libvirt PATCH 4/8] lxc: define cleanup function for virLXCDriverConfig

2021-12-10 Thread Ján Tomko
Signed-off-by: Ján Tomko 
---
 src/lxc/lxc_conf.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/lxc/lxc_conf.h b/src/lxc/lxc_conf.h
index 8993013ea4..5a1351bd63 100644
--- a/src/lxc/lxc_conf.h
+++ b/src/lxc/lxc_conf.h
@@ -102,6 +102,8 @@ struct _virLXCDriver {
 virCloseCallbacks *closeCallbacks;
 };
 
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(virLXCDriverConfig, virObjectUnref);
+
 virLXCDriverConfig *virLXCDriverConfigNew(void);
 virLXCDriverConfig *virLXCDriverGetConfig(virLXCDriver *driver);
 int virLXCLoadDriverConfig(virLXCDriverConfig *cfg,
-- 
2.31.1



[libvirt PATCH 2/8] Use g_auto for freeing virCaps

2021-12-10 Thread Ján Tomko
Convert all the users who unref their virCaps object unconditionally.

Signed-off-by: Ján Tomko 
---
 src/bhyve/bhyve_driver.c |  9 +++--
 src/ch/ch_driver.c   |  3 +--
 src/lxc/lxc_driver.c | 21 +++--
 src/lxc/lxc_process.c|  3 +--
 4 files changed, 12 insertions(+), 24 deletions(-)

diff --git a/src/bhyve/bhyve_driver.c b/src/bhyve/bhyve_driver.c
index 250e10b9d0..e445c8cadf 100644
--- a/src/bhyve/bhyve_driver.c
+++ b/src/bhyve/bhyve_driver.c
@@ -140,7 +140,7 @@ static char *
 bhyveConnectGetCapabilities(virConnectPtr conn)
 {
 struct _bhyveConn *privconn = conn->privateData;
-virCaps *caps;
+g_autoptr(virCaps) caps = NULL;
 char *xml = NULL;
 
 if (virConnectGetCapabilitiesEnsureACL(conn) < 0)
@@ -156,7 +156,6 @@ bhyveConnectGetCapabilities(virConnectPtr conn)
 goto cleanup;
 
  cleanup:
-virObjectUnref(caps);
 return xml;
 }
 
@@ -508,7 +507,7 @@ bhyveDomainDefineXMLFlags(virConnectPtr conn, const char 
*xml, unsigned int flag
 g_autoptr(virDomainDef) oldDef = NULL;
 virDomainObj *vm = NULL;
 virObjectEvent *event = NULL;
-virCaps *caps = NULL;
+g_autoptr(virCaps) caps = NULL;
 unsigned int parse_flags = VIR_DOMAIN_DEF_PARSE_INACTIVE;
 
 virCheckFlags(VIR_DOMAIN_DEFINE_VALIDATE, NULL);
@@ -554,7 +553,6 @@ bhyveDomainDefineXMLFlags(virConnectPtr conn, const char 
*xml, unsigned int flag
 dom = virGetDomain(conn, vm->def->name, vm->def->uuid, vm->def->id);
 
  cleanup:
-virObjectUnref(caps);
 virDomainObjEndAPI();
 virObjectEventStateQueue(privconn->domainEventState, event);
 
@@ -1434,7 +1432,7 @@ bhyveConnectCompareCPU(virConnectPtr conn,
 {
 struct _bhyveConn *driver = conn->privateData;
 int ret = VIR_CPU_COMPARE_ERROR;
-virCaps *caps = NULL;
+g_autoptr(virCaps) caps = NULL;
 bool failIncompatible;
 bool validateXML;
 
@@ -1466,7 +1464,6 @@ bhyveConnectCompareCPU(virConnectPtr conn,
 }
 
  cleanup:
-virObjectUnref(caps);
 return ret;
 }
 
diff --git a/src/ch/ch_driver.c b/src/ch/ch_driver.c
index 108644e503..06cfb1c5ef 100644
--- a/src/ch/ch_driver.c
+++ b/src/ch/ch_driver.c
@@ -187,7 +187,7 @@ static int chNodeGetInfo(virConnectPtr conn,
 static char *chConnectGetCapabilities(virConnectPtr conn)
 {
 virCHDriver *driver = conn->privateData;
-virCaps *caps;
+g_autoptr(virCaps) caps = NULL;
 char *xml;
 
 if (virConnectGetCapabilitiesEnsureACL(conn) < 0)
@@ -198,7 +198,6 @@ static char *chConnectGetCapabilities(virConnectPtr conn)
 
 xml = virCapabilitiesFormatXML(caps);
 
-virObjectUnref(caps);
 return xml;
 }
 
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index d86147cc28..92ae22ef2b 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -197,7 +197,7 @@ static int lxcConnectIsAlive(virConnectPtr conn 
G_GNUC_UNUSED)
 
 static char *lxcConnectGetCapabilities(virConnectPtr conn) {
 virLXCDriver *driver = conn->privateData;
-virCaps *caps;
+g_autoptr(virCaps) caps = NULL;
 char *xml;
 
 if (virConnectGetCapabilitiesEnsureACL(conn) < 0)
@@ -208,7 +208,6 @@ static char *lxcConnectGetCapabilities(virConnectPtr conn) {
 
 xml = virCapabilitiesFormatXML(caps);
 
-virObjectUnref(caps);
 return xml;
 }
 
@@ -405,7 +404,7 @@ lxcDomainDefineXMLFlags(virConnectPtr conn, const char 
*xml, unsigned int flags)
 virObjectEvent *event = NULL;
 g_autoptr(virDomainDef) oldDef = NULL;
 virLXCDriverConfig *cfg = virLXCDriverGetConfig(driver);
-virCaps *caps = NULL;
+g_autoptr(virCaps) caps = NULL;
 unsigned int parse_flags = VIR_DOMAIN_DEF_PARSE_INACTIVE;
 
 virCheckFlags(VIR_DOMAIN_DEFINE_VALIDATE, NULL);
@@ -459,7 +458,6 @@ lxcDomainDefineXMLFlags(virConnectPtr conn, const char 
*xml, unsigned int flags)
  cleanup:
 virDomainObjEndAPI();
 virObjectEventStateQueue(driver->domainEventState, event);
-virObjectUnref(caps);
 virObjectUnref(cfg);
 return dom;
 }
@@ -937,7 +935,7 @@ static char *lxcConnectDomainXMLFromNative(virConnectPtr 
conn,
 char *xml = NULL;
 g_autoptr(virDomainDef) def = NULL;
 virLXCDriver *driver = conn->privateData;
-virCaps *caps = virLXCDriverGetCapabilities(driver, false);
+g_autoptr(virCaps) caps = virLXCDriverGetCapabilities(driver, false);
 
 virCheckFlags(0, NULL);
 
@@ -956,7 +954,6 @@ static char *lxcConnectDomainXMLFromNative(virConnectPtr 
conn,
 xml = virDomainDefFormat(def, driver->xmlopt, 0);
 
  cleanup:
-virObjectUnref(caps);
 return xml;
 }
 
@@ -1082,7 +1079,7 @@ lxcDomainCreateXMLWithFiles(virConnectPtr conn,
 virDomainPtr dom = NULL;
 virObjectEvent *event = NULL;
 virLXCDriverConfig *cfg = virLXCDriverGetConfig(driver);
-virCaps *caps = NULL;
+g_autoptr(virCaps) caps = NULL;
 unsigned int parse_flags = VIR_DOMAIN_DEF_PARSE_INACTIVE;
 
 virCheckFlags(VIR_DOMAIN_START_AUTODESTROY |
@@ -1150,7 +1147,6 @@ 

[libvirt PATCH 1/8] lxc: fix error value of lxcNodeGetSecurityModel

2021-12-10 Thread Ján Tomko
When adding the ACL check and caps getter, we assumed that
the default return value is -1, not 0 as usual.

Fix the return value on error by assigning them explicitly.

Signed-off-by: Ján Tomko 
---
 src/lxc/lxc_driver.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index 349783ca7c..d86147cc28 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -1234,11 +1234,15 @@ static int lxcNodeGetSecurityModel(virConnectPtr conn,
 
 memset(secmodel, 0, sizeof(*secmodel));
 
-if (virNodeGetSecurityModelEnsureACL(conn) < 0)
+if (virNodeGetSecurityModelEnsureACL(conn) < 0) {
+ret = -1;
 goto cleanup;
+}
 
-if (!(caps = virLXCDriverGetCapabilities(driver, false)))
+if (!(caps = virLXCDriverGetCapabilities(driver, false))) {
+ret = -1;
 goto cleanup;
+}
 
 /* we treat no driver as success, but simply return no data in *secmodel */
 if (caps->host.nsecModels == 0
-- 
2.31.1



Re: [libvirt PATCH v3] qemu: Enable unprivileged userfaultfd for post-copy migration

2021-12-10 Thread Daniel P . Berrangé
On Tue, Dec 07, 2021 at 03:00:31PM +0100, Jiri Denemark wrote:
> Userfaultfd is by default allowed only for privileged processes. Since
> libvirt runs QEMU unprivileged, we need to enable unprivileged access to
> userfaultfd to enable post-copy migration.
> 
> https://bugzilla.redhat.com/show_bug.cgi?id=1945420
> 
> Signed-off-by: Jiri Denemark 

Reviewed-by: Daniel P. Berrangé 


> Notes:
> If you wonder about the 60-* prefix of the installed sysctl file, we 
> already
> install 60-libvirtd.conf so I think it makes sense to use the same prefix 
> for
> all sysctl configuration installed by libvirt.

Yep, 50-* is often used by common distro defaults, so 60 makes
sense and leaves space for users to override.


Regards,
Daniel
-- 
|: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o-https://fstop138.berrange.com :|
|: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|



Re: [libvirt PATCH v2 11/12] qemu: probe for sev-guest.kernel-hashes property

2021-12-10 Thread Peter Krempa
On Fri, Dec 10, 2021 at 14:56:05 +, Daniel P. Berrangé wrote:
> On Fri, Dec 10, 2021 at 03:53:46PM +0100, Peter Krempa wrote:
> > On Fri, Dec 10, 2021 at 11:37:34 +, Daniel P. Berrangé wrote:
> > > This sev-guest object property indicates whether QEMU should
> > > expose the kernel, ramdisk, cmdline hashes to the firmware
> > > for measurement.
> > > 
> > > The 6.2.0 capabilities are hacked to look as if they were
> > > generated with sev-guest support.
> > 
> > The qemu-6.2 lifecycle is not ended yet, so I'll be re-generating the
> > caps, thus your hack will get lost.
> > 
> > Given that qemu is at rc4 now you can either wait until the final
> > release is out and I update the caps or pick a different older version
> > to hack.
> 
> This is a new feature in 6.2.0, so it has to be done in the
> 6.2.0 caps to make any sense.
> 
> As long as you can re-generate the 6.2.0 caps on a SEV capable
> machine, I'll just wait for you.

I don't have a sev-capable box, but I kept generating the caps for all
of the 6.2.0 lifecycle so it will have the least of diff.



Re: [libvirt PATCH v2 12/12] qemu: format sev-guest.kernel-hashes property

2021-12-10 Thread Peter Krempa
On Fri, Dec 10, 2021 at 11:37:35 +, Daniel P. Berrangé wrote:
> Set the kernel-hashes property on the sev-guest object if
> the config asked for it explicitly. While QEMU machine
> types currently default to having this setting off, it
> is not guaranteed to remain this way.
> 
> Signed-off-by: Daniel P. Berrangé 
> ---
>  src/qemu/qemu_command.c   |  7 
>  src/qemu/qemu_validate.c  |  8 
>  ...unch-security-sev-direct.x86_64-6.2.0.args | 40 +++
>  .../launch-security-sev-direct.xml| 39 ++
>  tests/qemuxml2argvtest.c  |  1 +
>  5 files changed, 95 insertions(+)
>  create mode 100644 
> tests/qemuxml2argvdata/launch-security-sev-direct.x86_64-6.2.0.args
>  create mode 100644 tests/qemuxml2argvdata/launch-security-sev-direct.xml
> 
> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
> index c47998aabd..6999afe5aa 100644
> --- a/src/qemu/qemu_command.c
> +++ b/src/qemu/qemu_command.c
> @@ -10112,6 +10112,13 @@ qemuBuildSEVCommandLine(virDomainObj *vm, virCommand 
> *cmd,
>   NULL) < 0)
>  return -1;

Replace all of this hunk with

"T:kernel-hashes", sev->kernel_hashes,

put into the call to qemuMonitorCreateObjectProps just above the NULL
sentinel.

>  
> +if (sev->kernel_hashes != VIR_TRISTATE_BOOL_ABSENT) {
> +bool val;
> +virTristateBoolToBool(sev->kernel_hashes, );
> +if (virJSONValueObjectAppendBoolean(props, "kernel-hashes", val) < 0)
> +return -1;
> +}
> +
>  if (qemuBuildObjectCommandlineFromJSON(cmd, props, priv->qemuCaps) < 0)
>  return -1;
>  
> diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
> index 29b01495ad..0150b0f082 100644
> --- a/src/qemu/qemu_validate.c
> +++ b/src/qemu/qemu_validate.c
> @@ -1200,6 +1200,14 @@ qemuValidateDomainDef(const virDomainDef *def,
>   "this QEMU binary"));
>  return -1;
>  }
> +
> +if (def->sec->data.sev.kernel_hashes == VIR_TRISTATE_BOOL_YES &&
> +!virQEMUCapsGet(qemuCaps, 
> QEMU_CAPS_SEV_GUEST_KERNEL_HASHES)) {
> +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
> +   _("SEV launch security measured direct kernel 
> "
> + "boot is not supported with this QEMU 
> binary"));

Error message on a single line please.

> +return -1;
> +}
>  break;
>  case VIR_DOMAIN_LAUNCH_SECURITY_PV:
>  if (!virQEMUCapsGet(qemuCaps, 
> QEMU_CAPS_MACHINE_CONFIDENTAL_GUEST_SUPPORT) ||


Reviewed-by: Peter Krempa 



Re: [libvirt PATCH v2 11/12] qemu: probe for sev-guest.kernel-hashes property

2021-12-10 Thread Daniel P . Berrangé
On Fri, Dec 10, 2021 at 03:53:46PM +0100, Peter Krempa wrote:
> On Fri, Dec 10, 2021 at 11:37:34 +, Daniel P. Berrangé wrote:
> > This sev-guest object property indicates whether QEMU should
> > expose the kernel, ramdisk, cmdline hashes to the firmware
> > for measurement.
> > 
> > The 6.2.0 capabilities are hacked to look as if they were
> > generated with sev-guest support.
> 
> The qemu-6.2 lifecycle is not ended yet, so I'll be re-generating the
> caps, thus your hack will get lost.
> 
> Given that qemu is at rc4 now you can either wait until the final
> release is out and I update the caps or pick a different older version
> to hack.

This is a new feature in 6.2.0, so it has to be done in the
6.2.0 caps to make any sense.

As long as you can re-generate the 6.2.0 caps on a SEV capable
machine, I'll just wait for you.

> 
> > Signed-off-by: Daniel P. Berrangé 
> > ---
> >  src/qemu/qemu_capabilities.c  |   8 ++
> >  src/qemu/qemu_capabilities.h  |   1 +
> >  .../domaincapsdata/qemu_6.2.0-q35.x86_64.xml  |   7 +-
> >  .../domaincapsdata/qemu_6.2.0-tcg.x86_64.xml  |   7 +-
> >  tests/domaincapsdata/qemu_6.2.0.x86_64.xml|   7 +-
> >  .../caps_2.12.0.x86_64.replies|  97 
> >  .../caps_3.0.0.x86_64.replies |  97 
> >  .../caps_3.1.0.x86_64.replies |  97 
> >  .../caps_4.0.0.x86_64.replies |  97 
> >  .../caps_4.1.0.x86_64.replies |  89 ++
> >  .../caps_4.2.0.x86_64.replies |  89 ++
> >  .../caps_5.0.0.x86_64.replies |  89 ++
> >  .../caps_5.1.0.x86_64.replies |  89 ++
> >  .../caps_5.2.0.x86_64.replies |  89 ++
> >  .../caps_6.0.0.x86_64.replies |  89 ++
> >  .../caps_6.1.0.x86_64.replies |  89 ++
> >  .../caps_6.2.0.x86_64.replies | 109 ++
> >  .../caps_6.2.0.x86_64.xml |   8 ++
> >  18 files changed, 895 insertions(+), 263 deletions(-)
> 
> Under the above conditions:
> 
> Reviewed-by: Peter Krempa 
> 

Regards,
Daniel
-- 
|: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o-https://fstop138.berrange.com :|
|: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|



Re: [libvirt PATCH v2 11/12] qemu: probe for sev-guest.kernel-hashes property

2021-12-10 Thread Peter Krempa
On Fri, Dec 10, 2021 at 11:37:34 +, Daniel P. Berrangé wrote:
> This sev-guest object property indicates whether QEMU should
> expose the kernel, ramdisk, cmdline hashes to the firmware
> for measurement.
> 
> The 6.2.0 capabilities are hacked to look as if they were
> generated with sev-guest support.

The qemu-6.2 lifecycle is not ended yet, so I'll be re-generating the
caps, thus your hack will get lost.

Given that qemu is at rc4 now you can either wait until the final
release is out and I update the caps or pick a different older version
to hack.

> Signed-off-by: Daniel P. Berrangé 
> ---
>  src/qemu/qemu_capabilities.c  |   8 ++
>  src/qemu/qemu_capabilities.h  |   1 +
>  .../domaincapsdata/qemu_6.2.0-q35.x86_64.xml  |   7 +-
>  .../domaincapsdata/qemu_6.2.0-tcg.x86_64.xml  |   7 +-
>  tests/domaincapsdata/qemu_6.2.0.x86_64.xml|   7 +-
>  .../caps_2.12.0.x86_64.replies|  97 
>  .../caps_3.0.0.x86_64.replies |  97 
>  .../caps_3.1.0.x86_64.replies |  97 
>  .../caps_4.0.0.x86_64.replies |  97 
>  .../caps_4.1.0.x86_64.replies |  89 ++
>  .../caps_4.2.0.x86_64.replies |  89 ++
>  .../caps_5.0.0.x86_64.replies |  89 ++
>  .../caps_5.1.0.x86_64.replies |  89 ++
>  .../caps_5.2.0.x86_64.replies |  89 ++
>  .../caps_6.0.0.x86_64.replies |  89 ++
>  .../caps_6.1.0.x86_64.replies |  89 ++
>  .../caps_6.2.0.x86_64.replies | 109 ++
>  .../caps_6.2.0.x86_64.xml |   8 ++
>  18 files changed, 895 insertions(+), 263 deletions(-)

Under the above conditions:

Reviewed-by: Peter Krempa 



Re: [libvirt PATCH v2 10/12] conf: add support for setting SEV kernel hashes

2021-12-10 Thread Peter Krempa
On Fri, Dec 10, 2021 at 11:37:33 +, Daniel P. Berrangé wrote:
> Normally the SEV measurement only covers the firmware
> loader contents. When doing a direct kernel boot, however,
> with new enough OVMF it is possible to ask for the
> measurement to cover the kernel, ramdisk and command line.
> 
> It can't be done automatically as that would break existing
> guests using direct kernel boot with old firmware, so there
> is a new XML setting allowing this behaviour to be toggled.
> 
> Signed-off-by: Daniel P. Berrangé 
> ---
>  docs/formatdomain.rst | 7 ++-
>  docs/schemas/domaincommon.rng | 5 +
>  src/conf/domain_conf.c| 8 
>  src/conf/domain_conf.h| 1 +
>  4 files changed, 20 insertions(+), 1 deletion(-)

Reviewed-by: Peter Krempa 



Re: [libvirt PATCH v2 09/12] qemu: report max number of SEV guests

2021-12-10 Thread Peter Krempa
On Fri, Dec 10, 2021 at 11:37:32 +, Daniel P. Berrangé wrote:
> Different CPU generations have different limits on the number
> of SEV/SEV-ES guests that can be run. Since both limits come
> from the same overall set, there is typically also BIOS config
> to set the tradeoff betweeen SEV and SEV-ES guest limits.
> 
> This is important information to expose for a mgmt application
> scheduling guests to hosts.
> 
> Signed-off-by: Daniel P. Berrangé 
> ---
>  src/qemu/qemu_capabilities.c  | 38 +++
>  src/qemu/qemu_driver.c| 10 +
>  .../domaincapsdata/qemu_2.12.0-q35.x86_64.xml |  2 +-
>  .../domaincapsdata/qemu_2.12.0-tcg.x86_64.xml |  2 +-
>  tests/domaincapsdata/qemu_2.12.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 +-
>  8 files changed, 54 insertions(+), 6 deletions(-)
> 
> diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
> index 4ffd0a98a2..456ce1b72e 100644
> --- a/src/qemu/qemu_capabilities.c
> +++ b/src/qemu/qemu_capabilities.c
> @@ -1897,6 +1897,8 @@ virQEMUCapsSEVInfoCopy(virSEVCapability **dst,
>  
>  tmp->cbitpos = src->cbitpos;
>  tmp->reduced_phys_bits = src->reduced_phys_bits;
> +tmp->max_guests = src->max_guests;
> +tmp->max_es_guests = src->max_es_guests;
>  
>  *dst = g_steal_pointer();
>  return 0;
> @@ -3286,6 +3288,30 @@ virQEMUCapsProbeQMPGICCapabilities(virQEMUCaps 
> *qemuCaps,
>  }
>  
>  
> +static void
> +virQEMUCapsGetSEVMaxGuests(virSEVCapability *caps)
> +{
> +# if __x86_64__

cppi: /home/pipo/libvirt/src/qemu/qemu_capabilities.c: line 3294: not properly 
indented


> +uint32_t eax, ebx, ecx, edx;
> +asm("xor %%ebx, %%ebx;" /* clear the other registers as some cpuid */
> +"xor %%edx, %%edx;" /* functions may use them as additional 
> arguments */
> +"cpuid;"
> +: "=a" (eax),
> +  "=b" (ebx),

Since the code doesn't use 'eax' and 'ebx' you can remove it and add it
to the clobbers section along with "cc".


> +  "=c" (ecx),
> +  "=d" (edx)
> +: "0" (0x801F),
> +  "c" (0)
> +: "cc");
> +

A comment what the data in 'ecx' and 'edx' is would be helpful even when
it's obvious on a second look

> +caps->max_guests = ecx - edx + 1;
> +caps->max_es_guests = edx - 1;
> +# else
> +VIR_WARN("Unexpectedly asked for SEV guest count on non-x86_64 arch");
> +caps->max_guests = caps->max_es_guests = 0;
> +# endif
> +}
> +
>  static int
>  virQEMUCapsProbeQMPSEVCapabilities(virQEMUCaps *qemuCaps,
> qemuMonitor *mon)
> @@ -3305,6 +3331,8 @@ virQEMUCapsProbeQMPSEVCapabilities(virQEMUCaps 
> *qemuCaps,
>  return 0;
>  }
>  
> +virQEMUCapsGetSEVMaxGuests(caps);

This code ...

> +
>  virSEVCapabilitiesFree(qemuCaps->sevCapabilities);
>  qemuCaps->sevCapabilities = caps;
>  return 0;
> @@ -4084,6 +4112,14 @@ virQEMUCapsParseSEVInfo(virQEMUCaps *qemuCaps, 
> xmlXPathContextPtr ctxt)
>  return -1;
>  }
>  
> +
> +/* We probe this every time because the values
> + * can change on every reboot via firmware
> + * config tunables. It is cheap to query so
> + * lack of caching is a non-issue
> + */
> +virQEMUCapsGetSEVMaxGuests(sev);

... and this code is executed also in context of e.g.
qemudomaincapstest, so the results are changing based on where you run
it, e.g. as on my box:

-  15
+  509


So this method definitely is not suitable for implementation as in this
patch.

Since we already have code digging trhough 'cpuid' it feels that it
should be a better place to do so.



Re: [libvirt PATCH] remote: Avoid crash in remoteSplitURIScheme()

2021-12-10 Thread Daniel P . Berrangé
On Fri, Dec 10, 2021 at 06:22:04AM -0800, Andrea Bolognani wrote:
> On Fri, Dec 10, 2021 at 02:06:18PM +, Daniel P. Berrangé wrote:
> > On Fri, Dec 10, 2021 at 05:47:41AM -0800, Andrea Bolognani wrote:
> > > I entertained the thought of adding the check to virURIParse()
> > > directly, because I can't think of a scenario where having a NULL
> > > scheme would be considered valid. But that seemed like a change that
> > > had the potential to break unrelated stuff, so I cowardly decided to
> > > go with the safe version instead O:-)
> >
> > We've supported URIs without a scheme in the past. IIRC, we allowed
> > a bath path to a UNIX socket for the original Xen driver. That
> > code is deleted now of course.
> 
> So do you think it would be possible to perform more strict
> validation in virURIParse() and reject this kind of wonky input
> outright at this point?

Probably, though calling it wonky input is a bit misleading. It
is valid from a URI pov, it is just that libvirt doesn't need
this ability to omit the scheme. I'd want to double check all
the callers of virURIParse to be sure first though

Regards,
Daniel
-- 
|: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o-https://fstop138.berrange.com :|
|: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|



Re: [libvirt PATCH] remote: Avoid crash in remoteSplitURIScheme()

2021-12-10 Thread Andrea Bolognani
On Fri, Dec 10, 2021 at 02:06:18PM +, Daniel P. Berrangé wrote:
> On Fri, Dec 10, 2021 at 05:47:41AM -0800, Andrea Bolognani wrote:
> > I entertained the thought of adding the check to virURIParse()
> > directly, because I can't think of a scenario where having a NULL
> > scheme would be considered valid. But that seemed like a change that
> > had the potential to break unrelated stuff, so I cowardly decided to
> > go with the safe version instead O:-)
>
> We've supported URIs without a scheme in the past. IIRC, we allowed
> a bath path to a UNIX socket for the original Xen driver. That
> code is deleted now of course.

So do you think it would be possible to perform more strict
validation in virURIParse() and reject this kind of wonky input
outright at this point?

-- 
Andrea Bolognani / Red Hat / Virtualization




Re: [libvirt PATCH] remote: Avoid crash in remoteSplitURIScheme()

2021-12-10 Thread Daniel P . Berrangé
On Fri, Dec 10, 2021 at 05:47:41AM -0800, Andrea Bolognani wrote:
> On Fri, Dec 10, 2021 at 11:31:19AM +0100, Peter Krempa wrote:
> > On Fri, Dec 10, 2021 at 10:59:27 +0100, Andrea Bolognani wrote:
> > > @@ -69,7 +69,15 @@ remoteSplitURIScheme(virURI *uri,
> > >   char **driver,
> > >   remoteDriverTransport *transport)
> > >  {
> > > -char *p = strchr(uri->scheme, '+');
> > > +char *p = NULL;
> > > +
> > > +if (!uri->scheme) {
> > > +virReportError(VIR_ERR_INVALID_ARG, "%s",
> > > +   _("missing scheme for URI"));
> >
> > The other place which leads to the call of this helper 
> > (virConnectOpenInternal)
> > uses the following error to reject the uri if scheme is missing:
> >
> > virReportError(VIR_ERR_NO_CONNECT,
> >_("URI '%s' does not include a driver name"),
> >name);
> 
> Yeah, it seems safer to catch the issue inside the helper than
> requiring the callers to perform the check ahead of time. It's okay
> for virConnectOpen() to have a nicer error message, as it's the one
> that people are more likely to see.

Yes, this is something I simply overlooked when refactoring
the code. The check should clearly be in this common helper.

> I entertained the thought of adding the check to virURIParse()
> directly, because I can't think of a scenario where having a NULL
> scheme would be considered valid. But that seemed like a change that
> had the potential to break unrelated stuff, so I cowardly decided to
> go with the safe version instead O:-)

We've supported URIs without a scheme in the past. IIRC, we allowed
a bath path to a UNIX socket for the original Xen driver. That
code is deleted now of course.

Regards,
Daniel
-- 
|: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o-https://fstop138.berrange.com :|
|: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|



Re: [libvirt PATCH v2 08/12] include: define parameters for reporting SEV guest limits

2021-12-10 Thread Peter Krempa
On Fri, Dec 10, 2021 at 11:37:31 +, Daniel P. Berrangé wrote:
> There are limits on the number of SEV/SEV-ES guests that can
> be run on machines, which may be influenced by firmware
> settings. This is important to expose to users.
> 
> Signed-off-by: Daniel P. Berrangé 
> ---
>  include/libvirt/libvirt-host.h | 16 
>  1 file changed, 16 insertions(+)

As noted before, it's a shame that we don't cross-link these macros with
the API function in any autmatic way.

Reviewed-by: Peter Krempa 



Re: [libvirt PATCH v2 07/12] conf: extend domain capabilities for max SEV guest count

2021-12-10 Thread Peter Krempa
On Fri, Dec 10, 2021 at 11:37:30 +, Daniel P. Berrangé wrote:
> There are limits on the number of SEV/SEV-ES guests that can
> be run on machines, which may be influenced by firmware
> settings. This is important to expose to users.
> 
> Signed-off-by: Daniel P. Berrangé 
> ---
>  docs/formatdomaincaps.html.in   | 6 ++
>  docs/schemas/domaincaps.rng | 6 ++
>  src/conf/domain_capabilities.c  | 4 
>  src/conf/domain_capabilities.h  | 2 ++
>  tests/domaincapsdata/qemu_2.12.0-q35.x86_64.xml | 2 ++
>  tests/domaincapsdata/qemu_2.12.0-tcg.x86_64.xml | 2 ++
>  tests/domaincapsdata/qemu_2.12.0.x86_64.xml | 2 ++
>  tests/domaincapsdata/qemu_6.0.0-q35.x86_64.xml  | 2 ++
>  tests/domaincapsdata/qemu_6.0.0-tcg.x86_64.xml  | 2 ++
>  tests/domaincapsdata/qemu_6.0.0.x86_64.xml  | 2 ++
>  10 files changed, 30 insertions(+)

Reviewed-by: Peter Krempa 



Re: [libvirt PATCH v2 06/12] tools: add 'nodesevinfo' virsh command

2021-12-10 Thread Peter Krempa
On Fri, Dec 10, 2021 at 11:37:29 +, Daniel P. Berrangé wrote:
> While some SEV info is reported in the domain capabilities,
> for reasons of size, this excludes the certificates. The
> nodesevinfo command provides the full set of information.
> 
> Signed-off-by: Daniel P. Berrangé 
> ---
>  docs/manpages/virsh.rst | 14 +
>  tools/virsh-host.c  | 45 +
>  2 files changed, 59 insertions(+)
> 
> diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst
> index 1a74217625..e828f7ef68 100644
> --- a/docs/manpages/virsh.rst
> +++ b/docs/manpages/virsh.rst
> @@ -479,6 +479,20 @@ Returns memory stats of the node.
>  If *cell* is specified, this will print the specified cell statistics only.
>  
>  
> +nodesevinfo
> +---
> +
> +**Syntax:**
> +
> +::
> +
> +   nodesevinfo
> +
> +Reports information about the AMD SEV launch security features for
> +the node, if any. Some of this information is also reported in the
> +domain capabilities XML document.

In this instance it wouldbe IMO higly beneficial to mention the
individual macros [1] that can be returned in the API docs:

https://www.libvirt.org/html/libvirt-libvirt-host.html#virNodeGetSEVInfo

And link to the API docs here. Duplicating the docs isn't great but not
documenting what you get isn't either.


[1]:
https://www.libvirt.org/html/libvirt-libvirt-host.html#VIR_NODE_SEV_CBITPOS
https://www.libvirt.org/html/libvirt-libvirt-host.html#VIR_NODE_SEV_CERT_CHAIN
https://www.libvirt.org/html/libvirt-libvirt-host.html#VIR_NODE_SEV_PDH
https://www.libvirt.org/html/libvirt-libvirt-host.html#VIR_NODE_SEV_REDUCED_PHYS_BITS

(It's unfortunate that these don't have a common anchor to link to)


Reviewed-by: Peter Krempa 



Re: [libvirt PATCH v2 05/12] tools: add 'domlaunchsecinfo' virsh command

2021-12-10 Thread Peter Krempa
On Fri, Dec 10, 2021 at 11:37:28 +, Daniel P. Berrangé wrote:
> This command reports the launch security parameters for
> a guest, allowing an external tool to perform a launch
> attestation.
> 
> Signed-off-by: Daniel P. Berrangé 
> ---
>  docs/manpages/virsh.rst | 17 +
>  tools/virsh-domain.c| 53 +
>  2 files changed, 70 insertions(+)
> 
> diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst
> index 275f416090..1a74217625 100644
> --- a/docs/manpages/virsh.rst
> +++ b/docs/manpages/virsh.rst
> @@ -2057,6 +2057,23 @@ destination hosts have synchronized time (i.e., NTP 
> daemon is running
>  on both of them).
>  
>  
> +domlaunchsecinfo
> +
> +
> +**Syntax:**
> +
> +::
> +
> +   domlaunchsecinfo domain
> +
> +Returns information about the launch security parameters associated
> +with a running domain.
> +
> +The set of parameters reported will vary depending on which type of
> +launch security protection is active. If none is active, no parameters
> +will be reported.

Too bad that 
https://www.libvirt.org/html/libvirt-libvirt-domain.html#virDomainGetLaunchSecurityInfo
doesn't link to all the fields it returns because in case of commands
such as this one it would be beneficial to at least link to the API docs
outlining what the values are.

Reviewed-by: Peter Krempa 



Re: [libvirt PATCH] remote: Avoid crash in remoteSplitURIScheme()

2021-12-10 Thread Andrea Bolognani
On Fri, Dec 10, 2021 at 11:31:19AM +0100, Peter Krempa wrote:
> On Fri, Dec 10, 2021 at 10:59:27 +0100, Andrea Bolognani wrote:
> > @@ -69,7 +69,15 @@ remoteSplitURIScheme(virURI *uri,
> >   char **driver,
> >   remoteDriverTransport *transport)
> >  {
> > -char *p = strchr(uri->scheme, '+');
> > +char *p = NULL;
> > +
> > +if (!uri->scheme) {
> > +virReportError(VIR_ERR_INVALID_ARG, "%s",
> > +   _("missing scheme for URI"));
>
> The other place which leads to the call of this helper 
> (virConnectOpenInternal)
> uses the following error to reject the uri if scheme is missing:
>
> virReportError(VIR_ERR_NO_CONNECT,
>_("URI '%s' does not include a driver name"),
>name);

Yeah, it seems safer to catch the issue inside the helper than
requiring the callers to perform the check ahead of time. It's okay
for virConnectOpen() to have a nicer error message, as it's the one
that people are more likely to see.

I entertained the thought of adding the check to virURIParse()
directly, because I can't think of a scenario where having a NULL
scheme would be considered valid. But that seemed like a change that
had the potential to break unrelated stuff, so I cowardly decided to
go with the safe version instead O:-)

> It looks like it's unlikely that anybody would use virt-ssh-helper
> manually though.

Absolutely! But it's still in the default $PATH, and not crashing
when passed invalid arguments is what I would consider the bare
minimum :)

Thanks for the review!

-- 
Andrea Bolognani / Red Hat / Virtualization



Re: [PATCH] Revert "lxc: controller: Fix container launch on cgroup v1"

2021-12-10 Thread Pavel Hrdina
On Fri, Dec 10, 2021 at 01:48:43PM +0100, Michal Privoznik wrote:
> Unfortunately, this fix breakes machinectl in a very nasty way,
> for instance 'machinectl shell' drops into the host shell. It's
> worse than being unable to start a container with CGroupsV1.
> 
> Revert until a proper fix is figured out.
> 
> This reverts commit 1b9ce05ce241a581d4e80228c92ceb0266f21f94.
> 
> Signed-off-by: Michal Privoznik 
> ---
>  src/lxc/lxc_controller.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

Reviewed-by: Pavel Hrdina 


signature.asc
Description: PGP signature


Re: [libvirt PATCH v2 03/12] qemu: add monitor APIs for query-sev

2021-12-10 Thread Peter Krempa
On Fri, Dec 10, 2021 at 11:37:26 +, Daniel P. Berrangé wrote:
> We're only returning the set of fields needed to perform an
> attestation, per the SEV API docs.
> 
> Signed-off-by: Daniel P. Berrangé 
> ---
>  src/qemu/qemu_monitor.c  | 13 ++
>  src/qemu/qemu_monitor.h  |  9 +++
>  src/qemu/qemu_monitor_json.c | 46 
>  src/qemu/qemu_monitor_json.h |  9 +++
>  tests/qemumonitorjsontest.c  | 43 +
>  5 files changed, 120 insertions(+)

Reviewed-by: Peter Krempa 



Re: Issue labe improvements

2021-12-10 Thread Michal Prívozník
On 12/8/21 16:34, Peter Krempa wrote:
> Hi,
> 

Should we also have a label for regression? Either if an issue needs to
be re-opened or if filed new and captures something that used to work.

On the other hand, it can be simulated by setting bug + critical labels.

Michal



[PATCH] Revert "lxc: controller: Fix container launch on cgroup v1"

2021-12-10 Thread Michal Privoznik
Unfortunately, this fix breakes machinectl in a very nasty way,
for instance 'machinectl shell' drops into the host shell. It's
worse than being unable to start a container with CGroupsV1.

Revert until a proper fix is figured out.

This reverts commit 1b9ce05ce241a581d4e80228c92ceb0266f21f94.

Signed-off-by: Michal Privoznik 
---
 src/lxc/lxc_controller.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c
index 039efcd7c7..7c593ee3a9 100644
--- a/src/lxc/lxc_controller.c
+++ b/src/lxc/lxc_controller.c
@@ -865,12 +865,12 @@ static int 
virLXCControllerSetupCgroupLimits(virLXCController *ctrl)
 nodeset = virDomainNumatuneGetNodeset(ctrl->def->numa, auto_nodeset, -1);
 
 if (!(ctrl->cgroup = virLXCCgroupCreate(ctrl->def,
-getpid(),
+ctrl->initpid,
 ctrl->nnicindexes,
 ctrl->nicindexes)))
 goto cleanup;
 
-if (virCgroupAddMachineProcess(ctrl->cgroup, ctrl->initpid) < 0)
+if (virCgroupAddMachineProcess(ctrl->cgroup, getpid()) < 0)
 goto cleanup;
 
 /* Add all qemu-nbd tasks to the cgroup */
-- 
2.32.0



Re: [PATCH 2/2] Revert "qemu: Avoid crash in qemuStateShutdownPrepare() and qemuStateShutdownWait()"

2021-12-10 Thread Peter Krempa
On Thu, Dec 09, 2021 at 15:43:56 +0100, Michal Privoznik wrote:
> This reverts commit 69977ff10560a80bcf5bf93f1a3f819a2d1623ca.
> 
> After previous commit it's no longer possible that QEMU driver is
> not initialized in qemuStateShutdownPrepare() nor
> qemuStateShutdownWait().
> 
> Signed-off-by: Michal Privoznik 
> ---
>  src/qemu/qemu_driver.c | 6 --
>  1 file changed, 6 deletions(-)

Reviewed-by: Peter Krempa 



Re: [PATCH 1/2] remote_daemon: Set shutdown callbacks only after init is done

2021-12-10 Thread Peter Krempa
On Thu, Dec 09, 2021 at 15:43:55 +0100, Michal Privoznik wrote:
> The initialization of drivers happens in a separate thread.
> However, the main thread continues initialization and sets
> shutdown callbacks (virStateShutdownPrepare() and
> virStateShutdownWait()) even though the driver init thread is
> still running. This is dangerous because if the daemon decides to
> quit early (e.g. because SIGINT was delivered) the
> shutdownPrepare and shutdownWait callback are called over
> partially init drivers.
> 
> Set callbacks only after all drivers were initialized.
> 
> Resolves: https://gitlab.com/libvirt/libvirt/-/issues/218
> Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2027400
> 
> Signed-off-by: Michal Privoznik 
> ---
>  src/remote/remote_daemon.c | 7 ---
>  1 file changed, 4 insertions(+), 3 deletions(-)
> 
> diff --git a/src/remote/remote_daemon.c b/src/remote/remote_daemon.c
> index de43a54c2e..4e10f3ad23 100644
> --- a/src/remote/remote_daemon.c
> +++ b/src/remote/remote_daemon.c
> @@ -626,6 +626,10 @@ static void daemonRunStateInit(void *opaque)
>  
>  driversInitialized = true;
>  
> +virNetDaemonSetShutdownCallbacks(dmn,
> + virStateShutdownPrepare,
> + virStateShutdownWait);
> +

Okay so this placement ensures that the state shutdown code will only
ever be executed if the state was already initialized ...

>  /* Tie the non-privileged daemons to the session/shutdown lifecycle */
>  if (!virNetDaemonIsPrivileged(dmn)) {
>  
> @@ -1214,9 +1218,6 @@ int main(int argc, char **argv) {
>  #endif
>  
>  /* Run event loop. */
> -virNetDaemonSetShutdownCallbacks(dmn,
> - virStateShutdownPrepare,
> - virStateShutdownWait);

... which wasn't always true here.

>  virNetDaemonRun(dmn);
>  
>  ret = 0;

So at this point it's still possible that the daemon will quit without
the callbacks being called, but tat was possible even before.

Based on the above and the fact that I wasn't able to reproduce the
crash:

Reviewed-by: Peter Krempa 



Re: [PATCH V2 0/3] Add virDomainSetLaunchSecurityState API

2021-12-10 Thread Daniel P . Berrangé
On Fri, Dec 10, 2021 at 09:48:00AM +0100, Peter Krempa wrote:
> On Thu, Dec 09, 2021 at 15:04:12 -0700, Jim Fehlig wrote:
> > V2 of 
> > https://listman.redhat.com/archives/libvir-list/2021-November/msg00980.html
> > 
> > Like V1, this series is compile-tested only. I plan to work on functional
> > testing soon, after wrapping up some tasks.
> 
> I have 2 minor comments:
> 
> - virsh impl is missing and it's not justified why

virsh is missing for all the sev related commands, but I've just
addressed that in my series, so agree it makes sense to add in
this series too.

> - 'qemuMonitorJSONSetLaunchSecurityState' is missing a test case in
>   qemumonitorjsontest. A simple test with GEN_TEST_FUNC/DO_TEST_GEN is
>   enough, it validates the arguments against the QMP monitor schema.

Regards,
Daniel
-- 
|: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o-https://fstop138.berrange.com :|
|: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|



Re: [PATCH V2 3/3] qemu: Implement the virDomainSetLaunchSecurityState API

2021-12-10 Thread Daniel P . Berrangé
On Thu, Dec 09, 2021 at 03:04:15PM -0700, Jim Fehlig wrote:
> Set a launch secret in guest memory using the sev-inject-launch-secret
> QMP API. Only supported for SEV-enabled guests in a paused state.
> 
> Signed-off-by: Jim Fehlig 
> ---
>  src/qemu/qemu_driver.c   | 88 
>  src/qemu/qemu_monitor.c  | 14 ++
>  src/qemu/qemu_monitor.h  |  7 +++
>  src/qemu/qemu_monitor_json.c | 45 ++
>  src/qemu/qemu_monitor_json.h |  6 +++
>  5 files changed, 160 insertions(+)

LGTM aside from the tests thing Peter mentions


Regards,
Daniel
-- 
|: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o-https://fstop138.berrange.com :|
|: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|



Re: [PATCH V2 1/3] libvirt: Introduce virDomainSetLaunchSecurityState public API

2021-12-10 Thread Daniel P . Berrangé
On Thu, Dec 09, 2021 at 03:04:13PM -0700, Jim Fehlig wrote:
> This API allows setting a launch secret within a guests's memory. The
> launch secret is created by the guest owner after retrieving and
> verifying the launch measurement with virDomainGetLaunchSecurityInfo.
> 
> The API uses virTypedParameter for input, allowing it to be expanded
> to support other confidential computing technologies. In the case of
> SEV, a basic guest launch workflow is described in the SEV API spec
> in section "1.3.1 Launch"
> 
> https://www.amd.com/system/files/TechDocs/55766_SEV-KM_API_Specification.pdf
> 
> Signed-off-by: Jim Fehlig 
> ---
>  include/libvirt/libvirt-domain.h | 35 ++
>  src/driver-hypervisor.h  |  7 
>  src/libvirt-domain.c | 62 
>  src/libvirt_public.syms  |  5 +++
>  4 files changed, 109 insertions(+)

Reviewed-by: Daniel P. Berrangé 


Regards,
Daniel
-- 
|: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o-https://fstop138.berrange.com :|
|: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|



[libvirt PATCH v2 11/12] qemu: probe for sev-guest.kernel-hashes property

2021-12-10 Thread Daniel P . Berrangé
This sev-guest object property indicates whether QEMU should
expose the kernel, ramdisk, cmdline hashes to the firmware
for measurement.

The 6.2.0 capabilities are hacked to look as if they were
generated with sev-guest support.

Signed-off-by: Daniel P. Berrangé 
---
 src/qemu/qemu_capabilities.c  |   8 ++
 src/qemu/qemu_capabilities.h  |   1 +
 .../domaincapsdata/qemu_6.2.0-q35.x86_64.xml  |   7 +-
 .../domaincapsdata/qemu_6.2.0-tcg.x86_64.xml  |   7 +-
 tests/domaincapsdata/qemu_6.2.0.x86_64.xml|   7 +-
 .../caps_2.12.0.x86_64.replies|  97 
 .../caps_3.0.0.x86_64.replies |  97 
 .../caps_3.1.0.x86_64.replies |  97 
 .../caps_4.0.0.x86_64.replies |  97 
 .../caps_4.1.0.x86_64.replies |  89 ++
 .../caps_4.2.0.x86_64.replies |  89 ++
 .../caps_5.0.0.x86_64.replies |  89 ++
 .../caps_5.1.0.x86_64.replies |  89 ++
 .../caps_5.2.0.x86_64.replies |  89 ++
 .../caps_6.0.0.x86_64.replies |  89 ++
 .../caps_6.1.0.x86_64.replies |  89 ++
 .../caps_6.2.0.x86_64.replies | 109 ++
 .../caps_6.2.0.x86_64.xml |   8 ++
 18 files changed, 895 insertions(+), 263 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 456ce1b72e..fbcb67713e 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -652,6 +652,7 @@ VIR_ENUM_IMPL(virQEMUCaps,
   "device.json", /* QEMU_CAPS_DEVICE_JSON */
   "query-dirty-rate", /* QEMU_CAPS_QUERY_DIRTY_RATE */
   "rbd-encryption", /* QEMU_CAPS_RBD_ENCRYPTION */
+  "sev-guest-kernel-hashes", /* QEMU_CAPS_SEV_GUEST_KERNEL_HASHES 
*/
 );
 
 
@@ -1718,6 +1719,10 @@ static struct virQEMUCapsStringFlags 
virQEMUCapsObjectPropsMaxCPU[] = {
 { "migratable", QEMU_CAPS_CPU_MIGRATABLE },
 };
 
+static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsSEVGuest[] = {
+{ "kernel-hashes", QEMU_CAPS_SEV_GUEST_KERNEL_HASHES },
+};
+
 static virQEMUCapsObjectTypeProps virQEMUCapsObjectProps[] = {
 { "memory-backend-file", virQEMUCapsObjectPropsMemoryBackendFile,
   G_N_ELEMENTS(virQEMUCapsObjectPropsMemoryBackendFile),
@@ -1731,6 +1736,9 @@ static virQEMUCapsObjectTypeProps 
virQEMUCapsObjectProps[] = {
 { "max-arm-cpu", virQEMUCapsObjectPropsMaxCPU,
   G_N_ELEMENTS(virQEMUCapsObjectPropsMaxCPU),
   QEMU_CAPS_ARM_MAX_CPU },
+{ "sev-guest", virQEMUCapsObjectPropsSEVGuest,
+  G_N_ELEMENTS(virQEMUCapsObjectPropsSEVGuest),
+  QEMU_CAPS_SEV_GUEST },
 };
 
 static struct virQEMUCapsStringFlags virQEMUCapsMachinePropsPSeries[] = {
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 716e09123c..aaac20a834 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -631,6 +631,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for 
syntax-check */
 QEMU_CAPS_DEVICE_JSON, /* -device accepts JSON */
 QEMU_CAPS_QUERY_DIRTY_RATE, /* accepts query-dirty-rate */
 QEMU_CAPS_RBD_ENCRYPTION, /* Ceph RBD encryption support */
+QEMU_CAPS_SEV_GUEST_KERNEL_HASHES, /* sev-guest.kernel-hashes= */
 
 QEMU_CAPS_LAST /* this must always be the last item */
 } virQEMUCapsFlags;
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 9d68c0a404..28d4f38fef 100644
--- a/tests/domaincapsdata/qemu_6.2.0-q35.x86_64.xml
+++ b/tests/domaincapsdata/qemu_6.2.0-q35.x86_64.xml
@@ -225,6 +225,11 @@
 
 
 
-
+
+  47
+  1
+  15
+  0
+
   
 
diff --git a/tests/domaincapsdata/qemu_6.2.0-tcg.x86_64.xml 
b/tests/domaincapsdata/qemu_6.2.0-tcg.x86_64.xml
index 8db840faac..711a77ccd1 100644
--- a/tests/domaincapsdata/qemu_6.2.0-tcg.x86_64.xml
+++ b/tests/domaincapsdata/qemu_6.2.0-tcg.x86_64.xml
@@ -231,6 +231,11 @@
 
 
 
-
+
+  47
+  1
+  15
+  0
+
   
 
diff --git a/tests/domaincapsdata/qemu_6.2.0.x86_64.xml 
b/tests/domaincapsdata/qemu_6.2.0.x86_64.xml
index 0f89790b60..b0fb1e11cd 100644
--- a/tests/domaincapsdata/qemu_6.2.0.x86_64.xml
+++ b/tests/domaincapsdata/qemu_6.2.0.x86_64.xml
@@ -225,6 +225,11 @@
 
 
 
-
+
+  47
+  1
+  15
+  0
+
   
 
diff --git a/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.replies 
b/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.replies
index 5fefbc64ab..c5bdd5398b 100644
--- a/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.replies
+++ b/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.replies
@@ -17361,10 +17361,59 @@
 }
 
 {
-  "execute": "query-machines",
+  "execute": "qom-list-properties",
+  "arguments": {
+"typename": 

[libvirt PATCH v2 12/12] qemu: format sev-guest.kernel-hashes property

2021-12-10 Thread Daniel P . Berrangé
Set the kernel-hashes property on the sev-guest object if
the config asked for it explicitly. While QEMU machine
types currently default to having this setting off, it
is not guaranteed to remain this way.

Signed-off-by: Daniel P. Berrangé 
---
 src/qemu/qemu_command.c   |  7 
 src/qemu/qemu_validate.c  |  8 
 ...unch-security-sev-direct.x86_64-6.2.0.args | 40 +++
 .../launch-security-sev-direct.xml| 39 ++
 tests/qemuxml2argvtest.c  |  1 +
 5 files changed, 95 insertions(+)
 create mode 100644 
tests/qemuxml2argvdata/launch-security-sev-direct.x86_64-6.2.0.args
 create mode 100644 tests/qemuxml2argvdata/launch-security-sev-direct.xml

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index c47998aabd..6999afe5aa 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -10112,6 +10112,13 @@ qemuBuildSEVCommandLine(virDomainObj *vm, virCommand 
*cmd,
  NULL) < 0)
 return -1;
 
+if (sev->kernel_hashes != VIR_TRISTATE_BOOL_ABSENT) {
+bool val;
+virTristateBoolToBool(sev->kernel_hashes, );
+if (virJSONValueObjectAppendBoolean(props, "kernel-hashes", val) < 0)
+return -1;
+}
+
 if (qemuBuildObjectCommandlineFromJSON(cmd, props, priv->qemuCaps) < 0)
 return -1;
 
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index 29b01495ad..0150b0f082 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -1200,6 +1200,14 @@ qemuValidateDomainDef(const virDomainDef *def,
  "this QEMU binary"));
 return -1;
 }
+
+if (def->sec->data.sev.kernel_hashes == VIR_TRISTATE_BOOL_YES &&
+!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SEV_GUEST_KERNEL_HASHES)) {
+virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+   _("SEV launch security measured direct kernel "
+ "boot is not supported with this QEMU 
binary"));
+return -1;
+}
 break;
 case VIR_DOMAIN_LAUNCH_SECURITY_PV:
 if (!virQEMUCapsGet(qemuCaps, 
QEMU_CAPS_MACHINE_CONFIDENTAL_GUEST_SUPPORT) ||
diff --git 
a/tests/qemuxml2argvdata/launch-security-sev-direct.x86_64-6.2.0.args 
b/tests/qemuxml2argvdata/launch-security-sev-direct.x86_64-6.2.0.args
new file mode 100644
index 00..0062faa06c
--- /dev/null
+++ b/tests/qemuxml2argvdata/launch-security-sev-direct.x86_64-6.2.0.args
@@ -0,0 +1,40 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/tmp/lib/domain--1-QEMUGuest1 \
+USER=test \
+LOGNAME=test \
+XDG_DATA_HOME=/tmp/lib/domain--1-QEMUGuest1/.local/share \
+XDG_CACHE_HOME=/tmp/lib/domain--1-QEMUGuest1/.cache \
+XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest1/.config \
+/usr/bin/qemu-system-x86_64 \
+-name guest=QEMUGuest1,debug-threads=on \
+-S \
+-object 
'{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/tmp/lib/domain--1-QEMUGuest1/master-key.aes"}'
 \
+-machine 
pc-i440fx-6.2,usb=off,dump-guest-core=off,confidential-guest-support=lsec0,memory-backend=pc.ram
 \
+-accel kvm \
+-cpu qemu64 \
+-m 214 \
+-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 \
+-display none \
+-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-shutdown \
+-no-acpi \
+-boot strict=on \
+-kernel /vmlinuz \
+-initrd /initrd \
+-append runme \
+-device 
'{"driver":"piix3-usb-uhci","id":"usb","bus":"pci.0","addr":"0x1.0x2"}' \
+-blockdev 
'{"driver":"host_device","filename":"/dev/HostVG/QEMUGuest1","node-name":"libvirt-1-storage","auto-read-only":true,"discard":"unmap"}'
 \
+-blockdev 
'{"node-name":"libvirt-1-format","read-only":false,"driver":"raw","file":"libvirt-1-storage"}'
 \
+-device 
'{"driver":"ide-hd","bus":"ide.0","unit":0,"drive":"libvirt-1-format","id":"ide0-0-0","bootindex":1}'
 \
+-audiodev '{"id":"audio1","driver":"none"}' \
+-object 
'{"qom-type":"sev-guest","id":"lsec0","cbitpos":47,"reduced-phys-bits":1,"policy":1,"dh-cert-file":"/tmp/lib/domain--1-QEMUGuest1/dh_cert.base64","session-file":"/tmp/lib/domain--1-QEMUGuest1/session.base64","kernel-hashes":true}'
 \
+-sandbox 
on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
+-msg timestamp=on
diff --git a/tests/qemuxml2argvdata/launch-security-sev-direct.xml 
b/tests/qemuxml2argvdata/launch-security-sev-direct.xml
new file mode 100644
index 00..80ce6412dd
--- /dev/null
+++ b/tests/qemuxml2argvdata/launch-security-sev-direct.xml
@@ -0,0 +1,39 @@
+
+  QEMUGuest1
+  c7a5fdbd-edaf-9455-926a-d65c16db1809
+  219100
+  219100
+  1
+  
+hvm
+/vmlinuz
+/initrd
+runme
+  
+  
+  

[libvirt PATCH v2 06/12] tools: add 'nodesevinfo' virsh command

2021-12-10 Thread Daniel P . Berrangé
While some SEV info is reported in the domain capabilities,
for reasons of size, this excludes the certificates. The
nodesevinfo command provides the full set of information.

Signed-off-by: Daniel P. Berrangé 
---
 docs/manpages/virsh.rst | 14 +
 tools/virsh-host.c  | 45 +
 2 files changed, 59 insertions(+)

diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst
index 1a74217625..e828f7ef68 100644
--- a/docs/manpages/virsh.rst
+++ b/docs/manpages/virsh.rst
@@ -479,6 +479,20 @@ Returns memory stats of the node.
 If *cell* is specified, this will print the specified cell statistics only.
 
 
+nodesevinfo
+---
+
+**Syntax:**
+
+::
+
+   nodesevinfo
+
+Reports information about the AMD SEV launch security features for
+the node, if any. Some of this information is also reported in the
+domain capabilities XML document.
+
+
 nodesuspend
 ---
 
diff --git a/tools/virsh-host.c b/tools/virsh-host.c
index 5da1346a9c..5ee3834de2 100644
--- a/tools/virsh-host.c
+++ b/tools/virsh-host.c
@@ -888,6 +888,45 @@ cmdNodeMemStats(vshControl *ctl, const vshCmd *cmd)
 return true;
 }
 
+/*
+ * "nodesevinfo" command
+ */
+static const vshCmdInfo info_nodesevinfo[] = {
+{.name = "help",
+ .data = N_("node SEV information")
+},
+{.name = "desc",
+ .data = N_("Returns basic SEV information about the node.")
+},
+{.name = NULL}
+};
+
+static bool
+cmdNodeSEVInfo(vshControl *ctl, const vshCmd *cmd G_GNUC_UNUSED)
+{
+virshControl *priv = ctl->privData;
+size_t i;
+int nparams = 0;
+virTypedParameterPtr params = NULL;
+bool ret = false;
+
+if (virNodeGetSEVInfo(priv->conn, , , 0) != 0) {
+vshError(ctl, "%s", _("Unable to get host SEV information"));
+goto cleanup;
+}
+
+for (i = 0; i < nparams; i++) {
+g_autofree char *str = vshGetTypedParamValue(ctl, [i]);
+vshPrint(ctl, "%-18s: %s\n", params[i].field, str);
+}
+
+ret = true;
+
+ cleanup:
+virTypedParamsFree(params, nparams);
+return ret;
+}
+
 /*
  * "nodesuspend" command
  */
@@ -1828,6 +1867,12 @@ const vshCmdDef hostAndHypervisorCmds[] = {
  .info = info_nodememstats,
  .flags = 0
 },
+{.name = "nodesevinfo",
+ .handler = cmdNodeSEVInfo,
+ .opts = NULL,
+ .info = info_nodesevinfo,
+ .flags = 0
+},
 {.name = "nodesuspend",
  .handler = cmdNodeSuspend,
  .opts = opts_node_suspend,
-- 
2.33.1



[libvirt PATCH v2 05/12] tools: add 'domlaunchsecinfo' virsh command

2021-12-10 Thread Daniel P . Berrangé
This command reports the launch security parameters for
a guest, allowing an external tool to perform a launch
attestation.

Signed-off-by: Daniel P. Berrangé 
---
 docs/manpages/virsh.rst | 17 +
 tools/virsh-domain.c| 53 +
 2 files changed, 70 insertions(+)

diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst
index 275f416090..1a74217625 100644
--- a/docs/manpages/virsh.rst
+++ b/docs/manpages/virsh.rst
@@ -2057,6 +2057,23 @@ destination hosts have synchronized time (i.e., NTP 
daemon is running
 on both of them).
 
 
+domlaunchsecinfo
+
+
+**Syntax:**
+
+::
+
+   domlaunchsecinfo domain
+
+Returns information about the launch security parameters associated
+with a running domain.
+
+The set of parameters reported will vary depending on which type of
+launch security protection is active. If none is active, no parameters
+will be reported.
+
+
 dommemstat
 --
 
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 8379f9f135..1560a8ea0d 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -9525,6 +9525,53 @@ cmdNumatune(vshControl * ctl, const vshCmd * cmd)
 goto cleanup;
 }
 
+/*
+ * "domlaunchsecinfo" command
+ */
+static const vshCmdInfo info_domlaunchsecinfo[] = {
+{.name = "help",
+ .data = N_("Get domain launch security info")
+},
+{.name = "desc",
+ .data = N_("Get the launch security parameters for a guest domain")
+},
+{.name = NULL}
+};
+
+static const vshCmdOptDef opts_domlaunchsecinfo[] = {
+VIRSH_COMMON_OPT_DOMAIN_FULL(0),
+{.name = NULL}
+};
+
+static bool
+cmdDomLaunchSecInfo(vshControl * ctl, const vshCmd * cmd)
+{
+g_autoptr(virshDomain) dom = NULL;
+size_t i;
+int nparams = 0;
+virTypedParameterPtr params = NULL;
+bool ret = false;
+
+if (!(dom = virshCommandOptDomain(ctl, cmd, NULL)))
+return false;
+
+if (virDomainGetLaunchSecurityInfo(dom, , , 0) != 0) {
+vshError(ctl, "%s", _("Unable to get launch security parameters"));
+goto cleanup;
+}
+
+for (i = 0; i < nparams; i++) {
+g_autofree char *str = vshGetTypedParamValue(ctl, [i]);
+vshPrint(ctl, "%-15s: %s\n", params[i].field, str);
+}
+
+ret = true;
+
+ cleanup:
+virTypedParamsFree(params, nparams);
+return ret;
+}
+
 /*
  * "qemu-monitor-command" command
  */
@@ -14544,6 +14591,12 @@ const vshCmdDef domManagementCmds[] = {
  .info = info_domjobinfo,
  .flags = 0
 },
+{.name = "domlaunchsecinfo",
+ .handler = cmdDomLaunchSecInfo,
+ .opts = opts_domlaunchsecinfo,
+ .info = info_domlaunchsecinfo,
+ .flags = 0
+},
 {.name = "domname",
  .handler = cmdDomname,
  .opts = opts_domname,
-- 
2.33.1



[libvirt PATCH v2 04/12] qemu: report new launch security parameters

2021-12-10 Thread Daniel P . Berrangé
Report extra info about the SEV setup, returning those fields
that are required to calculate the expected launch measurement

 HMAC(0x04 || API_MAJOR || API_MINOR || BUILD ||
  GCTX.POLICY || GCTX.LD || MNONCE; GCTX.TIK)

specified in section 6.5.1 of AMD Secure Encrypted
Virtualization API.

Reviewed-by: Peter Krempa 
Signed-off-by: Daniel P. Berrangé 
---
 src/qemu/qemu_driver.c | 43 +++---
 1 file changed, 36 insertions(+), 7 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 5bacf73003..1bf1938634 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -19977,14 +19977,19 @@ qemuNodeGetSEVInfo(virConnectPtr conn,
 
 
 static int
-qemuDomainGetSEVMeasurement(virQEMUDriver *driver,
-virDomainObj *vm,
-virTypedParameterPtr *params,
-int *nparams,
-unsigned int flags)
+qemuDomainGetSEVInfo(virQEMUDriver *driver,
+ virDomainObj *vm,
+ virTypedParameterPtr *params,
+ int *nparams,
+ unsigned int flags)
 {
 int ret = -1;
+int rv;
 g_autofree char *tmp = NULL;
+unsigned int apiMajor = 0;
+unsigned int apiMinor = 0;
+unsigned int buildID = 0;
+unsigned int policy = 0;
 int maxpar = 0;
 
 virCheckFlags(VIR_TYPED_PARAM_STRING_OKAY, -1);
@@ -20001,15 +20006,39 @@ qemuDomainGetSEVMeasurement(virQEMUDriver *driver,
 qemuDomainObjEnterMonitor(driver, vm);
 tmp = qemuMonitorGetSEVMeasurement(QEMU_DOMAIN_PRIVATE(vm)->mon);
 
+
+if (!tmp) {
+qemuDomainObjExitMonitor(driver, vm);
+goto endjob;
+}
+
+rv = qemuMonitorGetSEVInfo(QEMU_DOMAIN_PRIVATE(vm)->mon,
+   , , , );
 qemuDomainObjExitMonitor(driver, vm);
 
-if (!tmp)
+if (rv < 0)
 goto endjob;
 
 if (virTypedParamsAddString(params, nparams, ,
 VIR_DOMAIN_LAUNCH_SECURITY_SEV_MEASUREMENT,
 tmp) < 0)
 goto endjob;
+if (virTypedParamsAddUInt(params, nparams, ,
+  VIR_DOMAIN_LAUNCH_SECURITY_SEV_API_MAJOR,
+  apiMajor) < 0)
+goto endjob;
+if (virTypedParamsAddUInt(params, nparams, ,
+  VIR_DOMAIN_LAUNCH_SECURITY_SEV_API_MINOR,
+  apiMinor) < 0)
+goto endjob;
+if (virTypedParamsAddUInt(params, nparams, ,
+  VIR_DOMAIN_LAUNCH_SECURITY_SEV_BUILD_ID,
+  buildID) < 0)
+goto endjob;
+if (virTypedParamsAddUInt(params, nparams, ,
+  VIR_DOMAIN_LAUNCH_SECURITY_SEV_POLICY,
+  policy) < 0)
+goto endjob;
 
 ret = 0;
 
@@ -20037,7 +20066,7 @@ qemuDomainGetLaunchSecurityInfo(virDomainPtr domain,
 
 if (vm->def->sec &&
 vm->def->sec->sectype == VIR_DOMAIN_LAUNCH_SECURITY_SEV) {
-if (qemuDomainGetSEVMeasurement(driver, vm, params, nparams, flags) < 
0)
+if (qemuDomainGetSEVInfo(driver, vm, params, nparams, flags) < 0)
 goto cleanup;
 }
 
-- 
2.33.1



[libvirt PATCH v2 01/12] include: add new launch security parameters

2021-12-10 Thread Daniel P . Berrangé
Three more parameters are required in order that clients can
perform a launch attestation on the SEV guest.

Reviewed-by: Peter Krempa 
Signed-off-by: Daniel P. Berrangé 
---
 include/libvirt/libvirt-domain.h | 32 
 1 file changed, 32 insertions(+)

diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index d0dd11ab01..5d3e15766e 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -5101,6 +5101,38 @@ int virDomainSetLifecycleAction(virDomainPtr domain,
  */
 # define VIR_DOMAIN_LAUNCH_SECURITY_SEV_MEASUREMENT "sev-measurement"
 
+/**
+ * VIR_DOMAIN_LAUNCH_SECURITY_SEV_API_MAJOR:
+ *
+ * Macro represents the API major version of the SEV host,
+ * as VIR_TYPED_PARAM_UINT.
+ */
+# define VIR_DOMAIN_LAUNCH_SECURITY_SEV_API_MAJOR "sev-api-major"
+
+/**
+ * VIR_DOMAIN_LAUNCH_SECURITY_SEV_API_MINOR:
+ *
+ * Macro represents the API minor version of the SEV guest,
+ * as VIR_TYPED_PARAM_UINT.
+ */
+# define VIR_DOMAIN_LAUNCH_SECURITY_SEV_API_MINOR "sev-api-minor"
+
+/**
+ * VIR_DOMAIN_LAUNCH_SECURITY_SEV_BUILD_ID:
+ *
+ * Macro represents the build ID of the SEV host,
+ * as VIR_TYPED_PARAM_UINT.
+ */
+# define VIR_DOMAIN_LAUNCH_SECURITY_SEV_BUILD_ID "sev-build-id"
+
+/**
+ * VIR_DOMAIN_LAUNCH_SECURITY_SEV_POLICY:
+ *
+ * Macro represents the policy of the SEV guest,
+ * as VIR_TYPED_PARAM_UINT.
+ */
+# define VIR_DOMAIN_LAUNCH_SECURITY_SEV_POLICY "sev-policy"
+
 int virDomainGetLaunchSecurityInfo(virDomainPtr domain,
virTypedParameterPtr *params,
int *nparams,
-- 
2.33.1



[libvirt PATCH v2 10/12] conf: add support for setting SEV kernel hashes

2021-12-10 Thread Daniel P . Berrangé
Normally the SEV measurement only covers the firmware
loader contents. When doing a direct kernel boot, however,
with new enough OVMF it is possible to ask for the
measurement to cover the kernel, ramdisk and command line.

It can't be done automatically as that would break existing
guests using direct kernel boot with old firmware, so there
is a new XML setting allowing this behaviour to be toggled.

Signed-off-by: Daniel P. Berrangé 
---
 docs/formatdomain.rst | 7 ++-
 docs/schemas/domaincommon.rng | 5 +
 src/conf/domain_conf.c| 8 
 src/conf/domain_conf.h| 1 +
 4 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index eb8c973cf1..c6e1f2226a 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -8191,7 +8191,7 @@ spec 
`__
 

  ...
- 
+ 
0x0001
47
1
@@ -8201,6 +8201,11 @@ spec 
`__
  ...

 
+``kernelHashes``
+   The optional ``kernelHashes`` attribute indicates whether the
+   hashes of the kernel, ramdisk and command line should be included
+   in the measurement done by the firmware. This is only valid if
+   using direct kernel boot. :since:`Since 8.0.0`
 ``cbitpos``
The required ``cbitpos`` element provides the C-bit (aka encryption bit)
location in guest page table entry. The value of ``cbitpos`` is hypervisor
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index f01b7a6470..8fe6134935 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -499,6 +499,11 @@
 
   sev
 
+
+  
+
+  
+
 
   
 
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 107d2a4f5d..86cd124c4a 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -14793,6 +14793,10 @@ virDomainSEVDefParseXML(virDomainSEVDef *def,
 unsigned long policy;
 int rc;
 
+if (virXMLPropTristateBool(ctxt->node, "kernelHashes", VIR_XML_PROP_NONE,
+   >kernel_hashes) < 0)
+return -1;
+
 if (virXPathULongHex("string(./policy)", ctxt, ) < 0) {
 virReportError(VIR_ERR_XML_ERROR, "%s",
_("failed to get launch security policy"));
@@ -27056,6 +27060,10 @@ virDomainSecDefFormat(virBuffer *buf, virDomainSecDef 
*sec)
 case VIR_DOMAIN_LAUNCH_SECURITY_SEV: {
 virDomainSEVDef *sev = >data.sev;
 
+if (sev->kernel_hashes != VIR_TRISTATE_BOOL_ABSENT)
+virBufferAsprintf(, " kernelHashes='%s'",
+  virTristateBoolTypeToString(sev->kernel_hashes));
+
 if (sev->haveCbitpos)
 virBufferAsprintf(, "%d\n", 
sev->cbitpos);
 
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index c0c07ea6ba..8e576c00f8 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2692,6 +2692,7 @@ struct _virDomainSEVDef {
 unsigned int cbitpos;
 bool haveReducedPhysBits;
 unsigned int reduced_phys_bits;
+virTristateBool kernel_hashes;
 };
 
 struct _virDomainSecDef {
-- 
2.33.1



[libvirt PATCH v2 09/12] qemu: report max number of SEV guests

2021-12-10 Thread Daniel P . Berrangé
Different CPU generations have different limits on the number
of SEV/SEV-ES guests that can be run. Since both limits come
from the same overall set, there is typically also BIOS config
to set the tradeoff betweeen SEV and SEV-ES guest limits.

This is important information to expose for a mgmt application
scheduling guests to hosts.

Signed-off-by: Daniel P. Berrangé 
---
 src/qemu/qemu_capabilities.c  | 38 +++
 src/qemu/qemu_driver.c| 10 +
 .../domaincapsdata/qemu_2.12.0-q35.x86_64.xml |  2 +-
 .../domaincapsdata/qemu_2.12.0-tcg.x86_64.xml |  2 +-
 tests/domaincapsdata/qemu_2.12.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 +-
 8 files changed, 54 insertions(+), 6 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 4ffd0a98a2..456ce1b72e 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -1897,6 +1897,8 @@ virQEMUCapsSEVInfoCopy(virSEVCapability **dst,
 
 tmp->cbitpos = src->cbitpos;
 tmp->reduced_phys_bits = src->reduced_phys_bits;
+tmp->max_guests = src->max_guests;
+tmp->max_es_guests = src->max_es_guests;
 
 *dst = g_steal_pointer();
 return 0;
@@ -3286,6 +3288,30 @@ virQEMUCapsProbeQMPGICCapabilities(virQEMUCaps *qemuCaps,
 }
 
 
+static void
+virQEMUCapsGetSEVMaxGuests(virSEVCapability *caps)
+{
+# if __x86_64__
+uint32_t eax, ebx, ecx, edx;
+asm("xor %%ebx, %%ebx;" /* clear the other registers as some cpuid */
+"xor %%edx, %%edx;" /* functions may use them as additional arguments 
*/
+"cpuid;"
+: "=a" (eax),
+  "=b" (ebx),
+  "=c" (ecx),
+  "=d" (edx)
+: "0" (0x801F),
+  "c" (0)
+: "cc");
+
+caps->max_guests = ecx - edx + 1;
+caps->max_es_guests = edx - 1;
+# else
+VIR_WARN("Unexpectedly asked for SEV guest count on non-x86_64 arch");
+caps->max_guests = caps->max_es_guests = 0;
+# endif
+}
+
 static int
 virQEMUCapsProbeQMPSEVCapabilities(virQEMUCaps *qemuCaps,
qemuMonitor *mon)
@@ -3305,6 +3331,8 @@ virQEMUCapsProbeQMPSEVCapabilities(virQEMUCaps *qemuCaps,
 return 0;
 }
 
+virQEMUCapsGetSEVMaxGuests(caps);
+
 virSEVCapabilitiesFree(qemuCaps->sevCapabilities);
 qemuCaps->sevCapabilities = caps;
 return 0;
@@ -4084,6 +4112,14 @@ virQEMUCapsParseSEVInfo(virQEMUCaps *qemuCaps, 
xmlXPathContextPtr ctxt)
 return -1;
 }
 
+
+/* We probe this every time because the values
+ * can change on every reboot via firmware
+ * config tunables. It is cheap to query so
+ * lack of caching is a non-issue
+ */
+virQEMUCapsGetSEVMaxGuests(sev);
+
 qemuCaps->sevCapabilities = g_steal_pointer();
 return 0;
 }
@@ -6344,6 +6380,8 @@ virQEMUCapsFillDomainFeatureSEVCaps(virQEMUCaps *qemuCaps,
 domCaps->sev->cert_chain = g_strdup(cap->cert_chain);
 domCaps->sev->cbitpos = cap->cbitpos;
 domCaps->sev->reduced_phys_bits = cap->reduced_phys_bits;
+domCaps->sev->max_guests = cap->max_guests;
+domCaps->sev->max_es_guests = cap->max_es_guests;
 }
 
 
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 1bf1938634..572e09be9f 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -19934,6 +19934,16 @@ qemuGetSEVInfoToParams(virQEMUCaps *qemuCaps,
 sev->reduced_phys_bits) < 0)
 goto cleanup;
 
+if (virTypedParamsAddUInt(, , ,
+VIR_NODE_SEV_MAX_GUESTS,
+sev->max_guests) < 0)
+goto cleanup;
+
+if (virTypedParamsAddUInt(, , ,
+VIR_NODE_SEV_MAX_ES_GUESTS,
+sev->max_es_guests) < 0)
+goto cleanup;
+
 *params = g_steal_pointer();
 *nparams = n;
 return 0;
diff --git a/tests/domaincapsdata/qemu_2.12.0-q35.x86_64.xml 
b/tests/domaincapsdata/qemu_2.12.0-q35.x86_64.xml
index 26816ff066..6956f9af07 100644
--- a/tests/domaincapsdata/qemu_2.12.0-q35.x86_64.xml
+++ b/tests/domaincapsdata/qemu_2.12.0-q35.x86_64.xml
@@ -205,7 +205,7 @@
 
   47
   1
-  0
+  15
   0
 
   
diff --git a/tests/domaincapsdata/qemu_2.12.0-tcg.x86_64.xml 
b/tests/domaincapsdata/qemu_2.12.0-tcg.x86_64.xml
index 5840a8b921..c6408d154c 100644
--- a/tests/domaincapsdata/qemu_2.12.0-tcg.x86_64.xml
+++ b/tests/domaincapsdata/qemu_2.12.0-tcg.x86_64.xml
@@ -215,7 +215,7 @@
 
   47
   1
-  0
+  15
   0
 
   
diff --git a/tests/domaincapsdata/qemu_2.12.0.x86_64.xml 
b/tests/domaincapsdata/qemu_2.12.0.x86_64.xml
index 21d1b6946e..918439e4a0 100644
--- a/tests/domaincapsdata/qemu_2.12.0.x86_64.xml
+++ b/tests/domaincapsdata/qemu_2.12.0.x86_64.xml
@@ -205,7 +205,7 @@
 
   47
   1
-  0
+  15
   0
 
   
diff --git 

[libvirt PATCH v2 08/12] include: define parameters for reporting SEV guest limits

2021-12-10 Thread Daniel P . Berrangé
There are limits on the number of SEV/SEV-ES guests that can
be run on machines, which may be influenced by firmware
settings. This is important to expose to users.

Signed-off-by: Daniel P. Berrangé 
---
 include/libvirt/libvirt-host.h | 16 
 1 file changed, 16 insertions(+)

diff --git a/include/libvirt/libvirt-host.h b/include/libvirt/libvirt-host.h
index 4caed94a77..1dc4b8a147 100644
--- a/include/libvirt/libvirt-host.h
+++ b/include/libvirt/libvirt-host.h
@@ -472,6 +472,22 @@ typedef virNodeMemoryStats *virNodeMemoryStatsPtr;
  */
 # define VIR_NODE_SEV_REDUCED_PHYS_BITS "reduced-phys-bits"
 
+/**
+ * VIR_NODE_SEV_MAX_GUESTS:
+ *
+ * Macro represents the number of SEV guests that can
+ * be run on the host, as a VIR_TYPED_PARAM_UINT.
+ */
+# define VIR_NODE_SEV_MAX_GUESTS "max-guests"
+
+/**
+ * VIR_NODE_SEV_MAX_ES_GUESTS:
+ *
+ * Macro represents the number of SEV-ES guests that can
+ * be run on the host, as a VIR_TYPED_PARAM_UINT.
+ */
+# define VIR_NODE_SEV_MAX_ES_GUESTS "max-es-guests"
+
 int virNodeGetSEVInfo (virConnectPtr conn,
virTypedParameterPtr *params,
int *nparams,
-- 
2.33.1



[libvirt PATCH v2 07/12] conf: extend domain capabilities for max SEV guest count

2021-12-10 Thread Daniel P . Berrangé
There are limits on the number of SEV/SEV-ES guests that can
be run on machines, which may be influenced by firmware
settings. This is important to expose to users.

Signed-off-by: Daniel P. Berrangé 
---
 docs/formatdomaincaps.html.in   | 6 ++
 docs/schemas/domaincaps.rng | 6 ++
 src/conf/domain_capabilities.c  | 4 
 src/conf/domain_capabilities.h  | 2 ++
 tests/domaincapsdata/qemu_2.12.0-q35.x86_64.xml | 2 ++
 tests/domaincapsdata/qemu_2.12.0-tcg.x86_64.xml | 2 ++
 tests/domaincapsdata/qemu_2.12.0.x86_64.xml | 2 ++
 tests/domaincapsdata/qemu_6.0.0-q35.x86_64.xml  | 2 ++
 tests/domaincapsdata/qemu_6.0.0-tcg.x86_64.xml  | 2 ++
 tests/domaincapsdata/qemu_6.0.0.x86_64.xml  | 2 ++
 10 files changed, 30 insertions(+)

diff --git a/docs/formatdomaincaps.html.in b/docs/formatdomaincaps.html.in
index 915ece8e3e..35b8bf3def 100644
--- a/docs/formatdomaincaps.html.in
+++ b/docs/formatdomaincaps.html.in
@@ -681,6 +681,12 @@
   reducedPhysBits
   When memory encryption is enabled, we lose certain bits in physical
   address space. The number of bits we lose is hypervisor dependent.
+  maxGuests
+  The maximum number of SEV guests that can be launched on the host.
+  This value may be configurable in the firmware for some hosts.
+  maxESGuests
+  The maximum number of SEV-ES guests that can be launched on the host.
+  This value may be configurable in the firmware for some hosts.
 
 
   
diff --git a/docs/schemas/domaincaps.rng b/docs/schemas/domaincaps.rng
index 1b6122507f..b40ee0f35a 100644
--- a/docs/schemas/domaincaps.rng
+++ b/docs/schemas/domaincaps.rng
@@ -323,6 +323,12 @@
 
   
 
+
+  
+
+
+  
+
   
 
   
diff --git a/src/conf/domain_capabilities.c b/src/conf/domain_capabilities.c
index fef1326190..c394a7a390 100644
--- a/src/conf/domain_capabilities.c
+++ b/src/conf/domain_capabilities.c
@@ -597,6 +597,10 @@ virDomainCapsFeatureSEVFormat(virBuffer *buf,
 virBufferAsprintf(buf, "%d\n", sev->cbitpos);
 virBufferAsprintf(buf, "%d\n",
   sev->reduced_phys_bits);
+virBufferAsprintf(buf, "%d\n",
+  sev->max_guests);
+virBufferAsprintf(buf, "%d\n",
+  sev->max_es_guests);
 virBufferAdjustIndent(buf, -2);
 virBufferAddLit(buf, "\n");
 }
diff --git a/src/conf/domain_capabilities.h b/src/conf/domain_capabilities.h
index 2fcad87fd8..1d2f4ac7a5 100644
--- a/src/conf/domain_capabilities.h
+++ b/src/conf/domain_capabilities.h
@@ -187,6 +187,8 @@ struct _virSEVCapability {
 char *cert_chain;
 unsigned int cbitpos;
 unsigned int reduced_phys_bits;
+unsigned int max_guests;
+unsigned int max_es_guests;
 };
 
 typedef enum {
diff --git a/tests/domaincapsdata/qemu_2.12.0-q35.x86_64.xml 
b/tests/domaincapsdata/qemu_2.12.0-q35.x86_64.xml
index 9f41dfaf2b..26816ff066 100644
--- a/tests/domaincapsdata/qemu_2.12.0-q35.x86_64.xml
+++ b/tests/domaincapsdata/qemu_2.12.0-q35.x86_64.xml
@@ -205,6 +205,8 @@
 
   47
   1
+  0
+  0
 
   
 
diff --git a/tests/domaincapsdata/qemu_2.12.0-tcg.x86_64.xml 
b/tests/domaincapsdata/qemu_2.12.0-tcg.x86_64.xml
index d5f9d8ebe3..5840a8b921 100644
--- a/tests/domaincapsdata/qemu_2.12.0-tcg.x86_64.xml
+++ b/tests/domaincapsdata/qemu_2.12.0-tcg.x86_64.xml
@@ -215,6 +215,8 @@
 
   47
   1
+  0
+  0
 
   
 
diff --git a/tests/domaincapsdata/qemu_2.12.0.x86_64.xml 
b/tests/domaincapsdata/qemu_2.12.0.x86_64.xml
index dc2c3ec4dd..21d1b6946e 100644
--- a/tests/domaincapsdata/qemu_2.12.0.x86_64.xml
+++ b/tests/domaincapsdata/qemu_2.12.0.x86_64.xml
@@ -205,6 +205,8 @@
 
   47
   1
+  0
+  0
 
   
 
diff --git a/tests/domaincapsdata/qemu_6.0.0-q35.x86_64.xml 
b/tests/domaincapsdata/qemu_6.0.0-q35.x86_64.xml
index 90acb29775..3415d44019 100644
--- a/tests/domaincapsdata/qemu_6.0.0-q35.x86_64.xml
+++ b/tests/domaincapsdata/qemu_6.0.0-q35.x86_64.xml
@@ -227,6 +227,8 @@
 
   47
   1
+  0
+  0
 
   
 
diff --git a/tests/domaincapsdata/qemu_6.0.0-tcg.x86_64.xml 
b/tests/domaincapsdata/qemu_6.0.0-tcg.x86_64.xml
index 768cba5a41..f58be3af6c 100644
--- a/tests/domaincapsdata/qemu_6.0.0-tcg.x86_64.xml
+++ b/tests/domaincapsdata/qemu_6.0.0-tcg.x86_64.xml
@@ -233,6 +233,8 @@
 
   47
   1
+  0
+  0
 
   
 
diff --git a/tests/domaincapsdata/qemu_6.0.0.x86_64.xml 
b/tests/domaincapsdata/qemu_6.0.0.x86_64.xml
index 7a95c530f9..0a2615c519 100644
--- a/tests/domaincapsdata/qemu_6.0.0.x86_64.xml
+++ b/tests/domaincapsdata/qemu_6.0.0.x86_64.xml
@@ -227,6 +227,8 @@
 
   47
   1
+  0
+  0
 
   
 
-- 
2.33.1



[libvirt PATCH v2 03/12] qemu: add monitor APIs for query-sev

2021-12-10 Thread Daniel P . Berrangé
We're only returning the set of fields needed to perform an
attestation, per the SEV API docs.

Signed-off-by: Daniel P. Berrangé 
---
 src/qemu/qemu_monitor.c  | 13 ++
 src/qemu/qemu_monitor.h  |  9 +++
 src/qemu/qemu_monitor_json.c | 46 
 src/qemu/qemu_monitor_json.h |  9 +++
 tests/qemumonitorjsontest.c  | 43 +
 5 files changed, 120 insertions(+)

diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 75e0e4ed92..dda6ae9796 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -4366,6 +4366,19 @@ qemuMonitorGetSEVMeasurement(qemuMonitor *mon)
 }
 
 
+int
+qemuMonitorGetSEVInfo(qemuMonitor *mon,
+  unsigned int *apiMajor,
+  unsigned int *apiMinor,
+  unsigned int *buildID,
+  unsigned int *policy)
+{
+QEMU_CHECK_MONITOR(mon);
+
+return qemuMonitorJSONGetSEVInfo(mon, apiMajor, apiMinor, buildID, policy);
+}
+
+
 int
 qemuMonitorGetPRManagerInfo(qemuMonitor *mon,
 GHashTable **retinfo)
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index edc2b01a66..29746f0b8e 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -1445,6 +1445,15 @@ int qemuMonitorBlockdevMediumInsert(qemuMonitor *mon,
 char *
 qemuMonitorGetSEVMeasurement(qemuMonitor *mon);
 
+int
+qemuMonitorGetSEVInfo(qemuMonitor *mon,
+  unsigned int *apiMajor,
+  unsigned int *apiMinor,
+  unsigned int *buildID,
+  unsigned int *policy)
+ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
+ATTRIBUTE_NONNULL(4) ATTRIBUTE_NONNULL(5);
+
 typedef struct _qemuMonitorPRManagerInfo qemuMonitorPRManagerInfo;
 struct _qemuMonitorPRManagerInfo {
 bool connected;
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index e00d785c20..a3d6eca569 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -8216,6 +8216,52 @@ qemuMonitorJSONGetSEVMeasurement(qemuMonitor *mon)
 }
 
 
+/**
+ * Retrive info about the SEV setup, returning those fields that
+ * are required to do a launch attestation, as per
+ *
+ * HMAC(0x04 || API_MAJOR || API_MINOR || BUILD || GCTX.POLICY || GCTX.LD || 
MNONCE; GCTX.TIK)
+ *
+ * specified in section 6.5.1 of AMD Secure Encrypted
+ * Virtualization API.
+ *
+ *  { "execute": "query-sev" }
+ *  { "return": { "enabled": true, "api-major" : 0, "api-minor" : 0,
+ *"build-id" : 0, "policy" : 0, "state" : "running",
+ *"handle" : 1 } }
+ */
+int
+qemuMonitorJSONGetSEVInfo(qemuMonitor *mon,
+  unsigned int *apiMajor,
+  unsigned int *apiMinor,
+  unsigned int *buildID,
+  unsigned int *policy)
+{
+g_autoptr(virJSONValue) cmd = NULL;
+g_autoptr(virJSONValue) reply = NULL;
+virJSONValue *data;
+
+if (!(cmd = qemuMonitorJSONMakeCommand("query-sev", NULL)))
+return -1;
+
+if (qemuMonitorJSONCommand(mon, cmd, ) < 0)
+return -1;
+
+if (qemuMonitorJSONCheckReply(cmd, reply, VIR_JSON_TYPE_OBJECT) < 0)
+return -1;
+
+data = virJSONValueObjectGetObject(reply, "return");
+
+if (virJSONValueObjectGetNumberUint(data, "api-major", apiMajor) < 0 ||
+virJSONValueObjectGetNumberUint(data, "api-minor", apiMinor) < 0 ||
+virJSONValueObjectGetNumberUint(data, "build-id", buildID) < 0 ||
+virJSONValueObjectGetNumberUint(data, "policy", policy) < 0)
+return -1;
+
+return 0;
+}
+
+
 /*
  * Example return data
  *
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index 64064b0519..e88dfc9d50 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -459,6 +459,15 @@ qemuMonitorJSONSystemWakeup(qemuMonitor *mon);
 char *
 qemuMonitorJSONGetSEVMeasurement(qemuMonitor *mon);
 
+int
+qemuMonitorJSONGetSEVInfo(qemuMonitor *mon,
+  unsigned int *apiMajor,
+  unsigned int *apiMinor,
+  unsigned int *buildID,
+  unsigned int *policy)
+ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
+ATTRIBUTE_NONNULL(4) ATTRIBUTE_NONNULL(5);
+
 int
 qemuMonitorJSONGetVersion(qemuMonitor *mon,
   int *major,
diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c
index 1ad2912b08..1b0bd0870d 100644
--- a/tests/qemumonitorjsontest.c
+++ b/tests/qemumonitorjsontest.c
@@ -2884,6 +2884,48 @@ 
testQemuMonitorJSONqemuMonitorJSONGetCPUModelBaseline(const void *opaque)
 }
 
 
+static int
+testQemuMonitorJSONGetSEVInfo(const void *opaque)
+{
+const testGenericData *data = opaque;
+virDomainXMLOption *xmlopt = data->xmlopt;
+g_autoptr(qemuMonitorTest) test = NULL;
+   

[libvirt PATCH v2 02/12] qemu: report error querying launch params for inactive guest

2021-12-10 Thread Daniel P . Berrangé
Querying launch params on a inactive guest currently triggers
a warning about the monitor being NULL.

https://bugzilla.redhat.com/show_bug.cgi?id=2030437

Reviewed-by: Peter Krempa 
Signed-off-by: Daniel P. Berrangé 
---
 src/qemu/qemu_driver.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 8093b8f69b..5bacf73003 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -19992,6 +19992,12 @@ qemuDomainGetSEVMeasurement(virQEMUDriver *driver,
 if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0)
 return -1;
 
+if (!virDomainObjIsActive(vm)) {
+virReportError(VIR_ERR_OPERATION_INVALID,
+   "%s", _("domain is not running"));
+goto endjob;
+}
+
 qemuDomainObjEnterMonitor(driver, vm);
 tmp = qemuMonitorGetSEVMeasurement(QEMU_DOMAIN_PRIVATE(vm)->mon);
 
-- 
2.33.1



[libvirt PATCH v2 00/12] Improve AMD SEV support

2021-12-10 Thread Daniel P . Berrangé
This addresses a few issues in the AMD SEV support

 - Neither host or domain level SEV metadata is
   exposed in virsh commands
 - The domain launch security parameters don't expose
   enough info to validate the measurement
 - Support verified direct kernel boot
 - Report max SEV/SEV-ES guest counts

The second point was the initial purpose of my work. Per the
SEV API guide to calculate the measurement we need

measurement = HMAC(0x04 || API_MAJOR || API_MINOR || BUILD ||
 GCTX.POLICY || GCTX.LD || MNONCE; GCTX.TIK)

The API_MINOR, API_MAJOR, BUILD values are things that are
available from 'query-sev' QMP command  and libvirt does
not expose this info. This patch series adds them to
virDomainGetLaunchSecurityParams alongside the measurement
that we already report.

So now the client can fetch this info and calculate an expected
measurement to compare with the actual measurement they got.

They will thus know if the guest is safe to inject secrets into,
which is where Jim's recent patches come into play.

Daniel P. Berrangé (12):
  include: add new launch security parameters
  qemu: report error querying launch params for inactive guest
  qemu: add monitor APIs for query-sev
  qemu: report new launch security parameters
  tools: add 'domlaunchsecinfo' virsh command
  tools: add 'nodesevinfo' virsh command
  conf: extend domain capabilities for max SEV guest count
  include: define parameters for reporting SEV guest limits
  qemu: report max number of SEV guests
  conf: add support for setting SEV kernel hashes
  qemu: probe for sev-guest.kernel-hashes property
  qemu: format sev-guest.kernel-hashes property

 docs/formatdomain.rst |   7 +-
 docs/formatdomaincaps.html.in |   6 +
 docs/manpages/virsh.rst   |  31 +
 docs/schemas/domaincaps.rng   |   6 +
 docs/schemas/domaincommon.rng |   5 +
 include/libvirt/libvirt-domain.h  |  32 +
 include/libvirt/libvirt-host.h|  16 +++
 src/conf/domain_capabilities.c|   4 +
 src/conf/domain_capabilities.h|   2 +
 src/conf/domain_conf.c|   8 ++
 src/conf/domain_conf.h|   1 +
 src/qemu/qemu_capabilities.c  |  46 
 src/qemu/qemu_capabilities.h  |   1 +
 src/qemu/qemu_command.c   |   7 ++
 src/qemu/qemu_driver.c|  59 --
 src/qemu/qemu_monitor.c   |  13 +++
 src/qemu/qemu_monitor.h   |   9 ++
 src/qemu/qemu_monitor_json.c  |  46 
 src/qemu/qemu_monitor_json.h  |   9 ++
 src/qemu/qemu_validate.c  |   8 ++
 .../domaincapsdata/qemu_2.12.0-q35.x86_64.xml |   2 +
 .../domaincapsdata/qemu_2.12.0-tcg.x86_64.xml |   2 +
 tests/domaincapsdata/qemu_2.12.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.2.0-q35.x86_64.xml  |   7 +-
 .../domaincapsdata/qemu_6.2.0-tcg.x86_64.xml  |   7 +-
 tests/domaincapsdata/qemu_6.2.0.x86_64.xml|   7 +-
 .../caps_2.12.0.x86_64.replies|  97 
 .../caps_3.0.0.x86_64.replies |  97 
 .../caps_3.1.0.x86_64.replies |  97 
 .../caps_4.0.0.x86_64.replies |  97 
 .../caps_4.1.0.x86_64.replies |  89 ++
 .../caps_4.2.0.x86_64.replies |  89 ++
 .../caps_5.0.0.x86_64.replies |  89 ++
 .../caps_5.1.0.x86_64.replies |  89 ++
 .../caps_5.2.0.x86_64.replies |  89 ++
 .../caps_6.0.0.x86_64.replies |  89 ++
 .../caps_6.1.0.x86_64.replies |  89 ++
 .../caps_6.2.0.x86_64.replies | 109 ++
 .../caps_6.2.0.x86_64.xml |   8 ++
 tests/qemumonitorjsontest.c   |  43 +++
 ...unch-security-sev-direct.x86_64-6.2.0.args |  40 +++
 .../launch-security-sev-direct.xml|  39 +++
 tests/qemuxml2argvtest.c  |   1 +
 tools/virsh-domain.c  |  53 +
 tools/virsh-host.c|  45 
 48 files changed, 1427 insertions(+), 271 deletions(-)
 create mode 100644 
tests/qemuxml2argvdata/launch-security-sev-direct.x86_64-6.2.0.args
 create mode 100644 tests/qemuxml2argvdata/launch-security-sev-direct.xml

-- 
2.33.1




Re: [PATCH] Fixes: #253

2021-12-10 Thread Peter Krempa
On Fri, Dec 10, 2021 at 11:26:18 +0800, JorhsonDeng wrote:
> To resolve the bug: #253.
> 
> The restore method should call the qemuProcessRefreshState method
> to refreash the state of the devices.

Please also mention that this happens when restoring a VM from a save
image, as it's not clear from the commit message itself.

In general the commit message must be a standalone source of information
describing what's happening. This also means that the summary line
should be more descriptive.


Note that the libvirt project requires that contributors declare
conformance with the Developer certificate of origin:

https://www.libvirt.org/hacking.html#developer-certificate-of-origin

> 
> ---
>  src/qemu/qemu_process.c | 9 +++--
>  1 file changed, 3 insertions(+), 6 deletions(-)
> 
> diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
> index 6b83a571b9..ebd60a7b84 100644
> --- a/src/qemu/qemu_process.c
> +++ b/src/qemu/qemu_process.c
> @@ -7703,14 +7703,11 @@ qemuProcessStart(virConnectPtr conn,
>  if (incoming->deferredURI &&
>  qemuMigrationDstRun(driver, vm, incoming->deferredURI, asyncJob) 
> < 0)
>  goto stop;
> -} else {
> -/* Refresh state of devices from QEMU. During migration this happens
> - * in qemuMigrationDstFinish to ensure that state information is 
> fully
> - * transferred. */
> -if (qemuProcessRefreshState(driver, vm, asyncJob) < 0)
> -goto stop;


So you are removing a comment which says that for migration this is
happening elsewhere without any justification or fix to the code.

The refresh in case of migration is happening in a different place for a
very good reason so we must keep it that way. This means you'll have to
introduce some form of logic which refreshes the state only when
restoring a save image.

>  }
>  
> +if (qemuProcessRefreshState(driver, vm, asyncJob) < 0)
> +goto stop;
> +
>  if (qemuProcessFinishStartup(driver, vm, asyncJob,
>   !(flags & VIR_QEMU_PROCESS_START_PAUSED),
>   incoming ?
> -- 
> 2.27.0
> 



[PATCH] Fixes: #253

2021-12-10 Thread JorhsonDeng
To resolve the bug: #253.

The restore method should call the qemuProcessRefreshState method
to refreash the state of the devices.

---
 src/qemu/qemu_process.c | 9 +++--
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 6b83a571b9..ebd60a7b84 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -7703,14 +7703,11 @@ qemuProcessStart(virConnectPtr conn,
 if (incoming->deferredURI &&
 qemuMigrationDstRun(driver, vm, incoming->deferredURI, asyncJob) < 
0)
 goto stop;
-} else {
-/* Refresh state of devices from QEMU. During migration this happens
- * in qemuMigrationDstFinish to ensure that state information is fully
- * transferred. */
-if (qemuProcessRefreshState(driver, vm, asyncJob) < 0)
-goto stop;
 }
 
+if (qemuProcessRefreshState(driver, vm, asyncJob) < 0)
+goto stop;
+
 if (qemuProcessFinishStartup(driver, vm, asyncJob,
  !(flags & VIR_QEMU_PROCESS_START_PAUSED),
  incoming ?
-- 
2.27.0



Re: Issue labe improvements

2021-12-10 Thread Daniel P . Berrangé
On Wed, Dec 08, 2021 at 04:34:27PM +0100, Peter Krempa wrote:
> Hi,
> 
> from time to time when I try to go through upstream issues I always feel
> that the labels we have are suboptimal and don't always allow to track
> the current state of the issue.
> 
> Recently I've had a look at the qemu issues and found what I was
> lacking.
> 
> Specifically I'm lacking the 'workflow' class of labels they use.
> 
> I propose we adopt the following changes:
> 
> 1) Convert the existing 'bug', 'enhancement', 'support', and
> 'discussion' labels into a set of scoped labels (again inspiration taken
> from qemu):
> 
>  kind::bug
>  kind::enhancement
>  kind::support
>  kind::discussion
>  kind::documentation
> 
> This is mostly as the above kinds are mutually exclusive.
> 
> 
> 2) Introduce the workflow label similarly to what qemu uses:
> 
>  workflow::Confirmed/Triaged (<- confirmed for bugs, triaged for
>enhancements)
>  workflow::Needs Info (replaces "needinfo")
>  workflow::In progress (replaces "Doing")
> 
> I'd also potentially like to have a 'Unconfirmed' state for when the
> bug has enough info, but it's unknown why it's happening.
> 
> I want to specifically avoid the ambiguous "Triaged" when used on it's
> own.
> 
> 3) Convert host-* labels into a scoped label. Hosts are usually mutually
> exclusive

This is not desirable, we can easily hauve issues that
affect both FreBSD and macOS at the same time.

> 4) Convert driver-* into scoped labels. Usually issues are not exceeding
> these boundaries

Again, this is not desirable, as I consider those labels to
mean that it /affects/ users of that driver, rather than it
being in code only related to that driver.  IOW, if there is
a cgroups bug it is relevant to want to put a label of qemu,
lxc and ch.

> 5) Remove the following unused or ambiguous labels:
> 
>   - critical

I think this is useful as a way to mark an issue as very
important.

>   - incident

This feels redundant since we're not providing production
support for some service.

>   - Doing



>   - To Do

'To do' is really just anothuer work for 'enhancement'

>   - gsoc::20* (all seem to be unused)

The intent of gsoc labels is that we'll use those to track
gsoc ideas instead of the wiki. When someone starts working
on a particular project, it'll get tagged with the year.
I was intending to copy over historical content from the
wiki prior to deleting the wiki

Regards,
Daniel
-- 
|: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o-https://fstop138.berrange.com :|
|: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|



Re: [PATCH] docs: Remove dependency on external resources

2021-12-10 Thread Andrea Bolognani
On Fri, Dec 10, 2021 at 11:41:29AM +0100, Peter Krempa wrote:
> >  docs/event_loop_simple.png   | Bin 0 -> 16043 bytes
> >  docs/event_loop_simple.svg   | 398 +
> >  docs/event_loop_worker.png   | Bin 0 -> 29696 bytes
> >  docs/event_loop_worker.svg   | 708 +++
>
> Shouldn't these files ...
>
> >  docs/internals/eventloop.html.in |   4 +-
>
> .. be inside the 'internals' directory?

For that to work, I'd have to replicate the docs_assets machinery
found in docs/meson.build to docs/internals/meson.build.

I'm not absolutely against it, and we already have a copy in
docs/logos/meson.build after all, but using relative paths seemed
preferable.

-- 
Andrea Bolognani / Red Hat / Virtualization



Re: [PATCH] docs: Remove dependency on external resources

2021-12-10 Thread Peter Krempa
On Thu, Dec 09, 2021 at 16:42:29 +0100, Andrea Bolognani wrote:
> The internals/eventloop document uses two images for
> illustrative purposes, but unlike other graphics included
> in the documentation these are not part of libvirt.git but
> rather were added to libvirt-media.git with
> 
>   commit fae5622074cf5e18d190496f8a43260c614599b2
>   Author: Michal Privoznik 
>   Date:   Mon Jun 6 17:27:50 2016 +0200
> 
> Add two event loop images
> 
> These images are going to be used in our documentation of the
> event loop.
> 
> Signed-off-by: Michal Privoznik 
> 
>   
> https://gitlab.com/libvirt/libvirt-media/-/commit/fae5622074cf5e18d190496f8a43260c614599b2
> 
> and are requested directly from there. Specifically, the
> URLs point to the libvirt.org mirror of libvirt-media.git
> instead of the primary repository hosted on GitLab.
> 
> Import the images into libvirt.git so that the website
> doesn't rely on external resources and can, if desired, be
> browsed entirely offline from installed packages.
> 
> Signed-off-by: Andrea Bolognani 
> ---
> Redacted to strip binary and binary-adjacent blobs.
> Full patch: 
> https://gitlab.com/abologna/libvirt/-/commit/684805e3cf65ab3bb93a92ada3b720331fae72ce
> 
>  docs/event_loop_simple.png   | Bin 0 -> 16043 bytes
>  docs/event_loop_simple.svg   | 398 +
>  docs/event_loop_worker.png   | Bin 0 -> 29696 bytes
>  docs/event_loop_worker.svg   | 708 +++

Shouldn't these files ...

>  docs/internals/eventloop.html.in |   4 +-

.. be inside the 'internals' directory?



Re: [libvirt PATCH] remote: Avoid crash in remoteSplitURIScheme()

2021-12-10 Thread Peter Krempa
On Fri, Dec 10, 2021 at 10:59:27 +0100, Andrea Bolognani wrote:
> We need to make sure the URI scheme is present before passing
> it to strchr(), otherwise we're going to get
> 
>   $ virt-ssh-helper foo
>   Segmentation fault (core dumped)
> 
> Signed-off-by: Andrea Bolognani 
> ---
>  src/remote/remote_sockets.c | 10 +-
>  1 file changed, 9 insertions(+), 1 deletion(-)
> 
> diff --git a/src/remote/remote_sockets.c b/src/remote/remote_sockets.c
> index 2979576680..c315b24d30 100644
> --- a/src/remote/remote_sockets.c
> +++ b/src/remote/remote_sockets.c
> @@ -69,7 +69,15 @@ remoteSplitURIScheme(virURI *uri,
>   char **driver,
>   remoteDriverTransport *transport)
>  {
> -char *p = strchr(uri->scheme, '+');
> +char *p = NULL;
> +
> +if (!uri->scheme) {
> +virReportError(VIR_ERR_INVALID_ARG, "%s",
> +   _("missing scheme for URI"));

The other place which leads to the call of this helper (virConnectOpenInternal)
uses the following error to reject the uri if scheme is missing:

virReportError(VIR_ERR_NO_CONNECT,
   _("URI '%s' does not include a driver name"),
   name);

It looks like it's unlikely that anybody would use virt-ssh-helper
manually though.

Reviewed-by: Peter Krempa 



  1   2   >