Compare commits

...

10 Commits

Author SHA1 Message Date
wash 325699d64a kernel: fix sys_msg_send returning without unlocking self 2026-03-29 11:51:26 +01:00
wash 286016040c kernel: only show task name/id in log output if TRACE is enabled 2026-03-29 11:51:05 +01:00
wash 04617e81e3 kernel: add a syscall to query generic information about an object 2026-03-29 11:50:37 +01:00
wash 62770f4ab2 kernel: replace kern_handle_duplicate with the more powerful kern_handle_transfer
this syscall can move and copy handles within the current task, or from/to
other tasks
2026-03-29 11:48:59 +01:00
wash 9001f8e064 kernel: handle: rename handle transfer mode constants 2026-03-29 11:48:31 +01:00
wash 537242e606 kernel: handle: add support for allocating a specific handle value 2026-03-29 11:47:22 +01:00
wash dfffb45e66 libc: adjust formatting 2026-03-29 11:43:39 +01:00
wash f5a83af0d7 kernel: remove SEND_BLOCKED and REPLY_BLOCKED statuses from ports
this allows a port to be used by multiple threads at the same time
2026-03-29 11:42:23 +01:00
wash 7d25f1c31a x86_64: suppress serial port input logging 2026-03-29 11:32:03 +01:00
wash 95d33ddcb9 kernel: msg: async messages no longer hold a pointer to the thread/port that sent them
this prevents a race condition where an event is sent as a port is being destroyed.
when the server gets around to handling the event, it now refers to a different port
that was created in the mean-time.
2026-03-25 20:19:19 +00:00
23 changed files with 287 additions and 65 deletions
+2
View File
@@ -138,6 +138,7 @@ static struct console serialcon = {
static int serial_irq1(void) static int serial_irq1(void)
{ {
#if 0
if (serial_received(COM1)) { if (serial_received(COM1)) {
unsigned char c = serial_recv_byte(COM1); unsigned char c = serial_recv_byte(COM1);
printk("serial: COM1 received %c", c); printk("serial: COM1 received %c", c);
@@ -147,6 +148,7 @@ static int serial_irq1(void)
unsigned char c = serial_recv_byte(COM3); unsigned char c = serial_recv_byte(COM3);
printk("serial: COM3 received %c", c); printk("serial: COM3 received %c", c);
} }
#endif
return 0; return 0;
} }
+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(
+12
View File
@@ -21,8 +21,20 @@ struct msg {
enum kmsg_status msg_status; enum kmsg_status msg_status;
struct btree_node msg_node; struct btree_node msg_node;
msgid_t msg_id; msgid_t msg_id;
union {
/* only valid for asynchronous messages (msg_status ==
* KMSG_ASYNC) */
struct {
koid_t msg_sender_port_id;
tid_t msg_sender_thread_id;
};
/* only valid for synchronous messages (msg_status !=
* KMSG_ASYNC) */
struct {
struct port *msg_sender_port; struct port *msg_sender_port;
struct thread *msg_sender_thread; struct thread *msg_sender_thread;
};
};
kern_status_t msg_result; kern_status_t msg_result;
kern_msg_type_t msg_type; kern_msg_type_t msg_type;
-6
View File
@@ -9,12 +9,6 @@ enum port_status {
PORT_OFFLINE = 0, PORT_OFFLINE = 0,
/* port is connected and ready to send messages */ /* port is connected and ready to send messages */
PORT_READY, PORT_READY,
/* port has sent a message, and is waiting for the remote to receive it
*/
PORT_SEND_BLOCKED,
/* port has sent a message, and the remote has received it. waiting for
* the remote to reply. */
PORT_REPLY_BLOCKED,
}; };
struct port { struct port {
+10 -3
View File
@@ -143,9 +143,13 @@ extern kern_status_t sys_address_space_release(
extern kern_status_t sys_kern_log(const char *s); extern kern_status_t sys_kern_log(const char *s);
extern kern_status_t sys_kern_handle_close(kern_handle_t handle); extern kern_status_t sys_kern_handle_close(kern_handle_t handle);
extern kern_status_t sys_kern_handle_duplicate( extern kern_status_t sys_kern_handle_transfer(
kern_handle_t handle, kern_handle_t src_task_handle,
kern_handle_t *out); kern_handle_t src_handle,
kern_handle_t dest_task_handle,
kern_handle_t dest_handle,
unsigned int mode,
kern_handle_t *out_handle);
extern kern_status_t sys_kern_config_get( extern kern_status_t sys_kern_config_get(
kern_config_key_t key, kern_config_key_t key,
void *ptr, void *ptr,
@@ -191,6 +195,9 @@ extern kern_status_t sys_msg_write(
extern kern_status_t sys_kern_object_wait( extern kern_status_t sys_kern_object_wait(
kern_wait_item_t *items, kern_wait_item_t *items,
size_t nr_items); size_t nr_items);
extern kern_status_t sys_kern_object_query(
kern_handle_t object,
kern_object_info_t *out);
extern kern_status_t sys_vm_controller_create(kern_handle_t *out); extern kern_status_t sys_vm_controller_create(kern_handle_t *out);
extern kern_status_t sys_vm_controller_recv( extern kern_status_t sys_vm_controller_recv(
+4 -4
View File
@@ -2,6 +2,7 @@
#include <kernel/channel.h> #include <kernel/channel.h>
#include <kernel/msg.h> #include <kernel/msg.h>
#include <kernel/port.h> #include <kernel/port.h>
#include <kernel/printk.h>
#include <kernel/task.h> #include <kernel/task.h>
#include <kernel/thread.h> #include <kernel/thread.h>
#include <kernel/util.h> #include <kernel/util.h>
@@ -101,7 +102,6 @@ static struct msg *get_next_msg(
switch (msg->msg_status) { switch (msg->msg_status) {
case KMSG_WAIT_RECEIVE: case KMSG_WAIT_RECEIVE:
msg->msg_status = KMSG_WAIT_REPLY; msg->msg_status = KMSG_WAIT_REPLY;
msg->msg_sender_port->p_status = PORT_REPLY_BLOCKED;
channel->c_msg_waiting--; channel->c_msg_waiting--;
return msg; return msg;
case KMSG_ASYNC: case KMSG_ASYNC:
@@ -157,12 +157,12 @@ extern kern_status_t channel_recv_msg(
/* msg is now set to the next message to process */ /* msg is now set to the next message to process */
if (msg->msg_type != KERN_MSG_TYPE_DATA) { if (msg->msg_type != KERN_MSG_TYPE_DATA) {
/* event messages as asynchronous */ /* event messages are asynchronous */
out_msg->msg_id = msg->msg_id; out_msg->msg_id = msg->msg_id;
out_msg->msg_type = msg->msg_type; out_msg->msg_type = msg->msg_type;
out_msg->msg_event = msg->msg_event; out_msg->msg_event = msg->msg_event;
out_msg->msg_sender = msg->msg_sender_thread->tr_parent->t_id; out_msg->msg_sender = msg->msg_sender_thread_id;
out_msg->msg_endpoint = msg->msg_sender_port->p_base.ob_id; out_msg->msg_endpoint = msg->msg_sender_port_id;
spin_unlock_irqrestore(&msg->msg_lock, msg_lock_flags); spin_unlock_irqrestore(&msg->msg_lock, msg_lock_flags);
msg_free(msg); msg_free(msg);
+54 -5
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)
@@ -294,11 +341,12 @@ kern_status_t handle_table_transfer(
} }
switch (src_handle.hnd_mode) { switch (src_handle.hnd_mode) {
case KERN_MSG_HANDLE_IGNORE: case HANDLE_TRANSFER_IGNORE:
break; break;
case KERN_MSG_HANDLE_MOVE: case HANDLE_TRANSFER_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) {
@@ -315,9 +363,10 @@ kern_status_t handle_table_transfer(
dst_handle.hnd_value = dst_value; dst_handle.hnd_value = dst_value;
dst_handle.hnd_result = KERN_OK; dst_handle.hnd_result = KERN_OK;
break; break;
case KERN_MSG_HANDLE_COPY: case HANDLE_TRANSFER_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) {
@@ -364,7 +413,7 @@ kern_status_t handle_table_transfer(
&handle, &handle,
NULL); NULL);
if (handle.hnd_mode != KERN_MSG_HANDLE_MOVE) { if (handle.hnd_mode != HANDLE_TRANSFER_MOVE) {
continue; continue;
} }
+4 -5
View File
@@ -83,8 +83,8 @@ kern_status_t port_connect(struct port *port, struct channel *remote)
msg->msg_status = KMSG_ASYNC; msg->msg_status = KMSG_ASYNC;
msg->msg_type = KERN_MSG_TYPE_EVENT; msg->msg_type = KERN_MSG_TYPE_EVENT;
msg->msg_event = KERN_MSG_EVENT_CONNECTION; msg->msg_event = KERN_MSG_EVENT_CONNECTION;
msg->msg_sender_thread = current_thread(); msg->msg_sender_thread_id = current_thread()->tr_id;
msg->msg_sender_port = port; msg->msg_sender_port_id = port->p_base.ob_id;
unsigned long flags; unsigned long flags;
channel_lock_irqsave(remote, &flags); channel_lock_irqsave(remote, &flags);
@@ -112,8 +112,8 @@ kern_status_t port_disconnect(struct port *port)
msg->msg_status = KMSG_ASYNC; msg->msg_status = KMSG_ASYNC;
msg->msg_type = KERN_MSG_TYPE_EVENT; msg->msg_type = KERN_MSG_TYPE_EVENT;
msg->msg_event = KERN_MSG_EVENT_DISCONNECTION; msg->msg_event = KERN_MSG_EVENT_DISCONNECTION;
msg->msg_sender_thread = current_thread(); msg->msg_sender_thread_id = current_thread()->tr_id;
msg->msg_sender_port = port; msg->msg_sender_port_id = port->p_base.ob_id;
unsigned long flags; unsigned long flags;
channel_lock_irqsave(port->p_remote, &flags); channel_lock_irqsave(port->p_remote, &flags);
@@ -148,7 +148,6 @@ kern_status_t port_send_msg(
unsigned long flags; unsigned long flags;
channel_lock_irqsave(port->p_remote, &flags); channel_lock_irqsave(port->p_remote, &flags);
port->p_status = PORT_SEND_BLOCKED;
channel_enqueue_msg(port->p_remote, &msg); channel_enqueue_msg(port->p_remote, &msg);
channel_unlock_irqrestore(port->p_remote, flags); channel_unlock_irqrestore(port->p_remote, flags);
+4 -3
View File
@@ -2,7 +2,8 @@
int memcmp(const void *vl, const void *vr, size_t n) int memcmp(const void *vl, const void *vr, size_t n)
{ {
const unsigned char *l=vl, *r=vr; const unsigned char *l = vl, *r = vr;
for (; n && *l == *r; n--, l++, r++); for (; n && *l == *r; n--, l++, r++)
return n ? *l-*r : 0; ;
return n ? *l - *r : 0;
} }
+1 -1
View File
@@ -1,5 +1,5 @@
#include <stdint.h>
#include <kernel/libc/string.h> #include <kernel/libc/string.h>
#include <stdint.h>
static void *memcpy_r(void *dest, const void *src, size_t sz) static void *memcpy_r(void *dest, const void *src, size_t sz)
{ {
+2 -1
View File
@@ -83,7 +83,7 @@ SYSCALL_GATE address_space_release SYS_ADDRESS_SPACE_RELEASE 3
SYSCALL_GATE kern_log SYS_KERN_LOG 1 SYSCALL_GATE kern_log SYS_KERN_LOG 1
SYSCALL_GATE kern_handle_close SYS_KERN_HANDLE_CLOSE 1 SYSCALL_GATE kern_handle_close SYS_KERN_HANDLE_CLOSE 1
SYSCALL_GATE kern_handle_duplicate SYS_KERN_HANDLE_DUPLICATE 2 SYSCALL_GATE kern_handle_transfer SYS_KERN_HANDLE_TRANSFER 6
SYSCALL_GATE kern_config_get SYS_KERN_CONFIG_GET 3 SYSCALL_GATE kern_config_get SYS_KERN_CONFIG_GET 3
SYSCALL_GATE kern_config_set SYS_KERN_CONFIG_SET 3 SYSCALL_GATE kern_config_set SYS_KERN_CONFIG_SET 3
@@ -105,6 +105,7 @@ SYSCALL_GATE vm_controller_detach_object SYS_VM_CONTROLLER_DETACH_OBJECT 2
SYSCALL_GATE vm_controller_supply_pages SYS_VM_CONTROLLER_SUPPLY_PAGES 6 SYSCALL_GATE vm_controller_supply_pages SYS_VM_CONTROLLER_SUPPLY_PAGES 6
SYSCALL_GATE kern_object_wait SYS_KERN_OBJECT_WAIT 2 SYSCALL_GATE kern_object_wait SYS_KERN_OBJECT_WAIT 2
SYSCALL_GATE kern_object_query SYS_KERN_OBJECT_QUERY 2
SYSCALL_GATE futex_wait SYS_FUTEX_WAIT 3 SYSCALL_GATE futex_wait SYS_FUTEX_WAIT 3
SYSCALL_GATE futex_wake SYS_FUTEX_WAKE 3 SYSCALL_GATE futex_wake SYS_FUTEX_WAKE 3
+7 -3
View File
@@ -5,8 +5,12 @@
#include <mango/types.h> #include <mango/types.h>
extern kern_status_t kern_handle_close(kern_handle_t handle); extern kern_status_t kern_handle_close(kern_handle_t handle);
extern kern_status_t kern_handle_duplicate( extern kern_status_t kern_handle_transfer(
kern_handle_t handle, kern_handle_t src_task,
kern_handle_t *out); kern_handle_t src_handle,
kern_handle_t dest_task,
kern_handle_t dest_handle,
unsigned int mode,
kern_handle_t *out_handle);
#endif #endif
+3
View File
@@ -4,5 +4,8 @@
#include <mango/types.h> #include <mango/types.h>
extern kern_status_t kern_object_wait(kern_wait_item_t *items, size_t nr_items); extern kern_status_t kern_object_wait(kern_wait_item_t *items, size_t nr_items);
extern kern_status_t kern_object_query(
kern_handle_t handle,
kern_object_info_t *out);
#endif #endif
+2 -1
View File
@@ -3,7 +3,7 @@
#define SYS_KERN_LOG 1 #define SYS_KERN_LOG 1
#define SYS_KERN_HANDLE_CLOSE 2 #define SYS_KERN_HANDLE_CLOSE 2
#define SYS_KERN_HANDLE_DUPLICATE 3 #define SYS_KERN_HANDLE_TRANSFER 3
#define SYS_KERN_CONFIG_GET 4 #define SYS_KERN_CONFIG_GET 4
#define SYS_KERN_CONFIG_SET 5 #define SYS_KERN_CONFIG_SET 5
#define SYS_KERN_OBJECT_WAIT 6 #define SYS_KERN_OBJECT_WAIT 6
@@ -49,5 +49,6 @@
#define SYS_VM_CONTROLLER_SUPPLY_PAGES 46 #define SYS_VM_CONTROLLER_SUPPLY_PAGES 46
#define SYS_FUTEX_WAIT 47 #define SYS_FUTEX_WAIT 47
#define SYS_FUTEX_WAKE 48 #define SYS_FUTEX_WAKE 48
#define SYS_KERN_OBJECT_QUERY 49
#endif #endif
+7 -3
View File
@@ -32,13 +32,13 @@
#define KERN_MSG_MAX_HANDLES 64 #define KERN_MSG_MAX_HANDLES 64
/* the corresponding handle should be ignored */ /* the corresponding handle should be ignored */
#define KERN_MSG_HANDLE_IGNORE 0 #define HANDLE_TRANSFER_IGNORE 0
/* the corresponding handle should be moved to the recipient task. the handle /* the corresponding handle should be moved to the recipient task. the handle
* will be closed. */ * will be closed. */
#define KERN_MSG_HANDLE_MOVE 1 #define HANDLE_TRANSFER_MOVE 1
/* the corresponding handle should be copied to the recipient task. the handle /* the corresponding handle should be copied to the recipient task. the handle
* will remain valid for the sending task. */ * will remain valid for the sending task. */
#define KERN_MSG_HANDLE_COPY 2 #define HANDLE_TRANSFER_COPY 2
/* maximum number of objects that can be waited on in a single call to /* maximum number of objects that can be waited on in a single call to
* kern_object_wait */ * kern_object_wait */
@@ -109,6 +109,10 @@ typedef unsigned short equeue_packet_type_t;
typedef unsigned int umode_t; typedef unsigned int umode_t;
typedef struct {
koid_t obj_id;
} kern_object_info_t;
typedef struct { typedef struct {
virt_addr_t io_base; virt_addr_t io_base;
size_t io_len; size_t io_len;
+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;
} }
+2 -1
View File
@@ -27,7 +27,7 @@ static const virt_addr_t syscall_table[] = {
SYSCALL_TABLE_ENTRY(ADDRESS_SPACE_RELEASE, address_space_release), SYSCALL_TABLE_ENTRY(ADDRESS_SPACE_RELEASE, address_space_release),
SYSCALL_TABLE_ENTRY(KERN_LOG, kern_log), SYSCALL_TABLE_ENTRY(KERN_LOG, kern_log),
SYSCALL_TABLE_ENTRY(KERN_HANDLE_CLOSE, kern_handle_close), SYSCALL_TABLE_ENTRY(KERN_HANDLE_CLOSE, kern_handle_close),
SYSCALL_TABLE_ENTRY(KERN_HANDLE_DUPLICATE, kern_handle_duplicate), SYSCALL_TABLE_ENTRY(KERN_HANDLE_TRANSFER, kern_handle_transfer),
SYSCALL_TABLE_ENTRY(KERN_CONFIG_GET, kern_config_get), SYSCALL_TABLE_ENTRY(KERN_CONFIG_GET, kern_config_get),
SYSCALL_TABLE_ENTRY(KERN_CONFIG_SET, kern_config_set), SYSCALL_TABLE_ENTRY(KERN_CONFIG_SET, kern_config_set),
SYSCALL_TABLE_ENTRY(CHANNEL_CREATE, channel_create), SYSCALL_TABLE_ENTRY(CHANNEL_CREATE, channel_create),
@@ -52,6 +52,7 @@ static const virt_addr_t syscall_table[] = {
VM_CONTROLLER_SUPPLY_PAGES, VM_CONTROLLER_SUPPLY_PAGES,
vm_controller_supply_pages), vm_controller_supply_pages),
SYSCALL_TABLE_ENTRY(KERN_OBJECT_WAIT, kern_object_wait), SYSCALL_TABLE_ENTRY(KERN_OBJECT_WAIT, kern_object_wait),
SYSCALL_TABLE_ENTRY(KERN_OBJECT_QUERY, kern_object_query),
SYSCALL_TABLE_ENTRY(FUTEX_WAIT, futex_wait), SYSCALL_TABLE_ENTRY(FUTEX_WAIT, futex_wait),
SYSCALL_TABLE_ENTRY(FUTEX_WAKE, futex_wake), SYSCALL_TABLE_ENTRY(FUTEX_WAKE, futex_wake),
}; };
+109 -9
View File
@@ -8,32 +8,132 @@ kern_status_t sys_kern_handle_close(kern_handle_t handle)
return task_close_handle(self, handle); return task_close_handle(self, handle);
} }
kern_status_t sys_kern_handle_duplicate( kern_status_t sys_kern_handle_transfer(
kern_handle_t handle, kern_handle_t src_task_handle,
kern_handle_t *out) kern_handle_t src_handle,
kern_handle_t dest_task_handle,
kern_handle_t dest_handle,
unsigned int mode,
kern_handle_t *out_handle)
{ {
switch (mode) {
case HANDLE_TRANSFER_MOVE:
case HANDLE_TRANSFER_COPY:
break;
default:
return KERN_INVALID_ARGUMENT;
}
struct task *self = current_task(); struct task *self = current_task();
if (!validate_access_w(self, out, sizeof *out)) { if (out_handle
&& !validate_access_w(self, out_handle, sizeof *out_handle)) {
return KERN_MEMORY_FAULT; return KERN_MEMORY_FAULT;
} }
unsigned long flags; unsigned long flags;
task_lock_irqsave(self, &flags); task_lock_irqsave(self, &flags);
struct object *src_object = NULL;
struct task *src_task = NULL;
struct task *dest_task = NULL;
kern_status_t status = KERN_OK;
struct object *obj = NULL; struct object *obj = NULL;
handle_flags_t handle_flags = 0; handle_flags_t handle_flags = 0;
kern_status_t status
= task_resolve_handle(self, handle, &obj, &handle_flags); if (src_task_handle != KERN_HANDLE_INVALID) {
status = task_resolve_handle(
self,
src_task_handle,
&obj,
&handle_flags);
if (status != KERN_OK) { if (status != KERN_OK) {
task_unlock_irqrestore(self, flags); task_unlock_irqrestore(self, flags);
return status; goto cleanup;
} }
status = task_open_handle(self, obj, handle_flags, out); src_task = task_cast(obj);
object_unref(obj); if (!src_task) {
status = KERN_INVALID_ARGUMENT;
goto cleanup;
}
} else {
src_task = self;
}
if (dest_task_handle != KERN_HANDLE_INVALID) {
status = task_resolve_handle(
self,
dest_task_handle,
&obj,
&handle_flags);
if (status != KERN_OK) {
task_unlock_irqrestore(self, flags);
goto cleanup;
}
dest_task = task_cast(obj);
if (!dest_task) {
status = KERN_INVALID_ARGUMENT;
goto cleanup;
}
} else {
dest_task = self;
}
status = task_resolve_handle(
self,
src_handle,
&src_object,
&handle_flags);
if (status != KERN_OK) {
goto cleanup;
}
task_unlock_irqrestore(self, flags); task_unlock_irqrestore(self, flags);
struct handle *dest = NULL;
task_lock_irqsave(dest_task, &flags);
status = handle_table_alloc_handle(
dest_task->t_handles,
dest_handle,
&dest,
&dest_handle);
task_unlock_irqrestore(dest_task, flags);
if (status != KERN_OK) {
goto cleanup;
}
if (mode == HANDLE_TRANSFER_MOVE) {
object_ref(src_object);
task_lock_irqsave(src_task, &flags);
handle_table_free_handle(src_task->t_handles, src_handle);
task_unlock_irqrestore(src_task, flags);
}
dest->h_object = src_object;
dest->h_flags = handle_flags;
if (out_handle) {
*out_handle = dest_handle;
}
return KERN_OK;
cleanup:
if (src_task && src_task_handle != KERN_HANDLE_INVALID) {
object_unref(&src_task->t_base);
}
if (dest_task && dest_task_handle != KERN_HANDLE_INVALID) {
object_unref(&dest_task->t_base);
}
if (src_object) {
object_unref(src_object);
}
return status; return status;
} }
+4
View File
@@ -5,8 +5,12 @@
kern_status_t sys_kern_log(const char *s) kern_status_t sys_kern_log(const char *s)
{ {
#ifdef TRACE
struct task *task = current_task(); struct task *task = current_task();
struct thread *thread = current_thread(); struct thread *thread = current_thread();
printk("%s[%d.%d]: %s", task->t_name, task->t_id, thread->tr_id, s); printk("%s[%d.%d]: %s", task->t_name, task->t_id, thread->tr_id, s);
#else
printk("%s", s);
#endif
return KERN_OK; return KERN_OK;
} }
+2 -2
View File
@@ -240,12 +240,12 @@ kern_status_t sys_msg_send(
port_handle, port_handle,
&port_obj, &port_obj,
&port_handle_flags); &port_handle_flags);
task_unlock_irqrestore(self, flags);
if (status != KERN_OK) { if (status != KERN_OK) {
return status; return status;
} }
task_unlock_irqrestore(self, flags);
struct port *port = port_cast(port_obj); struct port *port = port_cast(port_obj);
if (!port) { if (!port) {
object_unref(port_obj); object_unref(port_obj);
+29
View File
@@ -80,3 +80,32 @@ cleanup:
self_thread->tr_state = THREAD_READY; self_thread->tr_state = THREAD_READY;
return status; return status;
} }
kern_status_t sys_kern_object_query(
kern_handle_t object_handle,
kern_object_info_t *out)
{
struct task *self = current_task();
if (!out) {
return KERN_INVALID_ARGUMENT;
}
if (!validate_access_w(self, out, sizeof *out)) {
return KERN_MEMORY_FAULT;
}
struct object *obj = NULL;
handle_flags_t flags = 0;
kern_status_t status
= task_resolve_handle(self, object_handle, &obj, &flags);
if (status != KERN_OK) {
return status;
}
out->obj_id = obj->ob_id;
object_unref(obj);
return KERN_OK;
}
+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);