Skip to content

Commit

Permalink
Tables: Add sanity check for static table load
Browse files Browse the repository at this point in the history
This patch extends sanity check to static table load by invoking
AcpiTbLoadTable() instead of AcpiNsLoadTable().

Some redundant code blocks are therefore reduced:
1. AcpiTbValidateTable() is replaced by AcpiTbGetTable() invoked in
   AcpiTbValidateTableForLoad(), DSDT handling code is thus moved to this
   function as it must be invoked for validated tables;
2. MLC handling in both AcpiNsLoadTable() and AcpiTbLoadTable() can be
   combined into AcpiTbLoadTable(), Reload parameter is added to
   AcpiTbLoadTable() in order to distiguish different table loading stages
   to keep group MLC logics.
Reported by Hans de Goede, fixed by Lv Zheng.

Reported-by: Hans de Goede <hdegoede@redhat.com>
Tested-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
  • Loading branch information
Lv Zheng committed Mar 22, 2017
1 parent 3d9eeb0 commit b6a1943
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 69 deletions.
2 changes: 1 addition & 1 deletion source/components/executer/exconfig.c
Expand Up @@ -293,7 +293,7 @@ AcpiExLoadTableOp (

ACPI_INFO (("Dynamic OEM Table Load:"));
AcpiExExitInterpreter ();
Status = AcpiTbLoadTable (&TableIndex, ParentNode);
Status = AcpiTbLoadTable (&TableIndex, TRUE, ParentNode);
AcpiExEnterInterpreter ();
if (ACPI_FAILURE (Status))
{
Expand Down
18 changes: 0 additions & 18 deletions source/components/namespace/nsload.c
Expand Up @@ -233,24 +233,6 @@ AcpiNsLoadTable (
ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
"**** Completed Table Object Initialization\n"));

/*
* Execute any module-level code that was detected during the table load
* phase. Although illegal since ACPI 2.0, there are many machines that
* contain this type of code. Each block of detected executable AML code
* outside of any control method is wrapped with a temporary control
* method object and placed on a global list. The methods on this list
* are executed below.
*
* This case executes the module-level code for each table immediately
* after the table has been loaded. This provides compatibility with
* other ACPI implementations. Optionally, the execution can be deferred
* until later, see AcpiInitializeObjects.
*/
if (!AcpiGbl_ParseTableAsTermList && !AcpiGbl_GroupModuleLevelCode)
{
AcpiNsExecModuleCodeList ();
}

return_ACPI_STATUS (Status);
}

