git: 3a766cd0f1fe - main - bhyve: add basl support for length fields

From: Corvin Köhne <corvink_at_FreeBSD.org>
Date: Tue, 15 Nov 2022 07:28:08 UTC
The branch main has been updated by corvink:

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

commit 3a766cd0f1fed90df8f3fd010357e36e050bceb2
Author:     Corvin Köhne <corvink@FreeBSD.org>
AuthorDate: 2022-04-06 09:10:39 +0000
Commit:     Corvin Köhne <corvink@FreeBSD.org>
CommitDate: 2022-11-15 07:27:09 +0000

    bhyve: add basl support for length fields
    
    ACPI tables have different layouts. So, there's no common position for
    the length field. When tables are build by basl, the length is unknown
    at the beginning. It has to be set after building the table.
    
    Reviewed by:            jhb
    Approved by:            manu (mentor)
    MFC after:              2 weeks
    Sponsored by:           Beckhoff Automation GmbH & Co. KG
    Differential Revision:  https://reviews.freebsd.org/D36989
---
 usr.sbin/bhyve/basl.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++
 usr.sbin/bhyve/basl.h |  1 +
 2 files changed, 59 insertions(+)

diff --git a/usr.sbin/bhyve/basl.c b/usr.sbin/bhyve/basl.c
index 7dfeb8d2acb3..b03c936bd517 100644
--- a/usr.sbin/bhyve/basl.c
+++ b/usr.sbin/bhyve/basl.c
@@ -21,6 +21,12 @@
 
 #include "basl.h"
 
+struct basl_table_length {
+	STAILQ_ENTRY(basl_table_length) chain;
+	uint32_t off;
+	uint8_t size;
+};
+
 struct basl_table {
 	STAILQ_ENTRY(basl_table) chain;
 	struct vmctx *ctx;
@@ -29,6 +35,7 @@ struct basl_table {
 	uint32_t len;
 	uint32_t off;
 	uint32_t alignment;
+	STAILQ_HEAD(basl_table_length_list, basl_table_length) lengths;
 };
 static STAILQ_HEAD(basl_table_list, basl_table) basl_tables = STAILQ_HEAD_INITIALIZER(
     basl_tables);
@@ -102,6 +109,22 @@ basl_finish_install_guest_tables(struct basl_table *const table)
 	return (0);
 }
 
+static int
+basl_finish_set_length(struct basl_table *const table)
+{
+	struct basl_table_length *length;
+
+	STAILQ_FOREACH(length, &table->lengths, chain) {
+		assert(length->off < table->len);
+		assert(length->off + length->size <= table->len);
+
+		basl_le_enc(table->data + length->off, table->len,
+		    length->size);
+	}
+
+	return (0);
+}
+
 int
 basl_finish(void)
 {
@@ -113,6 +136,7 @@ basl_finish(void)
 	}
 
 	STAILQ_FOREACH(table, &basl_tables, chain) {
+		BASL_EXEC(basl_finish_set_length(table));
 		BASL_EXEC(basl_finish_install_guest_tables(table));
 	}
 
@@ -125,6 +149,26 @@ basl_init(void)
 	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 *length;
+
+	length = calloc(1, sizeof(struct basl_table_length));
+	if (length == NULL) {
+		warnx("%s: failed to allocate length", __func__);
+		return (ENOMEM);
+	}
+
+	length->off = off;
+	length->size = size;
+
+	STAILQ_INSERT_TAIL(&table->lengths, length, chain);
+
+	return (0);
+}
+
 int
 basl_table_append_bytes(struct basl_table *const table, const void *const bytes,
     const uint32_t len)
@@ -184,6 +228,18 @@ basl_table_append_int(struct basl_table *const table, const uint64_t val,
 	return (basl_table_append_bytes(table, buf, size));
 }
 
+int
+basl_table_append_length(struct basl_table *const table, const uint8_t size)
+{
+	assert(table != NULL);
+	assert(size <= sizeof(table->len));
+
+	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 *const name, const uint32_t alignment,
@@ -207,6 +263,8 @@ basl_table_create(struct basl_table **const table, struct vmctx *ctx,
 	new_table->alignment = alignment;
 	new_table->off = off;
 
+	STAILQ_INIT(&new_table->lengths);
+
 	STAILQ_INSERT_TAIL(&basl_tables, new_table, chain);
 
 	*table = new_table;
diff --git a/usr.sbin/bhyve/basl.h b/usr.sbin/bhyve/basl.h
index 95164e98ed7a..95c5fd916761 100644
--- a/usr.sbin/bhyve/basl.h
+++ b/usr.sbin/bhyve/basl.h
@@ -43,5 +43,6 @@ int basl_table_append_gas(struct basl_table *table, uint8_t space_id,
     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, uint32_t alignment, uint32_t off);