xref: /freebsd/usr.sbin/bhyve/tpm_device.c (revision 624f956bd91f118d12b2fef5ff01521ed7d8a935)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2023 Beckhoff Automation GmbH & Co. KG
5  * Author: Corvin Köhne <corvink@FreeBSD.org>
6  */
7 
8 #include <sys/types.h>
9 
10 #include <err.h>
11 #include <errno.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <vmmapi.h>
15 
16 #include "acpi_device.h"
17 #include "config.h"
18 #include "tpm_device.h"
19 
20 #define TPM_ACPI_DEVICE_NAME "TPM"
21 #define TPM_ACPI_HARDWARE_ID "MSFT0101"
22 
23 struct tpm_device {
24 	struct vmctx *vm_ctx;
25 	struct acpi_device *acpi_dev;
26 };
27 
28 static const struct acpi_device_emul tpm_acpi_device_emul = {
29 	.name = TPM_ACPI_DEVICE_NAME,
30 	.hid = TPM_ACPI_HARDWARE_ID,
31 };
32 
33 void
34 tpm_device_destroy(struct tpm_device *const dev)
35 {
36 	if (dev == NULL)
37 		return;
38 
39 	acpi_device_destroy(dev->acpi_dev);
40 	free(dev);
41 }
42 
43 int
44 tpm_device_create(struct tpm_device **const new_dev, struct vmctx *const vm_ctx,
45     nvlist_t *const nvl)
46 {
47 	struct tpm_device *dev = NULL;
48 	const char *value;
49 	int error;
50 
51 	if (new_dev == NULL || vm_ctx == NULL) {
52 		error = EINVAL;
53 		goto err_out;
54 	}
55 
56 	value = get_config_value_node(nvl, "version");
57 	if (value == NULL || strcmp(value, "2.0")) {
58 		warnx("%s: unsupported tpm version %s", __func__, value);
59 		error = EINVAL;
60 		goto err_out;
61 	}
62 
63 	dev = calloc(1, sizeof(*dev));
64 	if (dev == NULL) {
65 		error = ENOMEM;
66 		goto err_out;
67 	}
68 
69 	dev->vm_ctx = vm_ctx;
70 
71 	error = acpi_device_create(&dev->acpi_dev, dev, dev->vm_ctx,
72 	    &tpm_acpi_device_emul);
73 	if (error)
74 		goto err_out;
75 
76 	*new_dev = dev;
77 
78 	return (0);
79 
80 err_out:
81 	tpm_device_destroy(dev);
82 
83 	return (error);
84 }
85