ACK: [PATCH] Fix FADT update in creation of fake FACS table.
Alex Hung
alex.hung at canonical.com
Wed Nov 25 02:15:47 UTC 2015
On 2015-11-23 10:49 PM, jvohanka wrote:
> If a FACS ACPI table is not found, a fake one is created and
> a fake physical address is assigned to it. This fake physical
> address is written to FIRMWARE_CTRL and X_FIRMWARE_CTRL fields
> of FADT table. The problem is that the checksum of the FADT
> table is not updated to reflect the change in FIRMWARE_CTRL
> and X_FIRMWARE_CTRL fields. Thus, the 'checksum' test falsely
> reports:
>
> FAILED [MEDIUM] ACPITableChecksum: Test 1, Table FACP has
> incorrect checksum, expected 0xe8, got 0xcf.
>
> This patch changes the update of the FADT table. If one of
> X_FIRMWARE_CTRL, FIRMWARE_CTRL fields is nonzero then that
> value is used as physical address of FACS table. If both
> fields are zero then a fake physical address is assigned
> to FACS, written to FADT table and the checksum of the FADT
> table is updated.
>
> Signed-off-by: jvohanka <jvohanka at redhat.com>
> ---
> src/lib/src/fwts_acpi_tables.c | 23 +++++++++++++++++------
> 1 file changed, 17 insertions(+), 6 deletions(-)
>
> diff --git a/src/lib/src/fwts_acpi_tables.c b/src/lib/src/fwts_acpi_tables.c
> index 0aab404..6dcf7f8 100644
> --- a/src/lib/src/fwts_acpi_tables.c
> +++ b/src/lib/src/fwts_acpi_tables.c
> @@ -936,7 +936,7 @@ static int fwts_acpi_load_tables_fixup(fwts_framework *fw)
> facs = (fwts_acpi_table_facs *)table->data;
> else {
> size_t size = 64;
> - uint64_t facs_fake_addr;
> + uint64_t facs_addr;
>
> /* This is most unexpected, so warn about it */
> fwts_log_warning(fw, "No FACS found, fwts has faked one instead.");
> @@ -949,12 +949,23 @@ static int fwts_acpi_load_tables_fixup(fwts_framework *fw)
> facs->hardware_signature = 0xf000a200; /* Some signature */
> facs->flags = 0;
> facs->version = 2;
> - facs_fake_addr = fwts_fake_physical_addr(size);
> - fadt->firmware_control = (uint32_t)facs_fake_addr;
> - if (fadt->header.length >= 140)
> - fadt->x_firmware_ctrl = (uint64_t)facs_fake_addr;
>
> - fwts_acpi_add_table("FACS", facs, (uint64_t)facs_fake_addr,
> + /* Get physical address of FACS, try to take it from FACS first,
> + and if that fails, create a fake one and update FACS */
> + if (fadt->header.length >= 140 && fadt->x_firmware_ctrl != 0) {
> + facs_addr = fadt->x_firmware_ctrl;
> + } else if (fadt->firmware_control != 0) {
> + facs_addr = (uint64_t)fadt->firmware_control;
> + } else {
> + facs_addr = (uint64_t)fwts_fake_physical_addr(size);
> + if (fadt->header.length >= 140)
> + fadt->x_firmware_ctrl = facs_addr;
> + else
> + fadt->firmware_control = (uint32_t)facs_addr;
> + fadt->header.checksum -= fwts_checksum((uint8_t*)&facs_addr, sizeof(facs_addr));
> + }
> +
> + fwts_acpi_add_table("FACS", facs, (uint64_t)facs_addr,
> size, FWTS_ACPI_TABLE_FROM_FIXUP);
> }
>
>
Acked-by: Alex Hung <alex.hung at canonical.com>
More information about the fwts-devel
mailing list