Skip to content

Commit

Permalink
opregion: make concurrent install & uninstall thread-safe
Browse files Browse the repository at this point in the history
Signed-off-by: Daniil Tatianin <99danilt@gmail.com>
  • Loading branch information
d-tatianin committed Dec 16, 2024
1 parent 875d0f4 commit 1721b8a
Show file tree
Hide file tree
Showing 5 changed files with 226 additions and 130 deletions.
13 changes: 9 additions & 4 deletions include/uacpi/internal/opregion.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
#include <uacpi/internal/types.h>
#include <uacpi/opregion.h>

uacpi_status uacpi_initialize_opregion(void);
void uacpi_deinitialize_opregion(void);

void uacpi_trace_region_error(
uacpi_namespace_node *node, uacpi_char *message, uacpi_status ret
);
Expand All @@ -17,11 +20,13 @@ uacpi_address_space_handlers *uacpi_node_get_address_space_handlers(
uacpi_namespace_node *node
);

uacpi_status uacpi_opregion_find_and_install_handler(
uacpi_namespace_node *node
);
uacpi_status uacpi_initialize_opregion_node(uacpi_namespace_node *node);

void uacpi_opregion_reg(uacpi_namespace_node *node);
uacpi_status uacpi_opregion_attach(uacpi_namespace_node *node);

void uacpi_install_default_address_space_handlers(void);

uacpi_status uacpi_dispatch_opregion_io(
uacpi_namespace_node *region_node, uacpi_u32 offset, uacpi_u8 byte_width,
uacpi_region_op op, uacpi_u64 *in_out
);
9 changes: 2 additions & 7 deletions source/interpreter.c
Original file line number Diff line number Diff line change
Expand Up @@ -1124,10 +1124,7 @@ static uacpi_status handle_create_op_region(struct execution_context *ctx)
if (uacpi_unlikely(node->object == UACPI_NULL))
return UACPI_STATUS_OUT_OF_MEMORY;

if (uacpi_opregion_find_and_install_handler(node) == UACPI_STATUS_OK &&
uacpi_get_current_init_level() >= UACPI_INIT_LEVEL_NAMESPACE_LOADED)
uacpi_opregion_reg(node);

uacpi_initialize_opregion_node(node);
return UACPI_STATUS_OK;
}

Expand Down Expand Up @@ -1226,9 +1223,7 @@ static uacpi_status handle_create_data_region(struct execution_context *ctx)
if (uacpi_unlikely(node->object == UACPI_NULL))
return UACPI_STATUS_OUT_OF_MEMORY;

if (uacpi_opregion_find_and_install_handler(node) == UACPI_STATUS_OK)
uacpi_opregion_reg(node);

uacpi_initialize_opregion_node(node);
return UACPI_STATUS_OK;
}

Expand Down
82 changes: 1 addition & 81 deletions source/io.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,86 +174,6 @@ void uacpi_write_buffer_field(
do_write_misaligned_buffer_field(field, src, size);
}

static uacpi_status dispatch_field_io(
uacpi_namespace_node *region_node, uacpi_u32 offset, uacpi_u8 byte_width,
uacpi_region_op op, uacpi_u64 *in_out
)
{
uacpi_status ret;
uacpi_object *obj;
uacpi_operation_region *region;
uacpi_address_space_handler *handler;
uacpi_address_space space;
uacpi_u64 offset_end;

uacpi_region_rw_data data = {
.byte_width = byte_width,
.offset = offset,
};

ret = uacpi_opregion_attach(region_node);
if (uacpi_unlikely_error(ret)) {
uacpi_trace_region_error(
region_node, "unable to attach", ret
);
return ret;
}

obj = uacpi_namespace_node_get_object(region_node);
if (uacpi_unlikely(obj == UACPI_NULL ||
obj->type != UACPI_OBJECT_OPERATION_REGION))
return UACPI_STATUS_INVALID_ARGUMENT;

region = obj->op_region;
space = region->space;
handler = region->handler;

offset_end = offset;
offset_end += byte_width;
data.offset += region->offset;

if (uacpi_unlikely(region->length < offset_end ||
data.offset < offset)) {
const uacpi_char *path;

path = uacpi_namespace_node_generate_absolute_path(region_node);
uacpi_error(
"out-of-bounds access to opregion %s[0x%"UACPI_PRIX64"->"
"0x%"UACPI_PRIX64"] at 0x%"UACPI_PRIX64" (idx=%u, width=%d)\n",
path, UACPI_FMT64(region->offset),
UACPI_FMT64(region->offset + region->length),
UACPI_FMT64(data.offset), offset, byte_width
);
uacpi_free_dynamic_string(path);
return UACPI_STATUS_AML_OUT_OF_BOUNDS_INDEX;
}

data.handler_context = handler->user_context;
data.region_context = region->user_context;

if (op == UACPI_REGION_OP_WRITE) {
data.value = *in_out;
uacpi_trace_region_io(region_node, space, op, data.offset,
byte_width, data.value);
}

uacpi_namespace_write_unlock();

ret = handler->callback(op, &data);
if (uacpi_unlikely_error(ret))
return ret;

uacpi_namespace_write_lock();

if (op == UACPI_REGION_OP_READ) {
*in_out = data.value;
uacpi_trace_region_io(region_node, space, op, data.offset,
byte_width, data.value);
}

return UACPI_STATUS_OK;
}

static uacpi_status access_field_unit(
uacpi_field_unit *field, uacpi_u32 offset, uacpi_region_op op,
uacpi_u64 *in_out
Expand Down Expand Up @@ -309,7 +229,7 @@ static uacpi_status access_field_unit(
if (uacpi_unlikely_error(ret))
goto out;

ret = dispatch_field_io(
ret = uacpi_dispatch_opregion_io(
region_node, offset, field->access_width_bytes, op, in_out
);

Expand Down
Loading

0 comments on commit 1721b8a

Please sign in to comment.