[PATCH v2 3/8] conf, qemu: adding 'tpmproxy' in domain definition

Daniel Henrique Barboza posted 8 patches 4 years, 6 months ago
There is a newer version of this series
[PATCH v2 3/8] conf, qemu: adding 'tpmproxy' in domain definition
Posted by Daniel Henrique Barboza 4 years, 6 months ago
A TPM Proxy device can coexist with a regular TPM. The TPM Proxy
is also always a 'passthrough' device of the 'spapr-tpm-proxy'
model.

This patch adds a pointer to this device in the domain definition
called 'tpmproxy'. This pointer is handled like the existing
'tpm' pointer of the VIR_DOMAIN_TPM_TYPE_PASSTHROUGH type.
Cgroup, DAC/SELinux and qemu validation code was adapted to handle
this new domain device.

XML functions to parse and format this new device from/to XML
will be added in the next patch, together with the logic that
will guarantee the assumptions made in the first paragraph.

Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
---
 src/conf/domain_audit.c         |  3 +++
 src/conf/domain_conf.c          | 18 ++++++++++++++++++
 src/conf/domain_conf.h          |  2 ++
 src/qemu/qemu_cgroup.c          | 12 +++++++++---
 src/qemu/qemu_domain.c          |  9 +++++----
 src/qemu/qemu_validate.c        | 12 ++++++++++++
 src/security/security_dac.c     | 14 ++++++++++++++
 src/security/security_selinux.c | 11 +++++++++++
 8 files changed, 74 insertions(+), 7 deletions(-)

diff --git a/src/conf/domain_audit.c b/src/conf/domain_audit.c
index 1b0abb21a0..4575f66e45 100644
--- a/src/conf/domain_audit.c
+++ b/src/conf/domain_audit.c
@@ -824,6 +824,9 @@ virDomainAuditStart(virDomainObjPtr vm, const char *reason, bool success)
     if (vm->def->tpm)
         virDomainAuditTPM(vm, vm->def->tpm, "start", true);
 
