Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ACPICA: Use original data_table_region pointer for accesses

ACPICA commit d9eb82bd7515989f0b29d79deeeb758db4d6529c

Currently the pointer to the table is cast to acpi_physical_address and
later cast back to a pointer to be dereferenced. Whether or not this is
supported is implementation-defined.

On CHERI, and thus Arm's experimental Morello prototype architecture,
pointers are represented as capabilities, which are unforgeable bounded
pointers, providing always-on fine-grained spatial memory safety. This
means that any pointer cast to a plain integer will lose all its
associated metadata, and when cast back to a pointer it will give a
null-derived pointer (one that has the same metadata as null but an
address equal to the integer) that will trap on any dereference. As a
result, this is an implementation where acpi_physical_address cannot be
used as a hack to store real pointers.

Thus, add a new field to struct acpi_object_region to store the pointer for
table regions, and propagate it to acpi_ex_data_table_space_handler via the
region context, to use a more portable implementation that supports
CHERI.

Link: https://github.com/acpica/acpica/commit/d9eb82bd
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

authored by

Jessica Clarke and committed by
Rafael J. Wysocki
ca25f92b f81bdeaf

+76 -5
+5
drivers/acpi/acpica/acevents.h
··· 224 224 void *handler_context, void **region_context); 225 225 226 226 acpi_status 227 + acpi_ev_data_table_region_setup(acpi_handle handle, 228 + u32 function, 229 + void *handler_context, void **region_context); 230 + 231 + acpi_status 227 232 acpi_ev_default_region_setup(acpi_handle handle, 228 233 u32 function, 229 234 void *handler_context, void **region_context);
+1
drivers/acpi/acpica/acobject.h
··· 138 138 union acpi_operand_object *next; 139 139 acpi_physical_address address; 140 140 u32 length; 141 + void *pointer; /* Only for data table regions */ 141 142 }; 142 143 143 144 struct acpi_object_method {
+1
drivers/acpi/acpica/dsopcode.c
··· 531 531 532 532 obj_desc->region.address = ACPI_PTR_TO_PHYSADDR(table); 533 533 obj_desc->region.length = table->length; 534 + obj_desc->region.pointer = table; 534 535 535 536 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n", 536 537 obj_desc,
+1 -1
drivers/acpi/acpica/evhandler.c
··· 386 386 case ACPI_ADR_SPACE_DATA_TABLE: 387 387 388 388 handler = acpi_ex_data_table_space_handler; 389 - setup = NULL; 389 + setup = acpi_ev_data_table_region_setup; 390 390 break; 391 391 392 392 default:
+52
drivers/acpi/acpica/evrgnini.c
··· 408 408 409 409 /******************************************************************************* 410 410 * 411 + * FUNCTION: acpi_ev_data_table_region_setup 412 + * 413 + * PARAMETERS: handle - Region we are interested in 414 + * function - Start or stop 415 + * handler_context - Address space handler context 416 + * region_context - Region specific context 417 + * 418 + * RETURN: Status 419 + * 420 + * DESCRIPTION: Setup a data_table_region 421 + * 422 + * MUTEX: Assumes namespace is not locked 423 + * 424 + ******************************************************************************/ 425 + 426 + acpi_status 427 + acpi_ev_data_table_region_setup(acpi_handle handle, 428 + u32 function, 429 + void *handler_context, void **region_context) 430 + { 431 + union acpi_operand_object *region_desc = 432 + (union acpi_operand_object *)handle; 433 + struct acpi_data_table_space_context *local_region_context; 434 + 435 + ACPI_FUNCTION_TRACE(ev_data_table_region_setup); 436 + 437 + if (function == ACPI_REGION_DEACTIVATE) { 438 + if (*region_context) { 439 + ACPI_FREE(*region_context); 440 + *region_context = NULL; 441 + } 442 + return_ACPI_STATUS(AE_OK); 443 + } 444 + 445 + /* Create a new context */ 446 + 447 + local_region_context = 448 + ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_data_table_space_context)); 449 + if (!(local_region_context)) { 450 + return_ACPI_STATUS(AE_NO_MEMORY); 451 + } 452 + 453 + /* Save the data table pointer for use in the handler */ 454 + 455 + local_region_context->pointer = region_desc->region.pointer; 456 + 457 + *region_context = local_region_context; 458 + return_ACPI_STATUS(AE_OK); 459 + } 460 + 461 + /******************************************************************************* 462 + * 411 463 * FUNCTION: acpi_ev_default_region_setup 412 464 * 413 465 * PARAMETERS: handle - Region we are interested in
+1
drivers/acpi/acpica/excreate.c
··· 279 279 obj_desc->region.space_id = space_id; 280 280 obj_desc->region.address = 0; 281 281 obj_desc->region.length = 0; 282 + obj_desc->region.pointer = NULL; 282 283 obj_desc->region.node = node; 283 284 obj_desc->region.handler = NULL; 284 285 obj_desc->common.flags &=
+11 -4
drivers/acpi/acpica/exregion.c
··· 509 509 u64 *value, 510 510 void *handler_context, void *region_context) 511 511 { 512 + struct acpi_data_table_space_context *mapping; 513 + char *pointer; 514 + 512 515 ACPI_FUNCTION_TRACE(ex_data_table_space_handler); 516 + 517 + mapping = (struct acpi_data_table_space_context *) region_context; 518 + pointer = ACPI_CAST_PTR(char, mapping->pointer) + 519 + (address - ACPI_PTR_TO_PHYSADDR(mapping->pointer)); 513 520 514 521 /* 515 522 * Perform the memory read or write. The bit_width was already ··· 525 518 switch (function) { 526 519 case ACPI_READ: 527 520 528 - memcpy(ACPI_CAST_PTR(char, value), 529 - ACPI_PHYSADDR_TO_PTR(address), ACPI_DIV_8(bit_width)); 521 + memcpy(ACPI_CAST_PTR(char, value), pointer, 522 + ACPI_DIV_8(bit_width)); 530 523 break; 531 524 532 525 case ACPI_WRITE: 533 526 534 - memcpy(ACPI_PHYSADDR_TO_PTR(address), 535 - ACPI_CAST_PTR(char, value), ACPI_DIV_8(bit_width)); 527 + memcpy(pointer, ACPI_CAST_PTR(char, value), 528 + ACPI_DIV_8(bit_width)); 536 529 break; 537 530 538 531 default:
+4
include/acpi/actypes.h
··· 1221 1221 struct acpi_mem_mapping *first_mm; 1222 1222 }; 1223 1223 1224 + struct acpi_data_table_space_context { 1225 + void *pointer; 1226 + }; 1227 + 1224 1228 /* 1225 1229 * struct acpi_memory_list is used only if the ACPICA local cache is enabled 1226 1230 */