aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/uapi/cap.c87
-rw-r--r--common/uapi/dispatch.c5
-rw-r--r--include/apos/caps.h70
-rw-r--r--include/apos/syscalls.h9
-rw-r--r--include/apos/tcb.h5
-rw-r--r--include/apos/types.h2
-rw-r--r--include/apos/uapi.h42
7 files changed, 215 insertions, 5 deletions
diff --git a/common/uapi/cap.c b/common/uapi/cap.c
new file mode 100644
index 0000000..84dbc45
--- /dev/null
+++ b/common/uapi/cap.c
@@ -0,0 +1,87 @@
+#include <apos/uapi.h>
+#include <apos/caps.h>
+#include <apos/tcb.h>
+
+/**
+ * @file cap.c
+ * Sycalls handlers for thread capabilities.
+ */
+
+/**
+ * Check that values are legal for thread ID and offset.
+ *
+ * @param tid Thread ID of thread whose caps should be fetched.
+ * @param off Offset of capabilities.
+ * @return Pointer to capabilities of \p tid, \c 0 otherwise.
+ */
+static capflags_t *__get_tcb_caps(id_t tid, size_t off)
+{
+ if (!cap_off_ok(off))
+ return NULL;
+
+ struct tcb *t = get_tcb(tid);
+ if (!t)
+ return NULL;
+
+ return &t->caps;
+}
+
+/**
+ * Set capabilities.
+ *
+ * @param tid Thread ID whose capabilities to set.
+ * @param off Offset of capability, multiple of \c bits(cap).
+ * @param caps Mask of capabilities to set.
+ * @return \ref OK on success, \ref ERR_INVAL on invalid input.
+ */
+SYSCALL_DEFINE3(set_cap)(sys_arg_t tid, sys_arg_t off, sys_arg_t caps)
+{
+ struct tcb *t = cur_tcb();
+ if (!is_set(t->caps, CAP_CAPS))
+ return (struct sys_ret){ERR_PERM, 0, 0, 0, 0, 0};
+
+ capflags_t *c;
+ if (!(c = __get_tcb_caps(tid, off)))
+ return (struct sys_ret){ERR_INVAL, 0, 0, 0, 0, 0};
+
+ set_caps(*c, off, caps);
+ return (struct sys_ret){OK, 0, 0, 0, 0, 0};
+}
+
+/**
+ * Get capabilities.
+ *
+ * @param tid Thread ID whose capabilities to get.
+ * @param off Offset of capability, multiple of \c bits(cap).
+ * @return \ref OK, capabilities.
+ */
+SYSCALL_DEFINE2(get_cap)(sys_arg_t tid, sys_arg_t off)
+{
+ capflags_t *c;
+ if (!(c = __get_tcb_caps(tid, off)))
+ return (struct sys_ret){ERR_INVAL, 0, 0, 0, 0, 0};
+
+ return (struct sys_ret){OK, get_caps(*c, off), 0, 0, 0, 0};
+}
+
+/**
+ * Clear capabilities.
+ *
+ * @param tid Thread ID whose capabilities to clear.
+ * @param off Offset of capability, multiple of \c bits(cap).
+ * @param caps Mask of capabilities to clear.
+ * @return \ref OK.
+ */
+SYSCALL_DEFINE3(clear_cap)(sys_arg_t tid, sys_arg_t off, sys_arg_t caps)
+{
+ struct tcb *t = cur_tcb();
+ if (!is_set(t->caps, CAP_CAPS))
+ return (struct sys_ret){ERR_PERM, 0, 0, 0, 0, 0};
+
+ capflags_t *c;
+ if (!(c = __get_tcb_caps(tid, off)))
+ return (struct sys_ret){ERR_INVAL, 0, 0, 0, 0, 0};
+
+ clear_caps(*c, off, caps);
+ return (struct sys_ret){OK, 0, 0, 0, 0, 0};
+}
diff --git a/common/uapi/dispatch.c b/common/uapi/dispatch.c
index f0f6ae0..30b2e2e 100644
--- a/common/uapi/dispatch.c
+++ b/common/uapi/dispatch.c
@@ -46,6 +46,11 @@ static const sys_t syscall_table[] = {
/* conf */
[SYS_CONF_SET] = sys_conf_set,
[SYS_CONF_GET] = sys_conf_get,
+
+ [SYS_SET_CAP] = sys_set_cap,
+ [SYS_GET_CAP] = sys_get_cap,
+ [SYS_CLEAR_CAP] = sys_clear_cap,
+
[SYS_POWEROFF] = sys_poweroff,
};
diff --git a/include/apos/caps.h b/include/apos/caps.h
new file mode 100644
index 0000000..e8ef76b
--- /dev/null
+++ b/include/apos/caps.h
@@ -0,0 +1,70 @@
+#ifndef APOS_CAPS_H
+#define APOS_CAPS_H
+
+/**
+ * @file caps.h
+ * Capabilities of threads.
+ * \todo The list of capabilities should maybe be placed in some other file so
+ * as to easier extract it into userspace programs.
+ */
+
+#include <apos/bits.h>
+
+/** Helper typedef for capabilities. */
+typedef unsigned char capflags_t;
+
+enum {
+ /** Thread is allowed to set capabilities of other threads. */
+ CAP_CAPS = (1 << 0),
+
+ /** Thread is allowed to modify process statuses, exec/fork/etc. */
+ CAP_PROC = (1 << 1),
+
+ /** Thread is allowed to force interrupt to callback in other thread. */
+ CAP_CALL = (1 << 2),
+};
+
+/**
+ * Check that offset is OK.
+ *
+ * @param o Offset to check.
+ * @return \ref true is OK, \ref false otherwise.
+ */
+#define cap_off_ok(o) (o == 0)
+
+/**
+ * Set capabilities.
+ *
+ * @param x Capabilities to modify.
+ * @param o Offset.
+ * @param c Capabilities to set.
+ */
+#define set_caps(x, o, c) set_bits(x, c)
+
+/**
+ * Clear capabilities.
+ *
+ * @param x Capabilities to modify.
+ * @param o Offset.
+ * @param c Capabilities to set.
+ */
+#define clear_caps(x, o, c) clear_bits(x, c)
+
+/**
+ * Copy capabilities.
+ *
+ * @param x Capabilities to copy to.
+ * @param y Capabilities to copy from.
+ */
+#define copy_caps(x, y) (x = y)
+
+/**
+ * Get capabilities at offset \p o.
+ *
+ * @param x Capabilities to get from.
+ * @param o Offset to get capabilities from.
+ * @return Capabilities at offset \p o.
+ */
+#define get_caps(x, o) (x)
+
+#endif /* APOS_CAPS_H */
diff --git a/include/apos/syscalls.h b/include/apos/syscalls.h
index 229e17e..0a6f0c7 100644
--- a/include/apos/syscalls.h
+++ b/include/apos/syscalls.h
@@ -108,6 +108,15 @@ enum {
/** Get system parameters. */
SYS_CONF_GET,
+ /** Set capability of thread. */
+ SYS_SET_CAP,
+
+ /** Get capabilities of thread. */
+ SYS_GET_CAP,
+
+ /** Clear capability of thread. */
+ SYS_CLEAR_CAP,
+
/** Shutdown, reboot, etc. */
SYS_POWEROFF,
/** @} */
diff --git a/include/apos/tcb.h b/include/apos/tcb.h
index 9e63a9a..41b5237 100644
--- a/include/apos/tcb.h
+++ b/include/apos/tcb.h
@@ -10,6 +10,7 @@
*/
#include <apos/mem_regions.h>
+#include <apos/caps.h>
#include <apos/types.h>
#include <arch/tcb.h> /* arch-specific data */
@@ -108,8 +109,8 @@ struct tcb {
/** Address of callback function in servers. */
vm_t callback;
- /** Address of signal callback. */
- vm_t signal;
+ /** Capabilities of thread. */
+ capflags_t caps;
/** Address of this thread's stack base. */
vm_t thread_stack;
diff --git a/include/apos/types.h b/include/apos/types.h
index f249705..e06ccd0 100644
--- a/include/apos/types.h
+++ b/include/apos/types.h
@@ -455,6 +455,8 @@ typedef uint_fast16_t vmflags_t;
*/
/* should this enum be somewhere else? */
enum status_codes {
+ /** Permission error. */
+ ERR_PERM = -10,
/** Internal error, should probably halt */
ERR_INT = -9,
/** Something went wrong :/ */
diff --git a/include/apos/uapi.h b/include/apos/uapi.h
index 5d61966..d0ce350 100644
--- a/include/apos/uapi.h
+++ b/include/apos/uapi.h
@@ -525,14 +525,14 @@ SYSCALL_DECLARE2(exec, bin, interp);
/**
* Kill syscall.
*
- * @param a Unused.
+ * @param tid Thread ID to kill. 0 if self.
* @param b Unused.
* @param c Unused.
* @param d Unused.
* @param e Unused.
* @return No.
*/
-SYSCALL_DECLARE0(kill);
+SYSCALL_DECLARE1(kill, tid);
/**
* Signal process syscall.
@@ -587,11 +587,47 @@ SYSCALL_DECLARE2(conf_set, param, val);
* @param c Unused.
* @param d Unused.
* @param e Unused.
- * @return \ref OK and 0.
+ * @return \ref OK.
*/
SYSCALL_DECLARE1(conf_get, param);
/**
+ * Set capabilities.
+ *
+ * @param tid Thread ID whose capabilities to set.
+ * @param off Offset of capability, multiple of \c bits(cap).
+ * @param caps Mask of capabilities to set.
+ * @param d Unused.
+ * @param e Unused.
+ * @return \ref OK on success, \ref ERR_INVAL on invalid input.
+ */
+SYSCALL_DECLARE3(set_cap, tid, off, caps);
+
+/**
+ * Get capabilities.
+ *
+ * @param tid Thread ID whose capabilities to get.
+ * @param off Offset of capability, multiple of \c bits(cap).
+ * @param c Unused.
+ * @param d Unused.
+ * @param e Unused.
+ * @return \ref OK, capabilities.
+ */
+SYSCALL_DECLARE2(get_cap, tid, off);
+
+/**
+ * Clear capabilities.
+ *
+ * @param tid Thread ID whose capabilities to clear.
+ * @param off Offset of capability, multiple of \c bits(cap).
+ * @param cap Mask of capabilities to clear.
+ * @param d Unused.
+ * @param e Unused.
+ * @return \ref OK.
+ */
+SYSCALL_DECLARE3(clear_cap, tid, off, cap);
+
+/**
* Power off syscall.
*
* Either shut down or reboot system.