git: e09778575817 - main - bhyve: add basic TPM emulation struct

From: Corvin Köhne <corvink_at_FreeBSD.org>
Date: Fri, 16 Jun 2023 06:23:02 UTC
The branch main has been updated by corvink:

URL: https://cgit.FreeBSD.org/src/commit/?id=e09778575817badd574389382317b46b4213ecf4

commit e09778575817badd574389382317b46b4213ecf4
Author:     Corvin Köhne <corvink@FreeBSD.org>
AuthorDate: 2023-05-15 11:49:42 +0000
Commit:     Corvin Köhne <corvink@FreeBSD.org>
CommitDate: 2023-06-16 06:18:39 +0000

    bhyve: add basic TPM emulation struct
    
    This struct will be used to implement various TPM emulations like a TPM
    passthrough or a virtual TPM.
    
    Reviewed by:            markj
    MFC after:              1 week
    Sponsored by:           Beckhoff Automation GmbH & Co. KG
    Differential Revision:  https://reviews.freebsd.org/D40454
---
 usr.sbin/bhyve/tpm_device.c | 29 +++++++++++++++++++++++++++++
 usr.sbin/bhyve/tpm_emul.h   | 22 ++++++++++++++++++++++
 2 files changed, 51 insertions(+)

diff --git a/usr.sbin/bhyve/tpm_device.c b/usr.sbin/bhyve/tpm_device.c
index e48f9df14701..3a847cc53a9b 100644
--- a/usr.sbin/bhyve/tpm_device.c
+++ b/usr.sbin/bhyve/tpm_device.c
@@ -17,13 +17,18 @@
 #include "acpi_device.h"
 #include "config.h"
 #include "tpm_device.h"
+#include "tpm_emul.h"
 
 #define TPM_ACPI_DEVICE_NAME "TPM"
 #define TPM_ACPI_HARDWARE_ID "MSFT0101"
 
+SET_DECLARE(tpm_emul_set, struct tpm_emul);
+
 struct tpm_device {
 	struct vmctx *vm_ctx;
 	struct acpi_device *acpi_dev;
+	struct tpm_emul *emul;
+	void *emul_sc;
 };
 
 static const struct acpi_device_emul tpm_acpi_device_emul = {
@@ -37,6 +42,9 @@ tpm_device_destroy(struct tpm_device *const dev)
 	if (dev == NULL)
 		return;
 
+	if (dev->emul != NULL && dev->emul->deinit != NULL)
+		dev->emul->deinit(dev->emul_sc);
+
 	acpi_device_destroy(dev->acpi_dev);
 	free(dev);
 }
@@ -46,6 +54,7 @@ tpm_device_create(struct tpm_device **const new_dev, struct vmctx *const vm_ctx,
     nvlist_t *const nvl)
 {
 	struct tpm_device *dev = NULL;
+	struct tpm_emul **ppemul;
 	const char *value;
 	int error;
 
@@ -75,6 +84,26 @@ tpm_device_create(struct tpm_device **const new_dev, struct vmctx *const vm_ctx,
 	if (error)
 		goto err_out;
 
+	value = get_config_value_node(nvl, "type");
+	assert(value != NULL);
+	SET_FOREACH(ppemul, tpm_emul_set) {
+		if (strcmp(value, (*ppemul)->name))
+			continue;
+		dev->emul = *ppemul;
+		break;
+	}
+	if (dev->emul == NULL) {
+		warnx("TPM emulation \"%s\" not found", value);
+		error = EINVAL;
+		goto err_out;
+	}
+
+	if (dev->emul->init) {
+		error = dev->emul->init(&dev->emul_sc, nvl);
+		if (error)
+			goto err_out;
+	}
+
 	*new_dev = dev;
 
 	return (0);
diff --git a/usr.sbin/bhyve/tpm_emul.h b/usr.sbin/bhyve/tpm_emul.h
new file mode 100644
index 000000000000..f75c0318d37e
--- /dev/null
+++ b/usr.sbin/bhyve/tpm_emul.h
@@ -0,0 +1,22 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2023 Beckhoff Automation GmbH & Co. KG
+ * Author: Corvin Köhne <corvink@FreeBSD.org>
+ */
+
+#pragma once
+
+#include <sys/linker_set.h>
+
+#include "config.h"
+
+struct tpm_device;
+
+struct tpm_emul {
+	const char *name;
+
+	int (*init)(void **sc, nvlist_t *nvl);
+	void (*deinit)(void *sc);
+};
+#define TPM_EMUL_SET(x) DATA_SET(tpm_emul_set, x)