Commit 55f8f3cc4f7c47c7896e2ad08e29eccc292c0c68
Committed by
Len Brown
1 parent
e0b91050f2
Exists in
master
and in
7 other branches
ACPICA: Clear reserved fields for incoming ACPI 1.0 FADTs
Fixed a problem with the internal FADT conversion where ACPI 1.0 FADTs that contained invalid non-zero values in reserved fields could cause later failures because these fields have meaning in later revisions of the FADT. For incoming ACPI 1.0 FADTs, these fields are now always zeroed. (Preferred_PM_Profile, PSTATE_CNT, CST_CNT, IAPC_BOOT_FLAGS.) Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Showing 1 changed file with 26 additions and 18 deletions Side-by-side Diff
drivers/acpi/tables/tbfadt.c
... | ... | @@ -211,14 +211,17 @@ |
211 | 211 | * DESCRIPTION: Get a local copy of the FADT and convert it to a common format. |
212 | 212 | * Performs validation on some important FADT fields. |
213 | 213 | * |
214 | + * NOTE: We create a local copy of the FADT regardless of the version. | |
215 | + * | |
214 | 216 | ******************************************************************************/ |
215 | 217 | |
216 | 218 | void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length) |
217 | 219 | { |
218 | 220 | |
219 | 221 | /* |
220 | - * Check if the FADT is larger than what we know about (ACPI 2.0 version). | |
221 | - * Truncate the table, but make some noise. | |
222 | + * Check if the FADT is larger than the largest table that we expect | |
223 | + * (the ACPI 2.0/3.0 version). If so, truncate the table, and issue | |
224 | + * a warning. | |
222 | 225 | */ |
223 | 226 | if (length > sizeof(struct acpi_table_fadt)) { |
224 | 227 | ACPI_WARNING((AE_INFO, |
225 | 228 | |
... | ... | @@ -227,10 +230,12 @@ |
227 | 230 | sizeof(struct acpi_table_fadt))); |
228 | 231 | } |
229 | 232 | |
230 | - /* Copy the entire FADT locally. Zero first for tb_convert_fadt */ | |
233 | + /* Clear the entire local FADT */ | |
231 | 234 | |
232 | 235 | ACPI_MEMSET(&acpi_gbl_FADT, 0, sizeof(struct acpi_table_fadt)); |
233 | 236 | |
237 | + /* Copy the original FADT, up to sizeof (struct acpi_table_fadt) */ | |
238 | + | |
234 | 239 | ACPI_MEMCPY(&acpi_gbl_FADT, table, |
235 | 240 | ACPI_MIN(length, sizeof(struct acpi_table_fadt))); |
236 | 241 | |
... | ... | @@ -251,7 +256,7 @@ |
251 | 256 | * RETURN: None |
252 | 257 | * |
253 | 258 | * DESCRIPTION: Converts all versions of the FADT to a common internal format. |
254 | - * -> Expand all 32-bit addresses to 64-bit. | |
259 | + * Expand all 32-bit addresses to 64-bit. | |
255 | 260 | * |
256 | 261 | * NOTE: acpi_gbl_FADT must be of size (struct acpi_table_fadt), |
257 | 262 | * and must contain a copy of the actual FADT. |
258 | 263 | |
... | ... | @@ -292,9 +297,24 @@ |
292 | 297 | } |
293 | 298 | |
294 | 299 | /* |
295 | - * Expand the 32-bit V1.0 addresses to the 64-bit "X" generic address | |
296 | - * structures as necessary. | |
300 | + * For ACPI 1.0 FADTs (revision 1 or 2), ensure that reserved fields which | |
301 | + * should be zero are indeed zero. This will workaround BIOSs that | |
302 | + * inadvertently place values in these fields. | |
303 | + * | |
304 | + * The ACPI 1.0 reserved fields that will be zeroed are the bytes located at | |
305 | + * offset 45, 55, 95, and the word located at offset 109, 110. | |
297 | 306 | */ |
307 | + if (acpi_gbl_FADT.header.revision < 3) { | |
308 | + acpi_gbl_FADT.preferred_profile = 0; | |
309 | + acpi_gbl_FADT.pstate_control = 0; | |
310 | + acpi_gbl_FADT.cst_control = 0; | |
311 | + acpi_gbl_FADT.boot_flags = 0; | |
312 | + } | |
313 | + | |
314 | + /* | |
315 | + * Expand the ACPI 1.0 32-bit V1.0 addresses to the ACPI 2.0 64-bit "X" | |
316 | + * generic address structures as necessary. | |
317 | + */ | |
298 | 318 | for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) { |
299 | 319 | target = |
300 | 320 | ACPI_ADD_PTR(struct acpi_generic_address, &acpi_gbl_FADT, |
... | ... | @@ -348,18 +368,6 @@ |
348 | 368 | acpi_gbl_xpm1b_enable.space_id = |
349 | 369 | acpi_gbl_FADT.xpm1a_event_block.space_id; |
350 | 370 | |
351 | - } | |
352 | - | |
353 | - /* | |
354 | - * For ACPI 1.0 FADTs, ensure that reserved fields (which should be zero) | |
355 | - * are indeed zero. This will workaround BIOSs that inadvertently placed | |
356 | - * values in these fields. | |
357 | - */ | |
358 | - if (acpi_gbl_FADT.header.revision < 3) { | |
359 | - acpi_gbl_FADT.preferred_profile = 0; | |
360 | - acpi_gbl_FADT.pstate_control = 0; | |
361 | - acpi_gbl_FADT.cst_control = 0; | |
362 | - acpi_gbl_FADT.boot_flags = 0; | |
363 | 371 | } |
364 | 372 | } |
365 | 373 |