+    if (vm->def->tpmproxy)
+        virDomainAuditTPM(vm, vm->def->tpmproxy, "start", true);
+
     for (i = 0; i < vm->def->nshmems; i++)
         virDomainAuditShmem(vm, vm->def->shmems[i], "start", true);
 
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index c201fc901d..01a32f62d1 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1165,6 +1165,7 @@ VIR_ENUM_IMPL(virDomainTPMModel,
               "tpm-tis",
               "tpm-crb",
               "tpm-spapr",
+              "spapr-tpm-proxy",
 );
 
 VIR_ENUM_IMPL(virDomainTPMBackend,
@@ -3480,6 +3481,7 @@ void virDomainDefFree(virDomainDefPtr def)
     VIR_FREE(def->mems);
 
     virDomainTPMDefFree(def->tpm);
+    virDomainTPMDefFree(def->tpmproxy);
 
     for (i = 0; i < def->npanics; i++)
         virDomainPanicDefFree(def->panics[i]);
@@ -4318,6 +4320,12 @@ virDomainDeviceInfoIterateInternal(virDomainDefPtr def,
         if ((rc = cb(def, &device, &def->tpm->info, opaque)) != 0)
             return rc;
     }
+    if (def->tpmproxy) {
+        device.type = VIR_DOMAIN_DEVICE_TPM;
+        device.data.tpm = def->tpmproxy;
+        if ((rc = cb(def, &device, &def->tpmproxy->info, opaque)) != 0)
+            return rc;
+    }
     device.type = VIR_DOMAIN_DEVICE_PANIC;
     for (i = 0; i < def->npanics; i++) {
         device.data.panic = def->panics[i];
@@ -24344,6 +24352,16 @@ virDomainDefCheckABIStabilityFlags(virDomainDefPtr src,
         goto error;
     }
 
+    if (src->tpmproxy && dst->tpmproxy) {
+        if (!virDomainTPMDefCheckABIStability(src->tpmproxy, dst->tpmproxy))
+            goto error;
+    } else if (src->tpmproxy || dst->tpmproxy) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                       _("Either both target and source domains or none of "
+                         "them must have TPM Proxy device present"));
+        goto error;
+    }
+
     if (src->nmems != dst->nmems) {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                        _("Target domain memory device count %zu "
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index ddc75d8de2..8f178ade34 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1293,6 +1293,7 @@ typedef enum {
     VIR_DOMAIN_TPM_MODEL_TIS,
     VIR_DOMAIN_TPM_MODEL_CRB,
     VIR_DOMAIN_TPM_MODEL_SPAPR,
+    VIR_DOMAIN_TPM_MODEL_SPAPR_PROXY,
 
     VIR_DOMAIN_TPM_MODEL_LAST
 } virDomainTPMModel;
@@ -2628,6 +2629,7 @@ struct _virDomainDef {
     virDomainMemballoonDefPtr memballoon;
     virDomainNVRAMDefPtr nvram;
     virDomainTPMDefPtr tpm;
+    virDomainTPMDefPtr tpmproxy;
     virCPUDefPtr cpu;
     virSysinfoDefPtr sysinfo;
     virDomainRedirFilterDefPtr redirfilter;
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index 2e019b64af..2ed4341655 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -333,10 +333,13 @@ qemuSetupChardevCgroupCB(virDomainDefPtr def G_GNUC_UNUSED,
 
 
 static int
-qemuSetupTPMCgroup(virDomainObjPtr vm)
+qemuSetupTPMCgroup(virDomainObjPtr vm,
+                   virDomainTPMDefPtr dev)
 {
     int ret = 0;
-    virDomainTPMDefPtr dev = vm->def->tpm;
+
+    if (!dev)
+        return 0;
 
     switch (dev->type) {
     case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH:
@@ -806,7 +809,10 @@ qemuSetupDevicesCgroup(virDomainObjPtr vm)
                                vm) < 0)
         return -1;
 
-    if (vm->def->tpm && qemuSetupTPMCgroup(vm) < 0)
+    if (qemuSetupTPMCgroup(vm, vm->def->tpm) < 0)
+        return -1;
+
+    if (qemuSetupTPMCgroup(vm, vm->def->tpmproxy) < 0)
         return -1;
 
     for (i = 0; i < vm->def->nhostdevs; i++) {
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index a1b250fd0b..a344f8a0e6 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -11574,11 +11574,9 @@ qemuDomainSetupAllChardevs(virQEMUDriverConfigPtr cfg G_GNUC_UNUSED,
 
 static int
 qemuDomainSetupTPM(virQEMUDriverConfigPtr cfg G_GNUC_UNUSED,
-                   virDomainObjPtr vm,
+                   virDomainTPMDefPtr dev,
                    const struct qemuDomainCreateDeviceData *data)
 {
-    virDomainTPMDefPtr dev = vm->def->tpm;
-
     if (!dev)
         return 0;
 
@@ -11823,7 +11821,10 @@ qemuDomainBuildNamespace(virQEMUDriverConfigPtr cfg,
     if (qemuDomainSetupAllChardevs(cfg, vm, &data) < 0)
         goto cleanup;
 
-    if (qemuDomainSetupTPM(cfg, vm, &data) < 0)
+    if (qemuDomainSetupTPM(cfg, vm->def->tpm, &data) < 0)
+        goto cleanup;
+
+    if (qemuDomainSetupTPM(cfg, vm->def->tpmproxy, &data) < 0)
         goto cleanup;
 
     if (qemuDomainSetupAllGraphics(cfg, vm, &data) < 0)
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index 584d1375b8..7210be3532 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -3602,6 +3602,7 @@ qemuValidateDomainDeviceDefTPM(virDomainTPMDef *tpm,
     case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH:
         if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_TPM_PASSTHROUGH))
             goto no_support;
+
         break;
 
     case VIR_DOMAIN_TPM_TYPE_EMULATOR:
@@ -3623,6 +3624,17 @@ qemuValidateDomainDeviceDefTPM(virDomainTPMDef *tpm,
     case VIR_DOMAIN_TPM_MODEL_SPAPR:
         flag = QEMU_CAPS_DEVICE_TPM_SPAPR;
         break;
+    case VIR_DOMAIN_TPM_MODEL_SPAPR_PROXY:
+        if (!ARCH_IS_PPC64(def->os.arch)) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                           _("TPM Proxy model %s is only available for "
+                             "PPC64 guests"),
+                          virDomainTPMModelTypeToString(tpm->model));
+            return -1;
+        }
+
+        flag = QEMU_CAPS_DEVICE_SPAPR_TPM_PROXY;
+        break;
     case VIR_DOMAIN_TPM_MODEL_LAST:
     default:
         virReportEnumRangeError(virDomainTPMModel, tpm->model);
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index bdc2d7edf3..e0542d2839 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -1980,6 +1980,13 @@ virSecurityDACRestoreAllLabel(virSecurityManagerPtr mgr,
             rc = -1;
     }
 
+    if (def->tpmproxy) {
+        if (virSecurityDACRestoreTPMFileLabel(mgr,
+                                              def,
+                                              def->tpmproxy) < 0)
+            rc = -1;
+    }
+
     if (def->sev) {
         if (virSecurityDACRestoreSEVLabel(mgr, def) < 0)
             rc = -1;
@@ -2159,6 +2166,13 @@ virSecurityDACSetAllLabel(virSecurityManagerPtr mgr,
             return -1;
     }
 
+    if (def->tpmproxy) {
+        if (virSecurityDACSetTPMFileLabel(mgr,
+                                          def,
+                                          def->tpmproxy) < 0)
+            return -1;
+    }
+
     if (def->sev) {
         if (virSecurityDACSetSEVLabel(mgr, def) < 0)
             return -1;
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index 9a929debe1..e80d43c0a7 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -2763,6 +2763,12 @@ virSecuritySELinuxRestoreAllLabel(virSecurityManagerPtr mgr,
             rc = -1;
     }
 
+    if (def->tpmproxy) {
+        if (virSecuritySELinuxRestoreTPMFileLabelInt(mgr, def,
+                                                     def->tpmproxy) < 0)
+            rc = -1;
+    }
+
     struct _virSecuritySELinuxChardevCallbackData chardevData = {
         .mgr = mgr,
         .chardevStdioLogd = chardevStdioLogd
@@ -3171,6 +3177,11 @@ virSecuritySELinuxSetAllLabel(virSecurityManagerPtr mgr,
             return -1;
     }
 
+    if (def->tpmproxy) {
+        if (virSecuritySELinuxSetTPMFileLabel(mgr, def, def->tpmproxy) < 0)
+            return -1;
+    }
+
     struct _virSecuritySELinuxChardevCallbackData chardevData = {
         .mgr = mgr,
         .chardevStdioLogd = chardevStdioLogd
-- 
2.26.2