diff options
Diffstat (limited to 'drivers/acpi/tables')
-rw-r--r-- | drivers/acpi/tables/tbget.c | 12 | ||||
-rw-r--r-- | drivers/acpi/tables/tbinstal.c | 21 | ||||
-rw-r--r-- | drivers/acpi/tables/tbrsdt.c | 27 | ||||
-rw-r--r-- | drivers/acpi/tables/tbxface.c | 32 |
4 files changed, 71 insertions, 21 deletions
diff --git a/drivers/acpi/tables/tbget.c b/drivers/acpi/tables/tbget.c index 99eacceff563..7856db759af0 100644 --- a/drivers/acpi/tables/tbget.c +++ b/drivers/acpi/tables/tbget.c | |||
@@ -320,6 +320,16 @@ acpi_tb_get_this_table(struct acpi_pointer *address, | |||
320 | 320 | ||
321 | ACPI_FUNCTION_TRACE(tb_get_this_table); | 321 | ACPI_FUNCTION_TRACE(tb_get_this_table); |
322 | 322 | ||
323 | /* Validate minimum length */ | ||
324 | |||
325 | if (header->length < sizeof(struct acpi_table_header)) { | ||
326 | ACPI_ERROR((AE_INFO, | ||
327 | "Table length (%X) is smaller than minimum (%X)", | ||
328 | header->length, sizeof(struct acpi_table_header))); | ||
329 | |||
330 | return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH); | ||
331 | } | ||
332 | |||
323 | /* | 333 | /* |
324 | * Flags contains the current processor mode (Virtual or Physical | 334 | * Flags contains the current processor mode (Virtual or Physical |
325 | * addressing) The pointer_type is either Logical or Physical | 335 | * addressing) The pointer_type is either Logical or Physical |
@@ -356,7 +366,7 @@ acpi_tb_get_this_table(struct acpi_pointer *address, | |||
356 | */ | 366 | */ |
357 | status = acpi_os_map_memory(address->pointer.physical, | 367 | status = acpi_os_map_memory(address->pointer.physical, |
358 | (acpi_size) header->length, | 368 | (acpi_size) header->length, |
359 | (void *)&full_table); | 369 | ACPI_CAST_PTR(void, &full_table)); |
360 | if (ACPI_FAILURE(status)) { | 370 | if (ACPI_FAILURE(status)) { |
361 | ACPI_ERROR((AE_INFO, | 371 | ACPI_ERROR((AE_INFO, |
362 | "Could not map memory for table [%4.4s] at %8.8X%8.8X for length %X", | 372 | "Could not map memory for table [%4.4s] at %8.8X%8.8X for length %X", |
diff --git a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c index 7ca2df75bb11..1668a232fb67 100644 --- a/drivers/acpi/tables/tbinstal.c +++ b/drivers/acpi/tables/tbinstal.c | |||
@@ -256,7 +256,7 @@ acpi_tb_init_table_descriptor(acpi_table_type table_type, | |||
256 | 256 | ||
257 | status = acpi_ut_allocate_owner_id(&table_desc->owner_id); | 257 | status = acpi_ut_allocate_owner_id(&table_desc->owner_id); |
258 | if (ACPI_FAILURE(status)) { | 258 | if (ACPI_FAILURE(status)) { |
259 | return_ACPI_STATUS(status); | 259 | goto error_exit1; |
260 | } | 260 | } |
261 | 261 | ||
262 | /* Install the table into the global data structure */ | 262 | /* Install the table into the global data structure */ |
@@ -274,8 +274,8 @@ acpi_tb_init_table_descriptor(acpi_table_type table_type, | |||
274 | * at this location, so return an error. | 274 | * at this location, so return an error. |
275 | */ | 275 | */ |
276 | if (list_head->next) { | 276 | if (list_head->next) { |
277 | ACPI_FREE(table_desc); | 277 | status = AE_ALREADY_EXISTS; |
278 | return_ACPI_STATUS(AE_ALREADY_EXISTS); | 278 | goto error_exit2; |
279 | } | 279 | } |
280 | 280 | ||
281 | table_desc->next = list_head->next; | 281 | table_desc->next = list_head->next; |
@@ -335,6 +335,17 @@ acpi_tb_init_table_descriptor(acpi_table_type table_type, | |||
335 | table_info->owner_id = table_desc->owner_id; | 335 | table_info->owner_id = table_desc->owner_id; |
336 | table_info->installed_desc = table_desc; | 336 | table_info->installed_desc = table_desc; |
337 | return_ACPI_STATUS(AE_OK); | 337 | return_ACPI_STATUS(AE_OK); |
338 | |||
339 | /* Error exit with cleanup */ | ||
340 | |||
341 | error_exit2: | ||
342 | |||
343 | acpi_ut_release_owner_id(&table_desc->owner_id); | ||
344 | |||
345 | error_exit1: | ||
346 | |||
347 | ACPI_FREE(table_desc); | ||
348 | return_ACPI_STATUS(status); | ||
338 | } | 349 | } |
339 | 350 | ||
340 | /******************************************************************************* | 351 | /******************************************************************************* |
@@ -525,6 +536,10 @@ struct acpi_table_desc *acpi_tb_uninstall_table(struct acpi_table_desc | |||
525 | 536 | ||
526 | acpi_tb_delete_single_table(table_desc); | 537 | acpi_tb_delete_single_table(table_desc); |
527 | 538 | ||
539 | /* Free the owner ID associated with this table */ | ||
540 | |||
541 | acpi_ut_release_owner_id(&table_desc->owner_id); | ||
542 | |||
528 | /* Free the table descriptor */ | 543 | /* Free the table descriptor */ |
529 | 544 | ||
530 | next_desc = table_desc->next; | 545 | next_desc = table_desc->next; |
diff --git a/drivers/acpi/tables/tbrsdt.c b/drivers/acpi/tables/tbrsdt.c index abcb08c2592a..0ad3dbb9ebca 100644 --- a/drivers/acpi/tables/tbrsdt.c +++ b/drivers/acpi/tables/tbrsdt.c | |||
@@ -183,6 +183,17 @@ acpi_status acpi_tb_validate_rsdt(struct acpi_table_header *table_ptr) | |||
183 | 183 | ||
184 | ACPI_FUNCTION_ENTRY(); | 184 | ACPI_FUNCTION_ENTRY(); |
185 | 185 | ||
186 | /* Validate minimum length */ | ||
187 | |||
188 | if (table_ptr->length < sizeof(struct acpi_table_header)) { | ||
189 | ACPI_ERROR((AE_INFO, | ||
190 | "RSDT/XSDT length (%X) is smaller than minimum (%X)", | ||
191 | table_ptr->length, | ||
192 | sizeof(struct acpi_table_header))); | ||
193 | |||
194 | return (AE_INVALID_TABLE_LENGTH); | ||
195 | } | ||
196 | |||
186 | /* Search for appropriate signature, RSDT or XSDT */ | 197 | /* Search for appropriate signature, RSDT or XSDT */ |
187 | 198 | ||
188 | if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) { | 199 | if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) { |
@@ -210,7 +221,7 @@ acpi_status acpi_tb_validate_rsdt(struct acpi_table_header *table_ptr) | |||
210 | ACPI_ERROR((AE_INFO, "Looking for XSDT")); | 221 | ACPI_ERROR((AE_INFO, "Looking for XSDT")); |
211 | } | 222 | } |
212 | 223 | ||
213 | ACPI_DUMP_BUFFER((char *)table_ptr, 48); | 224 | ACPI_DUMP_BUFFER(ACPI_CAST_PTR(char, table_ptr), 48); |
214 | return (AE_BAD_SIGNATURE); | 225 | return (AE_BAD_SIGNATURE); |
215 | } | 226 | } |
216 | 227 | ||
@@ -258,7 +269,7 @@ acpi_status acpi_tb_get_table_rsdt(void) | |||
258 | 269 | ||
259 | status = acpi_tb_validate_rsdt(table_info.pointer); | 270 | status = acpi_tb_validate_rsdt(table_info.pointer); |
260 | if (ACPI_FAILURE(status)) { | 271 | if (ACPI_FAILURE(status)) { |
261 | return_ACPI_STATUS(status); | 272 | goto error_cleanup; |
262 | } | 273 | } |
263 | 274 | ||
264 | /* Get the number of tables defined in the RSDT or XSDT */ | 275 | /* Get the number of tables defined in the RSDT or XSDT */ |
@@ -270,14 +281,14 @@ acpi_status acpi_tb_get_table_rsdt(void) | |||
270 | 281 | ||
271 | status = acpi_tb_convert_to_xsdt(&table_info); | 282 | status = acpi_tb_convert_to_xsdt(&table_info); |
272 | if (ACPI_FAILURE(status)) { | 283 | if (ACPI_FAILURE(status)) { |
273 | return_ACPI_STATUS(status); | 284 | goto error_cleanup; |
274 | } | 285 | } |
275 | 286 | ||
276 | /* Save the table pointers and allocation info */ | 287 | /* Save the table pointers and allocation info */ |
277 | 288 | ||
278 | status = acpi_tb_init_table_descriptor(ACPI_TABLE_ID_XSDT, &table_info); | 289 | status = acpi_tb_init_table_descriptor(ACPI_TABLE_ID_XSDT, &table_info); |
279 | if (ACPI_FAILURE(status)) { | 290 | if (ACPI_FAILURE(status)) { |
280 | return_ACPI_STATUS(status); | 291 | goto error_cleanup; |
281 | } | 292 | } |
282 | 293 | ||
283 | acpi_gbl_XSDT = | 294 | acpi_gbl_XSDT = |
@@ -285,4 +296,12 @@ acpi_status acpi_tb_get_table_rsdt(void) | |||
285 | 296 | ||
286 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "XSDT located at %p\n", acpi_gbl_XSDT)); | 297 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "XSDT located at %p\n", acpi_gbl_XSDT)); |
287 | return_ACPI_STATUS(status); | 298 | return_ACPI_STATUS(status); |
299 | |||
300 | error_cleanup: | ||
301 | |||
302 | /* Free table allocated by acpi_tb_get_table */ | ||
303 | |||
304 | acpi_tb_delete_single_table(&table_info); | ||
305 | |||
306 | return_ACPI_STATUS(status); | ||
288 | } | 307 | } |
diff --git a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c index 4e91f2984815..7767987be15a 100644 --- a/drivers/acpi/tables/tbxface.c +++ b/drivers/acpi/tables/tbxface.c | |||
@@ -134,8 +134,8 @@ ACPI_EXPORT_SYMBOL(acpi_load_tables) | |||
134 | * RETURN: Status | 134 | * RETURN: Status |
135 | * | 135 | * |
136 | * DESCRIPTION: This function is called to load a table from the caller's | 136 | * DESCRIPTION: This function is called to load a table from the caller's |
137 | * buffer. The buffer must contain an entire ACPI Table including | 137 | * buffer. The buffer must contain an entire ACPI Table including |
138 | * a valid header. The header fields will be verified, and if it | 138 | * a valid header. The header fields will be verified, and if it |
139 | * is determined that the table is invalid, the call will fail. | 139 | * is determined that the table is invalid, the call will fail. |
140 | * | 140 | * |
141 | ******************************************************************************/ | 141 | ******************************************************************************/ |
@@ -245,15 +245,18 @@ acpi_status acpi_unload_table(acpi_table_type table_type) | |||
245 | /* Find all tables of the requested type */ | 245 | /* Find all tables of the requested type */ |
246 | 246 | ||
247 | table_desc = acpi_gbl_table_lists[table_type].next; | 247 | table_desc = acpi_gbl_table_lists[table_type].next; |
248 | if (!table_desc) { | ||
249 | return_ACPI_STATUS(AE_NOT_EXIST); | ||
250 | } | ||
251 | |||
248 | while (table_desc) { | 252 | while (table_desc) { |
249 | /* | 253 | /* |
250 | * Delete all namespace entries owned by this table. Note that these | 254 | * Delete all namespace objects owned by this table. Note that these |
251 | * entries can appear anywhere in the namespace by virtue of the AML | 255 | * objects can appear anywhere in the namespace by virtue of the AML |
252 | * "Scope" operator. Thus, we need to track ownership by an ID, not | 256 | * "Scope" operator. Thus, we need to track ownership by an ID, not |
253 | * simply a position within the hierarchy | 257 | * simply a position within the hierarchy |
254 | */ | 258 | */ |
255 | acpi_ns_delete_namespace_by_owner(table_desc->owner_id); | 259 | acpi_ns_delete_namespace_by_owner(table_desc->owner_id); |
256 | acpi_ut_release_owner_id(&table_desc->owner_id); | ||
257 | table_desc = table_desc->next; | 260 | table_desc = table_desc->next; |
258 | } | 261 | } |
259 | 262 | ||
@@ -275,12 +278,12 @@ ACPI_EXPORT_SYMBOL(acpi_unload_table) | |||
275 | * see acpi_gbl_acpi_table_flag | 278 | * see acpi_gbl_acpi_table_flag |
276 | * out_table_header - pointer to the struct acpi_table_header if successful | 279 | * out_table_header - pointer to the struct acpi_table_header if successful |
277 | * | 280 | * |
278 | * DESCRIPTION: This function is called to get an ACPI table header. The caller | 281 | * DESCRIPTION: This function is called to get an ACPI table header. The caller |
279 | * supplies an pointer to a data area sufficient to contain an ACPI | 282 | * supplies an pointer to a data area sufficient to contain an ACPI |
280 | * struct acpi_table_header structure. | 283 | * struct acpi_table_header structure. |
281 | * | 284 | * |
282 | * The header contains a length field that can be used to determine | 285 | * The header contains a length field that can be used to determine |
283 | * the size of the buffer needed to contain the entire table. This | 286 | * the size of the buffer needed to contain the entire table. This |
284 | * function is not valid for the RSD PTR table since it does not | 287 | * function is not valid for the RSD PTR table since it does not |
285 | * have a standard header and is fixed length. | 288 | * have a standard header and is fixed length. |
286 | * | 289 | * |
@@ -322,7 +325,8 @@ acpi_get_table_header(acpi_table_type table_type, | |||
322 | 325 | ||
323 | /* Copy the header to the caller's buffer */ | 326 | /* Copy the header to the caller's buffer */ |
324 | 327 | ||
325 | ACPI_MEMCPY((void *)out_table_header, (void *)tbl_ptr, | 328 | ACPI_MEMCPY(ACPI_CAST_PTR(void, out_table_header), |
329 | ACPI_CAST_PTR(void, tbl_ptr), | ||
326 | sizeof(struct acpi_table_header)); | 330 | sizeof(struct acpi_table_header)); |
327 | 331 | ||
328 | return_ACPI_STATUS(status); | 332 | return_ACPI_STATUS(status); |
@@ -344,10 +348,10 @@ ACPI_EXPORT_SYMBOL(acpi_get_table_header) | |||
344 | * | 348 | * |
345 | * RETURN: Status | 349 | * RETURN: Status |
346 | * | 350 | * |
347 | * DESCRIPTION: This function is called to get an ACPI table. The caller | 351 | * DESCRIPTION: This function is called to get an ACPI table. The caller |
348 | * supplies an out_buffer large enough to contain the entire ACPI | 352 | * supplies an out_buffer large enough to contain the entire ACPI |
349 | * table. The caller should call the acpi_get_table_header function | 353 | * table. The caller should call the acpi_get_table_header function |
350 | * first to determine the buffer size needed. Upon completion | 354 | * first to determine the buffer size needed. Upon completion |
351 | * the out_buffer->Length field will indicate the number of bytes | 355 | * the out_buffer->Length field will indicate the number of bytes |
352 | * copied into the out_buffer->buf_ptr buffer. This table will be | 356 | * copied into the out_buffer->buf_ptr buffer. This table will be |
353 | * a complete table including the header. | 357 | * a complete table including the header. |
@@ -417,7 +421,9 @@ acpi_get_table(acpi_table_type table_type, | |||
417 | 421 | ||
418 | /* Copy the table to the buffer */ | 422 | /* Copy the table to the buffer */ |
419 | 423 | ||
420 | ACPI_MEMCPY((void *)ret_buffer->pointer, (void *)tbl_ptr, table_length); | 424 | ACPI_MEMCPY(ACPI_CAST_PTR(void, ret_buffer->pointer), |
425 | ACPI_CAST_PTR(void, tbl_ptr), table_length); | ||
426 | |||
421 | return_ACPI_STATUS(AE_OK); | 427 | return_ACPI_STATUS(AE_OK); |
422 | } | 428 | } |
423 | 429 | ||