Expand Down
72 changes: 59 additions & 13 deletions source/components/tables/tbdata.c
Expand Up @@ -1020,6 +1020,7 @@ AcpiTbValidateTableForLoad (
UINT32 i;
ACPI_TABLE_DESC *TableDesc;
ACPI_STATUS Status = AE_OK;
ACPI_TABLE_HEADER *NewDsdt;


/* Acquire the table lock */
Expand All @@ -1038,6 +1039,40 @@ AcpiTbValidateTableForLoad (
goto UnlockAndExit;
}

if (*TableIndex == AcpiGbl_DsdtIndex)
{
/*
* Save the DSDT pointer for simple access. This is the mapped memory
* address. We must take care here because the address of the .Tables
* array can change dynamically as tables are loaded at run-time.
* Note: .Pointer field is not validated until after call to
* AcpiGetTableByIndex().
*/
AcpiGbl_DSDT = TableDesc->Pointer;

/*
* Optionally copy the entire DSDT to local memory (instead of simply
* mapping it.) There are some BIOSs that corrupt or replace the
* original DSDT, creating the need for this option. Default is FALSE,
* do not copy the DSDT.
*/
if (AcpiGbl_CopyDsdtLocally)
{
NewDsdt = AcpiTbCopyDsdt (AcpiGbl_DsdtIndex);
if (NewDsdt)
{
AcpiGbl_DSDT = NewDsdt;
}
}

/*
* Save the original DSDT header for detection of table corruption
* and/or replacement of the DSDT from outside the OS.
*/
memcpy (&AcpiGbl_OriginalDsdtHeader, AcpiGbl_DSDT,
sizeof (ACPI_TABLE_HEADER));
}

/* Check if table is already loaded */

for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i)
Expand Down Expand Up @@ -1087,6 +1122,7 @@ AcpiTbValidateTableForLoad (
* FUNCTION: AcpiTbLoadTable
*
* PARAMETERS: TableIndex - Table index
* Reload - Whether reload should be performed
* ParentNode - Where table index is returned
*
* RETURN: Status
Expand All @@ -1098,6 +1134,7 @@ AcpiTbValidateTableForLoad (
ACPI_STATUS
AcpiTbLoadTable (
UINT32 *TableIndex,
BOOLEAN Reload,
ACPI_NAMESPACE_NODE *ParentNode)
{
ACPI_TABLE_HEADER *Table;
Expand Down Expand Up @@ -1126,23 +1163,32 @@ AcpiTbLoadTable (

Status = AcpiNsLoadTable (*TableIndex, ParentNode);

/* Execute any module-level code that was found in the table */

if (!AcpiGbl_ParseTableAsTermList && AcpiGbl_GroupModuleLevelCode)
/*
* Execute any module-level code that was found in the table. This only
* applies when new grammar support is not set (as MLC are executed in
* place) and dynamic table loading. For static table loading, executes
* MLC here if group module level code is not set, otherwise, it is
* executed in AcpiInitializeObjects().
*/
if (!AcpiGbl_ParseTableAsTermList &&
(Reload || !AcpiGbl_GroupModuleLevelCode))
{
AcpiNsExecModuleCodeList ();
}

/*
* Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is
* responsible for discovering any new wake GPEs by running _PRW methods
* that may have been loaded by this table.
*/
Status = AcpiTbGetOwnerId (*TableIndex, &OwnerId);
if (ACPI_SUCCESS (Status))
if (Reload)
{
AcpiEvUpdateGpes (OwnerId);
}
/*
* Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host
* is responsible for discovering any new wake GPEs by running _PRW
* methods that may have been loaded by this table.
*/
Status = AcpiTbGetOwnerId (*TableIndex, &OwnerId);
if (ACPI_SUCCESS (Status))
{
AcpiEvUpdateGpes (OwnerId);
}
}

/* Invoke table handler */

Expand Down Expand Up @@ -1189,7 +1235,7 @@ AcpiTbInstallAndLoadTable (
goto Exit;
}

Status = AcpiTbLoadTable (&i, AcpiGbl_RootNode);
Status = AcpiTbLoadTable (&i, TRUE, AcpiGbl_RootNode);

Exit:
*TableIndex = i;
Expand Down
41 changes: 4 additions & 37 deletions source/components/tables/tbxfload.c
Expand Up @@ -224,7 +224,6 @@ AcpiTbLoadNamespace (
{
ACPI_STATUS Status;
UINT32 i;
ACPI_TABLE_HEADER *NewDsdt;
ACPI_TABLE_DESC *Table;
UINT32 TablesLoaded = 0;
UINT32 TablesFailed = 0;
Expand All @@ -242,47 +241,16 @@ AcpiTbLoadNamespace (
Table = &AcpiGbl_RootTableList.Tables[AcpiGbl_DsdtIndex];

if (!AcpiGbl_RootTableList.CurrentTableCount ||
!ACPI_COMPARE_NAME (Table->Signature.Ascii, ACPI_SIG_DSDT) ||
ACPI_FAILURE (AcpiTbValidateTable (Table)))
!ACPI_COMPARE_NAME (Table->Signature.Ascii, ACPI_SIG_DSDT))
{
Status = AE_NO_ACPI_TABLES;
goto UnlockAndExit;
}

/*
* Save the DSDT pointer for simple access. This is the mapped memory
* address. We must take care here because the address of the .Tables
* array can change dynamically as tables are loaded at run-time. Note:
* .Pointer field is not validated until after call to AcpiTbValidateTable.
*/
AcpiGbl_DSDT = Table->Pointer;

/*
* Optionally copy the entire DSDT to local memory (instead of simply
* mapping it.) There are some BIOSs that corrupt or replace the original
* DSDT, creating the need for this option. Default is FALSE, do not copy
* the DSDT.
*/
if (AcpiGbl_CopyDsdtLocally)
{
NewDsdt = AcpiTbCopyDsdt (AcpiGbl_DsdtIndex);
if (NewDsdt)
{
AcpiGbl_DSDT = NewDsdt;
}
}

/*
* Save the original DSDT header for detection of table corruption
* and/or replacement of the DSDT from outside the OS.
*/
memcpy (&AcpiGbl_OriginalDsdtHeader, AcpiGbl_DSDT,
sizeof (ACPI_TABLE_HEADER));

/* Load and parse tables */

(void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
Status = AcpiNsLoadTable (AcpiGbl_DsdtIndex, AcpiGbl_RootNode);
Status = AcpiTbLoadTable (&AcpiGbl_DsdtIndex, FALSE, AcpiGbl_RootNode);
(void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
if (ACPI_FAILURE (Status))
{
Expand All @@ -303,16 +271,15 @@ AcpiTbLoadNamespace (
if (!Table->Address ||
(!ACPI_COMPARE_NAME (Table->Signature.Ascii, ACPI_SIG_SSDT) &&
!ACPI_COMPARE_NAME (Table->Signature.Ascii, ACPI_SIG_PSDT) &&
!ACPI_COMPARE_NAME (Table->Signature.Ascii, ACPI_SIG_OSDT)) ||
ACPI_FAILURE (AcpiTbValidateTable (Table)))
!ACPI_COMPARE_NAME (Table->Signature.Ascii, ACPI_SIG_OSDT)))
{
continue;
}

/* Ignore errors while loading tables, get as many as possible */

(void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
Status = AcpiNsLoadTable (i, AcpiGbl_RootNode);
Status = AcpiTbLoadTable (&i, FALSE, AcpiGbl_RootNode);
(void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
if (ACPI_FAILURE (Status))
{
Expand Down
1 change: 1 addition & 0 deletions source/include/actables.h
Expand Up @@ -253,6 +253,7 @@ AcpiTbUninstallTable (
ACPI_STATUS
AcpiTbLoadTable (
UINT32 *TableIndex,
BOOLEAN Reload,
ACPI_NAMESPACE_NODE *ParentNode);

ACPI_STATUS
Expand Down

0 comments on commit b6a1943

Please sign in to comment.