mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-11-01 17:08:10 +00:00
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>
This commit is contained in:
parent
f81bdeaf81
commit
ca25f92b72
8 changed files with 76 additions and 5 deletions
|
@ -223,6 +223,11 @@ acpi_ev_pci_bar_region_setup(acpi_handle handle,
|
||||||
u32 function,
|
u32 function,
|
||||||
void *handler_context, void **region_context);
|
void *handler_context, void **region_context);
|
||||||
|
|
||||||
|
acpi_status
|
||||||
|
acpi_ev_data_table_region_setup(acpi_handle handle,
|
||||||
|
u32 function,
|
||||||
|
void *handler_context, void **region_context);
|
||||||
|
|
||||||
acpi_status
|
acpi_status
|
||||||
acpi_ev_default_region_setup(acpi_handle handle,
|
acpi_ev_default_region_setup(acpi_handle handle,
|
||||||
u32 function,
|
u32 function,
|
||||||
|
|
|
@ -138,6 +138,7 @@ struct acpi_object_region {
|
||||||
union acpi_operand_object *next;
|
union acpi_operand_object *next;
|
||||||
acpi_physical_address address;
|
acpi_physical_address address;
|
||||||
u32 length;
|
u32 length;
|
||||||
|
void *pointer; /* Only for data table regions */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct acpi_object_method {
|
struct acpi_object_method {
|
||||||
|
|
|
@ -531,6 +531,7 @@ acpi_ds_eval_table_region_operands(struct acpi_walk_state *walk_state,
|
||||||
|
|
||||||
obj_desc->region.address = ACPI_PTR_TO_PHYSADDR(table);
|
obj_desc->region.address = ACPI_PTR_TO_PHYSADDR(table);
|
||||||
obj_desc->region.length = table->length;
|
obj_desc->region.length = table->length;
|
||||||
|
obj_desc->region.pointer = table;
|
||||||
|
|
||||||
ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
|
ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
|
||||||
obj_desc,
|
obj_desc,
|
||||||
|
|
|
@ -386,7 +386,7 @@ acpi_ev_install_space_handler(struct acpi_namespace_node *node,
|
||||||
case ACPI_ADR_SPACE_DATA_TABLE:
|
case ACPI_ADR_SPACE_DATA_TABLE:
|
||||||
|
|
||||||
handler = acpi_ex_data_table_space_handler;
|
handler = acpi_ex_data_table_space_handler;
|
||||||
setup = NULL;
|
setup = acpi_ev_data_table_region_setup;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -406,6 +406,58 @@ acpi_ev_cmos_region_setup(acpi_handle handle,
|
||||||
return_ACPI_STATUS(AE_OK);
|
return_ACPI_STATUS(AE_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* FUNCTION: acpi_ev_data_table_region_setup
|
||||||
|
*
|
||||||
|
* PARAMETERS: handle - Region we are interested in
|
||||||
|
* function - Start or stop
|
||||||
|
* handler_context - Address space handler context
|
||||||
|
* region_context - Region specific context
|
||||||
|
*
|
||||||
|
* RETURN: Status
|
||||||
|
*
|
||||||
|
* DESCRIPTION: Setup a data_table_region
|
||||||
|
*
|
||||||
|
* MUTEX: Assumes namespace is not locked
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
acpi_status
|
||||||
|
acpi_ev_data_table_region_setup(acpi_handle handle,
|
||||||
|
u32 function,
|
||||||
|
void *handler_context, void **region_context)
|
||||||
|
{
|
||||||
|
union acpi_operand_object *region_desc =
|
||||||
|
(union acpi_operand_object *)handle;
|
||||||
|
struct acpi_data_table_space_context *local_region_context;
|
||||||
|
|
||||||
|
ACPI_FUNCTION_TRACE(ev_data_table_region_setup);
|
||||||
|
|
||||||
|
if (function == ACPI_REGION_DEACTIVATE) {
|
||||||
|
if (*region_context) {
|
||||||
|
ACPI_FREE(*region_context);
|
||||||
|
*region_context = NULL;
|
||||||
|
}
|
||||||
|
return_ACPI_STATUS(AE_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create a new context */
|
||||||
|
|
||||||
|
local_region_context =
|
||||||
|
ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_data_table_space_context));
|
||||||
|
if (!(local_region_context)) {
|
||||||
|
return_ACPI_STATUS(AE_NO_MEMORY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Save the data table pointer for use in the handler */
|
||||||
|
|
||||||
|
local_region_context->pointer = region_desc->region.pointer;
|
||||||
|
|
||||||
|
*region_context = local_region_context;
|
||||||
|
return_ACPI_STATUS(AE_OK);
|
||||||
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
*
|
*
|
||||||
* FUNCTION: acpi_ev_default_region_setup
|
* FUNCTION: acpi_ev_default_region_setup
|
||||||
|
|
|
@ -279,6 +279,7 @@ acpi_ex_create_region(u8 * aml_start,
|
||||||
obj_desc->region.space_id = space_id;
|
obj_desc->region.space_id = space_id;
|
||||||
obj_desc->region.address = 0;
|
obj_desc->region.address = 0;
|
||||||
obj_desc->region.length = 0;
|
obj_desc->region.length = 0;
|
||||||
|
obj_desc->region.pointer = NULL;
|
||||||
obj_desc->region.node = node;
|
obj_desc->region.node = node;
|
||||||
obj_desc->region.handler = NULL;
|
obj_desc->region.handler = NULL;
|
||||||
obj_desc->common.flags &=
|
obj_desc->common.flags &=
|
||||||
|
|
|
@ -509,8 +509,15 @@ acpi_ex_data_table_space_handler(u32 function,
|
||||||
u64 *value,
|
u64 *value,
|
||||||
void *handler_context, void *region_context)
|
void *handler_context, void *region_context)
|
||||||
{
|
{
|
||||||
|
struct acpi_data_table_space_context *mapping;
|
||||||
|
char *pointer;
|
||||||
|
|
||||||
ACPI_FUNCTION_TRACE(ex_data_table_space_handler);
|
ACPI_FUNCTION_TRACE(ex_data_table_space_handler);
|
||||||
|
|
||||||
|
mapping = (struct acpi_data_table_space_context *) region_context;
|
||||||
|
pointer = ACPI_CAST_PTR(char, mapping->pointer) +
|
||||||
|
(address - ACPI_PTR_TO_PHYSADDR(mapping->pointer));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Perform the memory read or write. The bit_width was already
|
* Perform the memory read or write. The bit_width was already
|
||||||
* validated.
|
* validated.
|
||||||
|
@ -518,14 +525,14 @@ acpi_ex_data_table_space_handler(u32 function,
|
||||||
switch (function) {
|
switch (function) {
|
||||||
case ACPI_READ:
|
case ACPI_READ:
|
||||||
|
|
||||||
memcpy(ACPI_CAST_PTR(char, value),
|
memcpy(ACPI_CAST_PTR(char, value), pointer,
|
||||||
ACPI_PHYSADDR_TO_PTR(address), ACPI_DIV_8(bit_width));
|
ACPI_DIV_8(bit_width));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ACPI_WRITE:
|
case ACPI_WRITE:
|
||||||
|
|
||||||
memcpy(ACPI_PHYSADDR_TO_PTR(address),
|
memcpy(pointer, ACPI_CAST_PTR(char, value),
|
||||||
ACPI_CAST_PTR(char, value), ACPI_DIV_8(bit_width));
|
ACPI_DIV_8(bit_width));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -1221,6 +1221,10 @@ struct acpi_mem_space_context {
|
||||||
struct acpi_mem_mapping *first_mm;
|
struct acpi_mem_mapping *first_mm;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct acpi_data_table_space_context {
|
||||||
|
void *pointer;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* struct acpi_memory_list is used only if the ACPICA local cache is enabled
|
* struct acpi_memory_list is used only if the ACPICA local cache is enabled
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue