aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorvin Köhne <corvink@FreeBSD.org>2022-08-29 10:10:43 +0000
committerCorvin Köhne <corvink@FreeBSD.org>2023-06-20 08:58:55 +0000
commit5ea98d326830f25fdeb6fc6ef46a8bccb829b13c (patch)
treede03c74d4fcb492ab12d436394be3c30cb7e49ae
parent24a0fef9dc4f782174232a3e57d50602a0fbae21 (diff)
downloadsrc-5ea98d326830f25fdeb6fc6ef46a8bccb829b13c.tar.gz
src-5ea98d326830f25fdeb6fc6ef46a8bccb829b13c.zip
bhyve/tpm: build TPM2 table by tpm interface
Each tpm has a device specific table. Which table a tpm uses depends on the tpm interface. Reviewed by: markj MFC after: 1 week Sponsored by: Beckhoff Automation GmbH & Co. KG Differential Revision: https://reviews.freebsd.org/D40457
-rw-r--r--usr.sbin/bhyve/tpm_device.c13
-rw-r--r--usr.sbin/bhyve/tpm_intf.h4
-rw-r--r--usr.sbin/bhyve/tpm_intf_crb.c51
3 files changed, 67 insertions, 1 deletions
diff --git a/usr.sbin/bhyve/tpm_device.c b/usr.sbin/bhyve/tpm_device.c
index e1db0bab1ee9..94e9f1ffdc27 100644
--- a/usr.sbin/bhyve/tpm_device.c
+++ b/usr.sbin/bhyve/tpm_device.c
@@ -35,9 +35,22 @@ struct tpm_device {
void *intf_sc;
};
+static int
+tpm_build_acpi_table(const struct acpi_device *const dev)
+{
+ const struct tpm_device *const tpm = acpi_device_get_softc(dev);
+
+ if (tpm->intf->build_acpi_table == NULL) {
+ return (0);
+ }
+
+ return (tpm->intf->build_acpi_table(tpm->intf_sc, tpm->vm_ctx));
+}
+
static const struct acpi_device_emul tpm_acpi_device_emul = {
.name = TPM_ACPI_DEVICE_NAME,
.hid = TPM_ACPI_HARDWARE_ID,
+ .build_table = tpm_build_acpi_table,
};
void
diff --git a/usr.sbin/bhyve/tpm_intf.h b/usr.sbin/bhyve/tpm_intf.h
index 7de7bc6d4435..3003d8fbd754 100644
--- a/usr.sbin/bhyve/tpm_intf.h
+++ b/usr.sbin/bhyve/tpm_intf.h
@@ -7,6 +7,8 @@
#pragma once
+#include <vmmapi.h>
+
#include "config.h"
#include "tpm_device.h"
@@ -30,6 +32,6 @@ struct tpm_intf {
int (*init)(void **sc);
void (*deinit)(void *sc);
- int (*build_acpi_table)(void *sc);
+ int (*build_acpi_table)(void *sc, struct vmctx *vm_ctx);
};
#define TPM_INTF_SET(x) DATA_SET(tpm_intf_set, x)
diff --git a/usr.sbin/bhyve/tpm_intf_crb.c b/usr.sbin/bhyve/tpm_intf_crb.c
index 5fd640b2d5c9..b8ae33c5ec0a 100644
--- a/usr.sbin/bhyve/tpm_intf_crb.c
+++ b/usr.sbin/bhyve/tpm_intf_crb.c
@@ -31,12 +31,20 @@
#define TPM_CRB_ADDRESS 0xFED40000
#define TPM_CRB_REGS_SIZE 0x1000
+#define TPM_CRB_CONTROL_AREA_ADDRESS \
+ (TPM_CRB_ADDRESS + offsetof(struct tpm_crb_regs, ctrl_req))
+#define TPM_CRB_CONTROL_AREA_SIZE TPM_CRB_REGS_SIZE
+
#define TPM_CRB_DATA_BUFFER_ADDRESS \
(TPM_CRB_ADDRESS + offsetof(struct tpm_crb_regs, data_buffer))
#define TPM_CRB_DATA_BUFFER_SIZE 0xF80
#define TPM_CRB_LOCALITIES_MAX 5
+#define TPM_CRB_LOG_AREA_MINIMUM_SIZE (64 * 1024)
+
+#define TPM_CRB_LOG_AREA_FWCFG_NAME "etc/tpm/log"
+
struct tpm_crb_regs {
union tpm_crb_reg_loc_state {
struct {
@@ -156,6 +164,7 @@ static_assert(sizeof(struct tpm_crb_regs) == TPM_CRB_REGS_SIZE,
} while (0)
struct tpm_crb {
+ uint8_t tpm_log_area[TPM_CRB_LOG_AREA_MINIMUM_SIZE];
struct tpm_crb_regs regs;
};
@@ -200,6 +209,13 @@ tpm_crb_init(void **sc)
CRB_RSP_SIZE_WRITE(crb->regs, TPM_CRB_DATA_BUFFER_SIZE);
CRB_RSP_ADDR_WRITE(crb->regs, TPM_CRB_DATA_BUFFER_ADDRESS);
+ error = qemu_fwcfg_add_file(TPM_CRB_LOG_AREA_FWCFG_NAME,
+ TPM_CRB_LOG_AREA_MINIMUM_SIZE, crb->tpm_log_area);
+ if (error) {
+ warnx("%s: failed to add fwcfg file", __func__);
+ goto err_out;
+ }
+
*sc = crb;
return (0);
@@ -224,9 +240,44 @@ tpm_crb_deinit(void *sc)
free(crb);
}
+static int
+tpm_crb_build_acpi_table(void *sc __unused, struct vmctx *vm_ctx)
+{
+ struct basl_table *table;
+
+ BASL_EXEC(basl_table_create(&table, vm_ctx, ACPI_SIG_TPM2,
+ BASL_TABLE_ALIGNMENT));
+
+ /* Header */
+ BASL_EXEC(basl_table_append_header(table, ACPI_SIG_TPM2, 4, 1));
+ /* Platform Class */
+ BASL_EXEC(basl_table_append_int(table, 0, 2));
+ /* Reserved */
+ BASL_EXEC(basl_table_append_int(table, 0, 2));
+ /* Control Address */
+ BASL_EXEC(
+ basl_table_append_int(table, TPM_CRB_CONTROL_AREA_ADDRESS, 8));
+ /* Start Method == (7) Command Response Buffer */
+ BASL_EXEC(basl_table_append_int(table, 7, 4));
+ /* Start Method Specific Parameters */
+ uint8_t parameters[12] = { 0 };
+ BASL_EXEC(basl_table_append_bytes(table, parameters, 12));
+ /* Log Area Minimum Length */
+ BASL_EXEC(
+ basl_table_append_int(table, TPM_CRB_LOG_AREA_MINIMUM_SIZE, 4));
+ /* Log Area Start Address */
+ BASL_EXEC(
+ basl_table_append_fwcfg(table, TPM_CRB_LOG_AREA_FWCFG_NAME, 1, 8));
+
+ BASL_EXEC(basl_table_register_to_rsdt(table));
+
+ return (0);
+}
+
static struct tpm_intf tpm_intf_crb = {
.name = "crb",
.init = tpm_crb_init,
.deinit = tpm_crb_deinit,
+ .build_acpi_table = tpm_crb_build_acpi_table,
};
TPM_INTF_SET(tpm_intf_crb);