Commit ca25f92b authored by Jessica Clarke's avatar Jessica Clarke Committed by Rafael J. Wysocki
Browse files

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: default avatarBob Moore <robert.moore@intel.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent f81bdeaf
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -223,6 +223,11 @@ acpi_ev_pci_bar_region_setup(acpi_handle handle,
			     u32 function,
			     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_ev_default_region_setup(acpi_handle handle,
			     u32 function,
+1 −0
Original line number Diff line number Diff line
@@ -138,6 +138,7 @@ struct acpi_object_region {
	union acpi_operand_object *next;
	acpi_physical_address address;
	u32 length;
	void *pointer;		/* Only for data table regions */
};

struct acpi_object_method {
+1 −0
Original line number Diff line number Diff line
@@ -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.length = table->length;
	obj_desc->region.pointer = table;

	ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
			  obj_desc,
+1 −1
Original line number Diff line number Diff line
@@ -386,7 +386,7 @@ acpi_ev_install_space_handler(struct acpi_namespace_node *node,
		case ACPI_ADR_SPACE_DATA_TABLE:

			handler = acpi_ex_data_table_space_handler;
			setup = NULL;
			setup = acpi_ev_data_table_region_setup;
			break;

		default:
+52 −0
Original line number Diff line number Diff line
@@ -406,6 +406,58 @@ acpi_ev_cmos_region_setup(acpi_handle handle,
	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
Loading