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