core: Add "tokens" to determine what processes can call which syscalls
This commit is contained in:
parent
6fa70693a5
commit
c24bc8ed27
@ -1,4 +1,5 @@
|
||||
const std = @import("std");
|
||||
const system = @import("system");
|
||||
const easyboot = @cImport(@cInclude("easyboot.h"));
|
||||
const debug = @import("arch/debug.zig");
|
||||
const cpu = @import("arch/cpu.zig");
|
||||
@ -70,6 +71,7 @@ export fn _start(magic: u32, info: MultibootInfo) callconv(.C) noreturn {
|
||||
|
||||
init.address_space = space;
|
||||
init.user_priority = 255;
|
||||
init.tokens = @intFromEnum(system.kernel.Token.Root);
|
||||
thread.arch.initUserRegisters(&init.regs);
|
||||
thread.arch.setArguments(&init.regs, base, space.phys.address);
|
||||
|
||||
|
@ -1,8 +1,15 @@
|
||||
const system = @import("system");
|
||||
const platform = @import("../arch/platform.zig");
|
||||
const sys = @import("syscall.zig");
|
||||
const pmm = @import("../pmm.zig");
|
||||
const cpu = @import("../arch/cpu.zig");
|
||||
const thread = @import("../thread.zig");
|
||||
const vmm = @import("../arch/vmm.zig");
|
||||
|
||||
pub fn allocFrame(_: *platform.Registers, _: *sys.Arguments, retval: *isize) anyerror!void {
|
||||
const core = cpu.thisCore();
|
||||
if (!sys.checkToken(core, system.kernel.Token.PhysicalMemory)) return error.NotAuthorized;
|
||||
|
||||
const allocator = pmm.lockGlobalAllocator();
|
||||
defer pmm.unlockGlobalAllocator();
|
||||
|
||||
@ -12,6 +19,9 @@ pub fn allocFrame(_: *platform.Registers, _: *sys.Arguments, retval: *isize) any
|
||||
}
|
||||
|
||||
pub fn freeFrame(_: *platform.Registers, args: *sys.Arguments, _: *isize) anyerror!void {
|
||||
const core = cpu.thisCore();
|
||||
if (!sys.checkToken(core, system.kernel.Token.PhysicalMemory)) return error.NotAuthorized;
|
||||
|
||||
const allocator = pmm.lockGlobalAllocator();
|
||||
defer pmm.unlockGlobalAllocator();
|
||||
|
||||
@ -19,8 +29,20 @@ pub fn freeFrame(_: *platform.Registers, args: *sys.Arguments, _: *isize) anyerr
|
||||
}
|
||||
|
||||
pub fn lockFrame(_: *platform.Registers, args: *sys.Arguments, _: *isize) anyerror!void {
|
||||
const core = cpu.thisCore();
|
||||
if (!sys.checkToken(core, system.kernel.Token.PhysicalMemory)) return error.NotAuthorized;
|
||||
|
||||
const allocator = pmm.lockGlobalAllocator();
|
||||
defer pmm.unlockGlobalAllocator();
|
||||
|
||||
try pmm.lockFrame(allocator, args.arg0);
|
||||
}
|
||||
|
||||
pub fn setAddressSpace(_: *platform.Registers, args: *sys.Arguments, _: *isize) anyerror!void {
|
||||
const core = cpu.thisCore();
|
||||
if (!sys.checkToken(core, system.kernel.Token.VirtualMemory)) return error.NotAuthorized;
|
||||
|
||||
const target = thread.lookupThreadById(args.arg0) orelse return error.NoSuchThread;
|
||||
|
||||
target.address_space = vmm.AddressSpace.create(.{ .address = args.arg1 }, vmm.PHYSICAL_MAPPING_BASE);
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ const RingBuffer = system.ring_buffer.RingBuffer;
|
||||
const SyscallError = error{
|
||||
NoSuchThread,
|
||||
ThreadQueueAlreadySet,
|
||||
NotAuthorized,
|
||||
};
|
||||
|
||||
pub fn yield(regs: *platform.Registers, _: *sys.Arguments, _: *isize) anyerror!void {
|
||||
@ -23,6 +24,9 @@ pub fn yield(regs: *platform.Registers, _: *sys.Arguments, _: *isize) anyerror!v
|
||||
|
||||
pub fn setPriority(_: *platform.Registers, args: *sys.Arguments, _: *isize) anyerror!void {
|
||||
const core = cpu.thisCore();
|
||||
|
||||
if (!sys.checkToken(core, system.kernel.Token.ThreadPriority)) return error.NotAuthorized;
|
||||
|
||||
core.current_thread.user_priority = @truncate(args.arg0);
|
||||
}
|
||||
|
||||
@ -36,6 +40,8 @@ pub fn sleep(regs: *platform.Registers, args: *sys.Arguments, _: *isize) anyerro
|
||||
}
|
||||
|
||||
pub fn setEventQueue(_: *platform.Registers, args: *sys.Arguments, _: *isize) anyerror!void {
|
||||
const core = cpu.thisCore();
|
||||
if (!sys.checkToken(core, system.kernel.Token.EventQueue)) return error.NotAuthorized;
|
||||
const target = thread.lookupThreadById(args.arg0) orelse return error.NoSuchThread;
|
||||
|
||||
if (target.event_queue) |_| return error.ThreadQueueAlreadySet;
|
||||
|
@ -1,8 +1,11 @@
|
||||
const std = @import("std");
|
||||
const system = @import("system");
|
||||
const platform = @import("../arch/platform.zig");
|
||||
const print = @import("print.zig");
|
||||
const mem = @import("mem.zig");
|
||||
const sched = @import("sched.zig");
|
||||
const tokens = @import("token.zig");
|
||||
const cpu = @import("../arch/cpu.zig");
|
||||
|
||||
pub const Arguments = struct {
|
||||
arg0: usize,
|
||||
@ -15,7 +18,18 @@ pub const Arguments = struct {
|
||||
|
||||
const SystemCall = *const fn (frame: *platform.Registers, args: *Arguments, retval: *isize) anyerror!void;
|
||||
|
||||
const syscalls = [_]SystemCall{ print.print, mem.allocFrame, mem.lockFrame, mem.freeFrame, sched.yield, sched.setPriority, sched.getPriority, sched.sleep, sched.setEventQueue };
|
||||
const syscalls = [_]SystemCall{
|
||||
print.print,
|
||||
mem.allocFrame,
|
||||
mem.lockFrame,
|
||||
mem.freeFrame,
|
||||
sched.yield,
|
||||
sched.setPriority,
|
||||
sched.getPriority,
|
||||
sched.sleep,
|
||||
sched.setEventQueue,
|
||||
tokens.setTokens,
|
||||
};
|
||||
|
||||
pub fn invokeSyscall(number: usize, frame: *platform.Registers, args: *Arguments, retval: *isize) void {
|
||||
if (number >= syscalls.len) {
|
||||
@ -28,3 +42,7 @@ pub fn invokeSyscall(number: usize, frame: *platform.Registers, args: *Arguments
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
pub fn checkToken(core: *cpu.arch.Core, token: system.kernel.Token) bool {
|
||||
return (core.current_thread.tokens & @intFromEnum(token)) > 0;
|
||||
}
|
||||
|
14
core/src/sys/token.zig
Normal file
14
core/src/sys/token.zig
Normal file
@ -0,0 +1,14 @@
|
||||
const system = @import("system");
|
||||
const platform = @import("../arch/platform.zig");
|
||||
const sys = @import("syscall.zig");
|
||||
const cpu = @import("../arch/cpu.zig");
|
||||
const thread = @import("../thread.zig");
|
||||
|
||||
pub fn setTokens(_: *platform.Registers, args: *sys.Arguments, _: *isize) anyerror!void {
|
||||
const core = cpu.thisCore();
|
||||
if (!sys.checkToken(core, system.kernel.Token.Root)) return error.NotAuthorized;
|
||||
|
||||
const target = thread.lookupThreadById(args.arg0) orelse return error.NoSuchThread;
|
||||
|
||||
target.tokens = args.arg1;
|
||||
}
|
@ -24,6 +24,7 @@ pub const ThreadControlBlock = struct {
|
||||
state: ThreadState,
|
||||
user_priority: u8,
|
||||
event_queue: ?RingBuffer,
|
||||
tokens: u64,
|
||||
|
||||
// Managed by addThreadToGlobalList(), no need to set manually.
|
||||
tag: GlobalThreadList.Node,
|
||||
@ -151,6 +152,7 @@ pub fn createThreadControlBlock(allocator: *pmm.FrameAllocator) !*ThreadControlB
|
||||
thread.state = .Inactive;
|
||||
thread.user_priority = 127;
|
||||
thread.event_queue = null;
|
||||
thread.tokens = 0;
|
||||
|
||||
addThreadToGlobalList(thread);
|
||||
|
||||
|
@ -7,17 +7,30 @@ const buffer = system.ring_buffer;
|
||||
// FIXME: Make arch-specific.
|
||||
const PAGE_SIZE = 4096;
|
||||
|
||||
const SELF_PID = 1;
|
||||
|
||||
fn setupKernelRingBuffer(base: u64) !buffer.RingBuffer {
|
||||
const phys = vm.PhysFrame{ .address = try syscalls.allocFrame() };
|
||||
|
||||
const data: [*]u8 = @ptrCast(phys.virtualPointer(u8, base));
|
||||
|
||||
try syscalls.setEventQueue(1, phys.address);
|
||||
try syscalls.setEventQueue(SELF_PID, phys.address);
|
||||
|
||||
return buffer.RingBuffer.init(data, PAGE_SIZE, true);
|
||||
}
|
||||
|
||||
fn setTokens() void {
|
||||
var tokens: u64 = 0;
|
||||
tokens |= @intFromEnum(system.kernel.Token.Root);
|
||||
tokens |= @intFromEnum(system.kernel.Token.PhysicalMemory);
|
||||
tokens |= @intFromEnum(system.kernel.Token.EventQueue);
|
||||
tokens |= @intFromEnum(system.kernel.Token.VirtualMemory);
|
||||
syscalls.setTokens(SELF_PID, tokens) catch {};
|
||||
}
|
||||
|
||||
export fn _start(base: u64, address: u64) callconv(.C) noreturn {
|
||||
setTokens();
|
||||
|
||||
const mapper = vm.MemoryMapper.create(.{ .address = address }, base);
|
||||
|
||||
syscalls.print(base);
|
||||
|
@ -8,9 +8,20 @@ pub const SystemCall = enum(u64) {
|
||||
GetPriority,
|
||||
Sleep,
|
||||
SetEventQueue,
|
||||
SetTokens,
|
||||
SetAddressSpace,
|
||||
};
|
||||
|
||||
pub const Token = enum(u64) {
|
||||
Root = 1 << 0,
|
||||
PhysicalMemory = 1 << 1,
|
||||
ThreadPriority = 1 << 2,
|
||||
EventQueue = 1 << 3,
|
||||
VirtualMemory = 1 << 4,
|
||||
};
|
||||
|
||||
pub const SystemError = error{
|
||||
OutOfMemory,
|
||||
NoSuchThread,
|
||||
NotAuthorized,
|
||||
};
|
||||
|
@ -51,3 +51,8 @@ pub fn setEventQueue(pid: u64, address: u64) !void {
|
||||
const retval = syscall(.SetEventQueue, pid, address);
|
||||
if (retval < 0) return error.NoSuchThread;
|
||||
}
|
||||
|
||||
pub fn setTokens(pid: u64, tokens: u64) !void {
|
||||
const retval = syscall(.SetTokens, pid, tokens);
|
||||
if (retval < 0) return error.NoSuchThread;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user