kernel: handle: add support for allocating a specific handle value

This commit is contained in:
2026-03-29 11:47:22 +01:00
parent dfffb45e66
commit 537242e606
5 changed files with 63 additions and 3 deletions
+1
View File
@@ -47,6 +47,7 @@ extern void handle_table_destroy(struct handle_table *tab);
extern kern_status_t handle_table_alloc_handle( extern kern_status_t handle_table_alloc_handle(
struct handle_table *tab, struct handle_table *tab,
kern_handle_t value,
struct handle **out_slot, struct handle **out_slot,
kern_handle_t *out_handle); kern_handle_t *out_handle);
extern kern_status_t handle_table_free_handle( extern kern_status_t handle_table_free_handle(
+50 -1
View File
@@ -109,7 +109,7 @@ static kern_status_t encode_handle_indices(
return KERN_OK; return KERN_OK;
} }
kern_status_t handle_table_alloc_handle( static kern_status_t alloc_handle(
struct handle_table *tab, struct handle_table *tab,
struct handle **out_slot, struct handle **out_slot,
kern_handle_t *out_handle) kern_handle_t *out_handle)
@@ -164,6 +164,53 @@ kern_status_t handle_table_alloc_handle(
return encode_handle_indices(indices, out_handle); return encode_handle_indices(indices, out_handle);
} }
kern_status_t handle_table_alloc_handle(
struct handle_table *tab,
kern_handle_t value,
struct handle **out_slot,
kern_handle_t *out_handle)
{
if (value == KERN_HANDLE_INVALID) {
return alloc_handle(tab, out_slot, out_handle);
}
unsigned int indices[MAX_TABLE_DEPTH];
if (decode_handle_indices(value, indices) != KERN_OK) {
return KERN_HANDLE_INVALID;
}
int i;
for (i = 0; i < MAX_TABLE_DEPTH - 1; i++) {
struct handle_table *next
= tab->t_subtables.t_subtable_list[indices[i]];
if (!next) {
next = handle_table_create();
tab->t_subtables.t_subtable_list[indices[i]] = next;
}
if (!next) {
return KERN_NO_MEMORY;
}
tab = next;
}
unsigned int handle_index = indices[i];
bitmap_set(tab->t_handles.t_handle_map, handle_index);
struct handle *out = &tab->t_handles.t_handle_list[handle_index];
if (out->h_object) {
object_unref(out->h_object);
out->h_object = NULL;
out->h_flags = 0;
}
*out_slot = out;
*out_handle = value;
return KERN_OK;
}
kern_status_t handle_table_free_handle( kern_status_t handle_table_free_handle(
struct handle_table *tab, struct handle_table *tab,
kern_handle_t handle) kern_handle_t handle)
@@ -299,6 +346,7 @@ kern_status_t handle_table_transfer(
case KERN_MSG_HANDLE_MOVE: case KERN_MSG_HANDLE_MOVE:
status = handle_table_alloc_handle( status = handle_table_alloc_handle(
dst, dst,
KERN_HANDLE_INVALID,
&dst_entry, &dst_entry,
&dst_value); &dst_value);
if (status != KERN_OK) { if (status != KERN_OK) {
@@ -318,6 +366,7 @@ kern_status_t handle_table_transfer(
case KERN_MSG_HANDLE_COPY: case KERN_MSG_HANDLE_COPY:
status = handle_table_alloc_handle( status = handle_table_alloc_handle(
dst, dst,
KERN_HANDLE_INVALID,
&dst_entry, &dst_entry,
&dst_value); &dst_value);
if (status != KERN_OK) { if (status != KERN_OK) {
+5 -2
View File
@@ -352,8 +352,11 @@ kern_status_t task_open_handle(
kern_handle_t *out) kern_handle_t *out)
{ {
struct handle *handle_data = NULL; struct handle *handle_data = NULL;
kern_status_t status kern_status_t status = handle_table_alloc_handle(
= handle_table_alloc_handle(task->t_handles, &handle_data, out); task->t_handles,
KERN_HANDLE_INVALID,
&handle_data,
out);
if (status != KERN_OK) { if (status != KERN_OK) {
return status; return status;
} }
+6
View File
@@ -30,6 +30,7 @@ kern_status_t sys_task_self(kern_handle_t *out)
kern_handle_t handle; kern_handle_t handle;
kern_status_t status = handle_table_alloc_handle( kern_status_t status = handle_table_alloc_handle(
self->t_handles, self->t_handles,
KERN_HANDLE_INVALID,
&handle_slot, &handle_slot,
&handle); &handle);
task_unlock_irqrestore(self, flags); task_unlock_irqrestore(self, flags);
@@ -89,6 +90,7 @@ kern_status_t sys_task_create(
kern_handle_t child_handle, space_handle; kern_handle_t child_handle, space_handle;
status = handle_table_alloc_handle( status = handle_table_alloc_handle(
self->t_handles, self->t_handles,
KERN_HANDLE_INVALID,
&child_handle_slot, &child_handle_slot,
&child_handle); &child_handle);
if (status != KERN_OK) { if (status != KERN_OK) {
@@ -99,6 +101,7 @@ kern_status_t sys_task_create(
status = handle_table_alloc_handle( status = handle_table_alloc_handle(
self->t_handles, self->t_handles,
KERN_HANDLE_INVALID,
&space_handle_slot, &space_handle_slot,
&space_handle); &space_handle);
if (status != KERN_OK) { if (status != KERN_OK) {
@@ -175,6 +178,7 @@ kern_status_t sys_task_create_thread(
kern_handle_t out_handle; kern_handle_t out_handle;
status = handle_table_alloc_handle( status = handle_table_alloc_handle(
self->t_handles, self->t_handles,
KERN_HANDLE_INVALID,
&target_handle, &target_handle,
&out_handle); &out_handle);
if (status != KERN_OK) { if (status != KERN_OK) {
@@ -236,6 +240,7 @@ kern_status_t sys_task_get_address_space(
status = handle_table_alloc_handle( status = handle_table_alloc_handle(
self->t_handles, self->t_handles,
KERN_HANDLE_INVALID,
&handle_slot, &handle_slot,
&handle); &handle);
if (status != KERN_OK) { if (status != KERN_OK) {
@@ -278,6 +283,7 @@ kern_status_t sys_thread_self(kern_handle_t *out)
kern_handle_t handle; kern_handle_t handle;
kern_status_t status = handle_table_alloc_handle( kern_status_t status = handle_table_alloc_handle(
self->t_handles, self->t_handles,
KERN_HANDLE_INVALID,
&handle_slot, &handle_slot,
&handle); &handle);
task_unlock_irqrestore(self, flags); task_unlock_irqrestore(self, flags);
+1
View File
@@ -154,6 +154,7 @@ kern_status_t sys_vm_controller_create_object(
kern_handle_t out_handle = KERN_HANDLE_INVALID; kern_handle_t out_handle = KERN_HANDLE_INVALID;
status = handle_table_alloc_handle( status = handle_table_alloc_handle(
self->t_handles, self->t_handles,
KERN_HANDLE_INVALID,
&out_slot, &out_slot,
&out_handle); &out_handle);