Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F109460978
D40458.id123479.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D40458.id123479.diff
View Options
diff --git a/usr.sbin/bhyve/tpm_device.c b/usr.sbin/bhyve/tpm_device.c
--- a/usr.sbin/bhyve/tpm_device.c
+++ b/usr.sbin/bhyve/tpm_device.c
@@ -141,7 +141,7 @@
}
if (dev->intf->init) {
- error = dev->intf->init(&dev->intf_sc);
+ error = dev->intf->init(&dev->intf_sc, dev->emul, dev->emul_sc);
if (error)
goto err_out;
}
diff --git a/usr.sbin/bhyve/tpm_emul.h b/usr.sbin/bhyve/tpm_emul.h
--- a/usr.sbin/bhyve/tpm_emul.h
+++ b/usr.sbin/bhyve/tpm_emul.h
@@ -18,5 +18,7 @@
int (*init)(void **sc, nvlist_t *nvl);
void (*deinit)(void *sc);
+ int (*execute_cmd)(void *sc, void *cmd, uint32_t cmd_size, void *rsp,
+ uint32_t rsp_size);
};
#define TPM_EMUL_SET(x) DATA_SET(tpm_emul_set, x)
diff --git a/usr.sbin/bhyve/tpm_intf.h b/usr.sbin/bhyve/tpm_intf.h
--- a/usr.sbin/bhyve/tpm_intf.h
+++ b/usr.sbin/bhyve/tpm_intf.h
@@ -11,6 +11,7 @@
#include "config.h"
#include "tpm_device.h"
+#include "tpm_emul.h"
#define TPM_INTF_TYPE_FIFO_PTP 0x0
#define TPM_INTF_TYPE_CRB 0x1
@@ -30,7 +31,7 @@
struct tpm_intf {
const char *name;
- int (*init)(void **sc);
+ int (*init)(void **sc, struct tpm_emul *emul, void *emul_sc);
void (*deinit)(void *sc);
int (*build_acpi_table)(void *sc, struct vmctx *vm_ctx);
};
diff --git a/usr.sbin/bhyve/tpm_intf_crb.c b/usr.sbin/bhyve/tpm_intf_crb.c
--- a/usr.sbin/bhyve/tpm_intf_crb.c
+++ b/usr.sbin/bhyve/tpm_intf_crb.c
@@ -26,6 +26,7 @@
#include "config.h"
#include "mem.h"
#include "qemu_fwcfg.h"
+#include "tpm_device.h"
#include "tpm_intf.h"
#define TPM_CRB_ADDRESS 0xFED40000
@@ -45,6 +46,8 @@
#define TPM_CRB_LOG_AREA_FWCFG_NAME "etc/tpm/log"
+#define TPM_CRB_INTF_NAME "crb"
+
struct tpm_crb_regs {
union tpm_crb_reg_loc_state {
struct {
@@ -164,17 +167,82 @@
} while (0)
struct tpm_crb {
+ struct tpm_emul *emul;
+ void *emul_sc;
uint8_t tpm_log_area[TPM_CRB_LOG_AREA_MINIMUM_SIZE];
struct tpm_crb_regs regs;
+ pthread_t thread;
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+ bool closing;
};
+static void *
+tpm_crb_thread(void *const arg)
+{
+ struct tpm_crb *const crb = arg;
+
+ pthread_mutex_lock(&crb->mutex);
+ for (;;) {
+ pthread_cond_wait(&crb->cond, &crb->mutex);
+
+ if (crb->closing)
+ break;
+
+ const uint64_t cmd_addr = CRB_CMD_ADDR_READ(crb->regs);
+ const uint64_t rsp_addr = CRB_RSP_ADDR_READ(crb->regs);
+ const uint32_t cmd_size = CRB_CMD_SIZE_READ(crb->regs);
+ const uint32_t rsp_size = CRB_RSP_SIZE_READ(crb->regs);
+
+ const uint64_t cmd_off = cmd_addr - TPM_CRB_DATA_BUFFER_ADDRESS;
+ const uint64_t rsp_off = rsp_addr - TPM_CRB_DATA_BUFFER_ADDRESS;
+
+ if (cmd_off > TPM_CRB_DATA_BUFFER_SIZE ||
+ cmd_off + cmd_size > TPM_CRB_DATA_BUFFER_SIZE ||
+ rsp_off > TPM_CRB_DATA_BUFFER_SIZE ||
+ rsp_off + rsp_size > TPM_CRB_DATA_BUFFER_SIZE) {
+ warnx(
+ "%s: invalid cmd [%16lx, %16lx] --> [%16lx, %16lx]\n\r",
+ __func__, cmd_addr, cmd_addr + cmd_size, rsp_addr,
+ rsp_addr + rsp_size);
+ break;
+ }
+
+ /*
+ * The command response buffer interface uses a single buffer
+ * for sending a command to and receiving a response from the
+ * tpm. To avoid reading old data from the command buffer which
+ * might be a security issue, we zero out the command buffer
+ * before writing the response into it. The rsp_size parameter
+ * is controlled by the guest and it's not guaranteed that the
+ * response has a size of rsp_size (e.g. if the tpm returned an
+ * error, the response would have a different size than
+ * expected). For that reason, use a second buffer for the
+ * response.
+ */
+ uint8_t rsp[TPM_CRB_DATA_BUFFER_SIZE] = { 0 };
+ crb->emul->execute_cmd(crb->emul_sc,
+ &crb->regs.data_buffer[cmd_off], cmd_size, &rsp[rsp_off],
+ rsp_size);
+
+ memset(crb->regs.data_buffer, 0, TPM_CRB_DATA_BUFFER_SIZE);
+ memcpy(&crb->regs.data_buffer[rsp_off], &rsp[rsp_off], rsp_size);
+
+ crb->regs.ctrl_start.start = false;
+ }
+ pthread_mutex_unlock(&crb->mutex);
+
+ return (NULL);
+}
+
static int
-tpm_crb_init(void **sc)
+tpm_crb_init(void **sc, struct tpm_emul *emul, void *emul_sc)
{
struct tpm_crb *crb = NULL;
int error;
assert(sc != NULL);
+ assert(emul != NULL);
crb = calloc(1, sizeof(struct tpm_crb));
if (crb == NULL) {
@@ -185,6 +253,9 @@
memset(crb, 0, sizeof(*crb));
+ crb->emul = emul;
+ crb->emul_sc = emul_sc;
+
crb->regs.loc_state.tpm_req_valid_sts = true;
crb->regs.loc_state.tpm_established = true;
@@ -216,6 +287,26 @@
goto err_out;
}
+ error = pthread_mutex_init(&crb->mutex, NULL);
+ if (error) {
+ warnc(error, "%s: failed to init mutex", __func__);
+ goto err_out;
+ }
+
+ error = pthread_cond_init(&crb->cond, NULL);
+ if (error) {
+ warnc(error, "%s: failed to init cond", __func__);
+ goto err_out;
+ }
+
+ error = pthread_create(&crb->thread, NULL, tpm_crb_thread, crb);
+ if (error) {
+ warnx("%s: failed to create thread\n", __func__);
+ goto err_out;
+ }
+
+ pthread_set_name_np(crb->thread, "tpm_intf_crb");
+
*sc = crb;
return (0);
@@ -237,6 +328,13 @@
crb = sc;
+ crb->closing = true;
+ pthread_cond_signal(&crb->cond);
+ pthread_join(crb->thread, NULL);
+
+ pthread_cond_destroy(&crb->cond);
+ pthread_mutex_destroy(&crb->mutex);
+
free(crb);
}
@@ -275,7 +373,7 @@
}
static struct tpm_intf tpm_intf_crb = {
- .name = "crb",
+ .name = TPM_CRB_INTF_NAME,
.init = tpm_crb_init,
.deinit = tpm_crb_deinit,
.build_acpi_table = tpm_crb_build_acpi_table,
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Feb 6, 9:18 AM (20 h, 17 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16490522
Default Alt Text
D40458.id123479.diff (5 KB)
Attached To
Mode
D40458: bhyve/tpm: create crb thread for sending tpm commands
Attached
Detach File
Event Timeline
Log In to Comment