diff --git a/usr.sbin/bhyve/acpi.c b/usr.sbin/bhyve/acpi.c --- a/usr.sbin/bhyve/acpi.c +++ b/usr.sbin/bhyve/acpi.c @@ -38,20 +38,6 @@ * * The tables are placed in the guest's ROM area just below 1MB physical, * above the MPTable. - * - * Layout (No longer correct at FADT and beyond due to properly - * calculating the size of the MADT to allow for changes to - * VM_MAXCPU above 21 which overflows this layout.) - * ------ - * RSDP -> 0xf2400 (36 bytes fixed) - * RSDT -> 0xf2440 (36 bytes + 4*7 table addrs, 4 used) - * XSDT -> 0xf2480 (36 bytes + 8*7 table addrs, 4 used) - * MADT -> 0xf2500 (depends on #CPUs) - * FADT -> 0xf2600 (268 bytes) - * HPET -> 0xf2740 (56 bytes) - * MCFG -> 0xf2780 (60 bytes) - * FACS -> 0xf27C0 (64 bytes) - * DSDT -> 0xf2800 (variable - can go up to 0x100000) */ #include @@ -79,32 +65,6 @@ #include "pci_emul.h" #include "vmgenc.h" -/* - * Define the base address of the ACPI tables, the sizes of some tables, - * and the offsets to the individual tables, - */ -#define RSDT_OFFSET 0x040 -#define XSDT_OFFSET 0x080 -#define MADT_OFFSET 0x100 -/* - * The MADT consists of: - * 44 Fixed Header - * 8 * maxcpu Processor Local APIC entries - * 12 I/O APIC entry - * 2 * 10 Interrupt Source Override entries - * 6 Local APIC NMI entry - */ -#define MADT_SIZE roundup2((44 + basl_ncpu*8 + 12 + 2*10 + 6), 0x100) -#define FADT_OFFSET (MADT_OFFSET + MADT_SIZE) -#define FADT_SIZE 0x140 -#define HPET_OFFSET (FADT_OFFSET + FADT_SIZE) -#define HPET_SIZE 0x40 -#define MCFG_OFFSET (HPET_OFFSET + HPET_SIZE) -#define MCFG_SIZE 0x40 -#define FACS_OFFSET (MCFG_OFFSET + MCFG_SIZE) -#define FACS_SIZE 0x40 -#define DSDT_OFFSET (FACS_OFFSET + FACS_SIZE) - #define BHYVE_ASL_TEMPLATE "bhyve.XXXXXXX" #define BHYVE_ASL_SUFFIX ".aml" #define BHYVE_ASL_COMPILER "/usr/sbin/iasl" @@ -335,7 +295,7 @@ } static int -basl_load(struct vmctx *ctx, int fd, uint64_t off) +basl_load(struct vmctx *ctx, int fd) { struct stat sb; void *addr; @@ -354,15 +314,14 @@ uint8_t name[ACPI_NAMESEG_SIZE + 1] = { 0 }; memcpy(name, addr, sizeof(name) - 1 /* last char is '\0' */); - BASL_EXEC( - basl_table_create(&table, ctx, name, BASL_TABLE_ALIGNMENT, off)); + BASL_EXEC(basl_table_create(&table, ctx, name, BASL_TABLE_ALIGNMENT)); BASL_EXEC(basl_table_append_bytes(table, addr, sb.st_size)); return (0); } static int -basl_compile(struct vmctx *ctx, int (*fwrite_section)(FILE *), uint64_t offset) +basl_compile(struct vmctx *ctx, int (*fwrite_section)(FILE *)) { struct basl_fio io[2]; static char iaslbuf[3*MAXPATHLEN + 10]; @@ -396,7 +355,7 @@ * Copy the aml output file into guest * memory at the specified location */ - err = basl_load(ctx, io[1].fd, offset); + err = basl_load(ctx, io[1].fd); } } basl_end(&io[0], &io[1]); @@ -454,7 +413,7 @@ static int build_dsdt(struct vmctx *const ctx) { - BASL_EXEC(basl_compile(ctx, basl_fwrite_dsdt, DSDT_OFFSET)); + BASL_EXEC(basl_compile(ctx, basl_fwrite_dsdt)); return (0); } @@ -477,7 +436,7 @@ facs.OspmFlags = htole32(0); BASL_EXEC(basl_table_create(&table, ctx, ACPI_SIG_FACS, - BASL_TABLE_ALIGNMENT_FACS, FACS_OFFSET)); + BASL_TABLE_ALIGNMENT_FACS)); BASL_EXEC(basl_table_append_bytes(table, &facs, sizeof(facs))); return (0); @@ -488,8 +447,8 @@ { struct basl_table *fadt; - BASL_EXEC(basl_table_create(&fadt, ctx, ACPI_SIG_FADT, - BASL_TABLE_ALIGNMENT, FADT_OFFSET)); + BASL_EXEC( + basl_table_create(&fadt, ctx, ACPI_SIG_FADT, BASL_TABLE_ALIGNMENT)); /* Header */ BASL_EXEC(basl_table_append_header(fadt, ACPI_SIG_FADT, 5, 1)); @@ -637,8 +596,8 @@ { struct basl_table *hpet; - BASL_EXEC(basl_table_create(&hpet, ctx, ACPI_SIG_HPET, - BASL_TABLE_ALIGNMENT, HPET_OFFSET)); + BASL_EXEC( + basl_table_create(&hpet, ctx, ACPI_SIG_HPET, BASL_TABLE_ALIGNMENT)); /* Header */ BASL_EXEC(basl_table_append_header(hpet, ACPI_SIG_HPET, 1, 1)); @@ -667,8 +626,8 @@ { struct basl_table *madt; - BASL_EXEC(basl_table_create(&madt, ctx, ACPI_SIG_MADT, - BASL_TABLE_ALIGNMENT, MADT_OFFSET)); + BASL_EXEC( + basl_table_create(&madt, ctx, ACPI_SIG_MADT, BASL_TABLE_ALIGNMENT)); /* Header */ BASL_EXEC(basl_table_append_header(madt, ACPI_SIG_MADT, 1, 1)); @@ -764,8 +723,8 @@ { struct basl_table *mcfg; - BASL_EXEC(basl_table_create(&mcfg, ctx, ACPI_SIG_MCFG, - BASL_TABLE_ALIGNMENT, MCFG_OFFSET)); + BASL_EXEC( + basl_table_create(&mcfg, ctx, ACPI_SIG_MCFG, BASL_TABLE_ALIGNMENT)); /* Header */ BASL_EXEC(basl_table_append_header(mcfg, ACPI_SIG_MCFG, 1, 1)); @@ -796,7 +755,7 @@ struct basl_table *rsdp; BASL_EXEC(basl_table_create(&rsdp, ctx, ACPI_RSDP_NAME, - BASL_TABLE_ALIGNMENT, 0)); + BASL_TABLE_ALIGNMENT)); /* Signature */ BASL_EXEC(basl_table_append_bytes(rsdp, ACPI_SIG_RSDP, @@ -827,8 +786,8 @@ static int build_rsdt(struct vmctx *const ctx) { - BASL_EXEC(basl_table_create(&rsdt, ctx, ACPI_SIG_RSDT, - BASL_TABLE_ALIGNMENT, RSDT_OFFSET)); + BASL_EXEC( + basl_table_create(&rsdt, ctx, ACPI_SIG_RSDT, BASL_TABLE_ALIGNMENT)); /* Header */ BASL_EXEC(basl_table_append_header(rsdt, ACPI_SIG_RSDT, 1, 1)); @@ -840,8 +799,8 @@ static int build_xsdt(struct vmctx *const ctx) { - BASL_EXEC(basl_table_create(&xsdt, ctx, ACPI_SIG_XSDT, - BASL_TABLE_ALIGNMENT, XSDT_OFFSET)); + BASL_EXEC( + basl_table_create(&xsdt, ctx, ACPI_SIG_XSDT, BASL_TABLE_ALIGNMENT)); /* Header */ BASL_EXEC(basl_table_append_header(xsdt, ACPI_SIG_XSDT, 1, 1)); 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 @@ -54,4 +54,4 @@ int basl_table_append_pointer(struct basl_table *table, const uint8_t src_signature[ACPI_NAMESEG_SIZE], uint8_t size); int basl_table_create(struct basl_table **table, struct vmctx *ctx, - const uint8_t *name, uint32_t alignment, uint32_t off); + const uint8_t *name, uint32_t alignment); 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 @@ -123,10 +123,18 @@ } static int -basl_finish_install_guest_tables(struct basl_table *const table) +basl_finish_install_guest_tables(struct basl_table *const table, uint32_t *const off) { void *gva; + table->off = roundup2(*off, table->alignment); + *off = table->off + table->len; + if (*off <= table->off) { + warnx("%s: invalid table length 0x%8x @ offset 0x%8x", __func__, + table->len, table->off); + return (EFAULT); + } + /* * Install ACPI tables directly in guest memory for use by guests which * do not boot via EFI. EFI ROMs provide a pointer to the firmware @@ -290,6 +298,7 @@ basl_finish(void) { struct basl_table *table; + uint32_t off = 0; if (STAILQ_EMPTY(&basl_tables)) { warnx("%s: no ACPI tables found", __func__); @@ -303,7 +312,7 @@ */ STAILQ_FOREACH(table, &basl_tables, chain) { BASL_EXEC(basl_finish_set_length(table)); - BASL_EXEC(basl_finish_install_guest_tables(table)); + BASL_EXEC(basl_finish_install_guest_tables(table, &off)); } STAILQ_FOREACH(table, &basl_tables, chain) { BASL_EXEC(basl_finish_patch_pointers(table)); @@ -524,8 +533,7 @@ int basl_table_create(struct basl_table **const table, struct vmctx *ctx, - const uint8_t *const name, const uint32_t alignment, - const uint32_t off) + const uint8_t *const name, const uint32_t alignment) { struct basl_table *new_table; @@ -543,7 +551,6 @@ "etc/acpi/%s", name); new_table->alignment = alignment; - new_table->off = off; STAILQ_INIT(&new_table->checksums); STAILQ_INIT(&new_table->lengths);