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 @@ -11,6 +11,8 @@ #include #pragma GCC diagnostic pop +#include "qemu_fwcfg.h" + #define ACPI_GAS_ACCESS_WIDTH_LEGACY 0 #define ACPI_GAS_ACCESS_WIDTH_UNDEFINED 0 #define ACPI_GAS_ACCESS_WIDTH_BYTE 1 @@ -59,8 +61,6 @@ } \ } while (0) -#define QEMU_FWCFG_MAX_NAME 56 - struct basl_table; void basl_fill_gas(ACPI_GENERIC_ADDRESS *gas, uint8_t space_id, 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 @@ -20,6 +20,7 @@ #include #include "basl.h" +#include "qemu_loader.h" struct basl_table_checksum { STAILQ_ENTRY(basl_table_checksum) chain; @@ -56,6 +57,8 @@ static STAILQ_HEAD(basl_table_list, basl_table) basl_tables = STAILQ_HEAD_INITIALIZER( basl_tables); +static struct qemu_loader *basl_loader; + static __inline uint64_t basl_le_dec(void *pp, size_t len) { @@ -163,6 +166,12 @@ } memcpy(gva, table->data, table->len); + /* Cause guest bios to copy the ACPI table into guest memory. */ + BASL_EXEC( + qemu_fwcfg_add_file(table->fwcfg_name, table->len, table->data)); + BASL_EXEC(qemu_loader_alloc(basl_loader, table->fwcfg_name, + table->alignment, QEMU_LOADER_ALLOC_HIGH)); + return (0); } @@ -219,6 +228,10 @@ sum += *(gva + i); } *checksum_gva = -sum; + + /* Cause guest bios to patch the checksum. */ + BASL_EXEC(qemu_loader_add_checksum(basl_loader, + table->fwcfg_name, checksum->off, checksum->start, len)); } return (0); @@ -286,6 +299,11 @@ val = basl_le_dec(gva + pointer->off, pointer->size); val += BHYVE_ACPI_BASE + src_table->off; basl_le_enc(gva + pointer->off, val, pointer->size); + + /* Cause guest bios to patch the pointer. */ + BASL_EXEC( + qemu_loader_add_pointer(basl_loader, table->fwcfg_name, + src_table->fwcfg_name, pointer->off, pointer->size)); } return (0); @@ -335,6 +353,7 @@ */ BASL_EXEC(basl_finish_patch_checksums(table)); } + BASL_EXEC(qemu_loader_finish(basl_loader)); return (0); } @@ -342,7 +361,7 @@ int basl_init(void) { - return (0); + return (qemu_loader_create(&basl_loader, QEMU_FWCFG_FILE_TABLE_LOADER)); } int diff --git a/usr.sbin/bhyve/qemu_fwcfg.h b/usr.sbin/bhyve/qemu_fwcfg.h --- a/usr.sbin/bhyve/qemu_fwcfg.h +++ b/usr.sbin/bhyve/qemu_fwcfg.h @@ -13,6 +13,8 @@ #define QEMU_FWCFG_MAX_ENTRIES 0x4000 #define QEMU_FWCFG_MAX_NAME 56 +#define QEMU_FWCFG_FILE_TABLE_LOADER "etc/table-loader" + struct qemu_fwcfg_item { uint32_t size; uint8_t *data;