[kernel] Add capabilities to handles
This change finally adds capabilities to handles. Included changes: - j6_handle_t is now again 64 bits, with the highest 8 bits being a type code, and the next highest 24 bits being the capability mask, so that programs can check type/caps without calling the kernel. - The definitions grammar now includes a `capabilities [ ]` section on objects, to list what capabilities are relevant. - j6/caps.h is auto-generated from object capability lists - init_libj6 again sets __handle_self and __handle_sys, this is a bit of a hack. - A new syscall, j6_handle_list, will return the list of existing handles owned by the calling process. - syscall_verify.cpp.cog now actually checks that the needed capabilities exist on handles before allowing the call.
This commit is contained in:
25
src/libraries/j6/include/j6/caps.h.cog
Normal file
25
src/libraries/j6/include/j6/caps.h.cog
Normal file
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
// vim: ft=cpp
|
||||
|
||||
/// \file caps.h
|
||||
/// Capability bitfield constants
|
||||
|
||||
/*[[[cog code generation
|
||||
from definitions.context import Context
|
||||
|
||||
ctx = Context(definitions_path)
|
||||
ctx.parse("syscalls.def")
|
||||
syscalls = ctx.interfaces["syscalls"]
|
||||
|
||||
for obj in syscalls.exposes:
|
||||
i = 0
|
||||
for cap in obj.object.caps:
|
||||
name = f"j6_cap_{obj.object.name}_{cap}"
|
||||
cog.outl(f"#define {name:<30} (1 << {i})")
|
||||
i += 1
|
||||
|
||||
name = f"j6_cap_{obj.object.name}_all"
|
||||
cog.outl(f"#define {name:<30} ((1<<{i})-1)")
|
||||
cog.outl()
|
||||
]]]*/
|
||||
/// [[[end]]]
|
||||
@@ -18,4 +18,5 @@
|
||||
#define j6_err_not_ready j6_err(0x0004)
|
||||
#define j6_err_insufficient j6_err(0x0005)
|
||||
#define j6_err_timed_out j6_err(0x0006)
|
||||
#define j6_err_denied j6_err(0x0007)
|
||||
|
||||
|
||||
@@ -27,14 +27,16 @@ typedef uint64_t j6_tag_t;
|
||||
#define j6_tag_from_irq(x) ((x) | j6_tag_irq_base)
|
||||
#define j6_tag_to_irq(x) ((x) & ~j6_tag_irq_base)
|
||||
|
||||
/// Handles are references and capabilities to other objects.
|
||||
typedef uint32_t j6_handle_t;
|
||||
/// Handles are references and capabilities to other objects. A handle is
|
||||
/// an id in the lower 32 bits, a bitfield of capabilities in bits 32-55
|
||||
/// and a type id in bits 56-63.
|
||||
typedef uint64_t j6_handle_t;
|
||||
|
||||
/// Bitfield for storage of capabilities on their own
|
||||
typedef uint32_t j6_cap_t;
|
||||
|
||||
#define j6_handle_invalid ((j6_handle_t)-1)
|
||||
|
||||
/// Bitfield for storage of capabilities
|
||||
typedef uint32_t j6_cap_t;
|
||||
|
||||
enum j6_object_type {
|
||||
#define OBJECT_TYPE( name, val ) j6_object_type_ ## name = val,
|
||||
#include <j6/tables/object_types.inc>
|
||||
|
||||
@@ -3,45 +3,47 @@
|
||||
#ifndef __j6kernel
|
||||
|
||||
#include <stdint.h>
|
||||
#include <j6/errors.h>
|
||||
#include <j6/init.h>
|
||||
#include <j6/syscalls.h>
|
||||
#include <j6/types.h>
|
||||
|
||||
static size_t __initc = 0;
|
||||
static struct j6_init_value *__initv = 0;
|
||||
|
||||
j6_handle_t __handle_sys = j6_handle_invalid;
|
||||
j6_handle_t __handle_self = j6_handle_invalid;
|
||||
|
||||
extern "C" void
|
||||
_get_init(size_t *initc, struct j6_init_value **initv)
|
||||
{
|
||||
if (!initc)
|
||||
return;
|
||||
namespace {
|
||||
constexpr size_t __static_arr_size = 4;
|
||||
j6_handle_t __handle_array[__static_arr_size];
|
||||
|
||||
*initc = __initc;
|
||||
if (initv)
|
||||
*initv = __initv;
|
||||
}
|
||||
static j6_status_t
|
||||
__load_handles()
|
||||
{
|
||||
size_t count = __static_arr_size;
|
||||
j6_handle_t *handles = __handle_array;
|
||||
j6_status_t s = j6_handle_list(handles, &count);
|
||||
|
||||
if (s != j6_err_insufficient && s != j6_status_ok)
|
||||
return s;
|
||||
|
||||
if (count > __static_arr_size)
|
||||
count = __static_arr_size;
|
||||
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
uint8_t type = (handles[i] >> 56);
|
||||
if (type == j6_object_type_system && __handle_sys == j6_handle_invalid)
|
||||
__handle_sys = handles[i];
|
||||
else if (type == j6_object_type_process && __handle_self == j6_handle_invalid)
|
||||
__handle_self = handles[i];
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
extern "C" void
|
||||
_init_libj6(uint64_t *rsp)
|
||||
{
|
||||
uint64_t argc = *rsp++;
|
||||
rsp += argc;
|
||||
|
||||
__initc = *rsp++;
|
||||
__initv = (struct j6_init_value *)rsp;
|
||||
|
||||
for (unsigned i = 0; i < __initc; ++i) {
|
||||
if (__initv[i].type == j6_init_handle_other &&
|
||||
__initv[i].handle.type == j6_object_type_system) {
|
||||
__handle_sys = __initv[i].handle.handle;
|
||||
}
|
||||
else if (__initv[i].type == j6_init_handle_self &&
|
||||
__initv[i].handle.type == j6_object_type_process) {
|
||||
__handle_self = __initv[i].handle.handle;
|
||||
}
|
||||
}
|
||||
__load_handles();
|
||||
}
|
||||
|
||||
#endif // __j6kernel
|
||||
|
||||
@@ -5,6 +5,7 @@ j6 = module("j6",
|
||||
includes = [ "include" ],
|
||||
sources = [
|
||||
"init.cpp",
|
||||
"include/j6/caps.h.cog",
|
||||
"include/j6/syscalls.h.cog",
|
||||
"include/j6/sysconf.h.cog",
|
||||
"syscalls.s.cog",
|
||||
@@ -18,6 +19,7 @@ sysconf = join(source_root, "definitions/sysconf.yaml")
|
||||
definitions = glob('definitions/**/*.def', recursive=True)
|
||||
|
||||
j6.add_depends([
|
||||
"include/j6/caps.h.cog",
|
||||
"include/j6/syscalls.h.cog",
|
||||
"syscalls.s.cog",
|
||||
], definitions)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include <j6/syscalls.h>
|
||||
//void *sbrk(intptr_t) __attribute__ ((weak));
|
||||
|
||||
static j6_handle_t __core_handle = 0;
|
||||
static j6_handle_t __core_handle = j6_handle_invalid;
|
||||
static intptr_t __core_size = 0;
|
||||
|
||||
static const uintptr_t __core_base = 0x1c0000000;
|
||||
|
||||
Reference in New Issue
Block a user