kernel: handle: add support for allocating a specific handle value
This commit is contained in:
@@ -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
@@ -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
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user