diff --git a/usr.sbin/bhyve/basl.h b/usr.sbin/bhyve/basl.h --- a/usr.sbin/bhyve/basl.h +++ b/usr.sbin/bhyve/basl.h @@ -44,5 +44,6 @@ uint8_t bit_width, uint8_t bit_offset, uint8_t access_width, uint64_t address); int basl_table_append_int(struct basl_table *table, uint64_t val, uint8_t size); +int basl_table_append_length(struct basl_table *table, uint8_t size); int basl_table_create(struct basl_table **table, struct vmctx *ctx, const uint8_t name[QEMU_FWCFG_MAX_NAME], uint32_t alignment, uint32_t off); diff --git a/usr.sbin/bhyve/basl.c b/usr.sbin/bhyve/basl.c --- a/usr.sbin/bhyve/basl.c +++ b/usr.sbin/bhyve/basl.c @@ -36,6 +36,15 @@ STAILQ_HEAD(basl_table_list, basl_table) basl_tables = STAILQ_HEAD_INITIALIZER( basl_tables); +struct basl_table_length { + STAILQ_ENTRY(basl_table_length) chain; + struct basl_table *table; + uint32_t off; + uint8_t size; +}; +STAILQ_HEAD(basl_table_length_list, + basl_table_length) basl_lengths = STAILQ_HEAD_INITIALIZER(basl_lengths); + struct qemu_loader *basl_loader; static int @@ -121,6 +130,21 @@ return (0); } +static int +basl_finish_set_length() +{ + struct basl_table_length *length; + STAILQ_FOREACH (length, &basl_lengths, chain) { + const struct basl_table *const table = length->table; + + uint32_t len_le = htole32(table->len); + + memcpy(table->data + length->off, &len_le, length->size); + } + + return (0); +} + int basl_finish() { @@ -129,6 +153,7 @@ return (EINVAL); } + BASL_EXEC(basl_finish_set_length()); BASL_EXEC(basl_finish_alloc()); return (0); @@ -140,6 +165,26 @@ return (0); } +static int +basl_table_add_length(struct basl_table *const table, const uint32_t off, + const uint8_t size) +{ + struct basl_table_length *const length = calloc(1, + sizeof(struct basl_table_length)); + if (length == NULL) { + warnx("%s: failed to allocate length", __func__); + return (ENOMEM); + } + + length->table = table; + length->off = off; + length->size = size; + + STAILQ_INSERT_TAIL(&basl_lengths, length, chain); + + return (0); +} + int basl_table_append_bytes(struct basl_table *const table, const void *const bytes, const uint32_t len) @@ -196,6 +241,19 @@ return (basl_table_append_bytes(table, &val_le, size)); } +int +basl_table_append_length(struct basl_table *const table, const uint8_t size) +{ + if (table == NULL || size > sizeof(table->len)) { + return (EINVAL); + } + + BASL_EXEC(basl_table_add_length(table, table->len, size)); + BASL_EXEC(basl_table_append_int(table, 0, size)); + + return (0); +} + int basl_table_create(struct basl_table **const table, struct vmctx *ctx, const uint8_t name[QEMU_FWCFG_MAX_NAME], const uint32_t alignment,