Commit 4ae6ed9d authored by Jeremy Soller's avatar Jeremy Soller

Pass syscall data to syscall, implement iopl

parent f7b961dd
#[naked]
pub unsafe extern fn syscall() {
#[inline(never)]
unsafe fn inner() {
unsafe fn inner(stack: &mut SyscallStack) {
extern {
fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, stack: usize) -> usize;
fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, rbp: usize, stack: &mut SyscallStack) -> usize;
}
let mut a;
{
let b;
let c;
let d;
let e;
let f;
let stack;
asm!("" : "={rax}"(a), "={rbx}"(b), "={rcx}"(c), "={rdx}"(d), "={rsi}"(e), "={rdi}"(f), "={rbp}"(stack)
let rbp;
asm!("" : "={rax}"(a), "={rbx}"(b), "={rbp}"(rbp)
: : : "intel", "volatile");
a = syscall(a, b, c, d, e, f, stack);
a = syscall(a, b, stack.rcx, stack.rdx, stack.rsi, stack.rdi, rbp, stack);
}
asm!("" : : "{rax}"(a) : : "intel", "volatile");
......@@ -37,7 +33,11 @@ pub unsafe extern fn syscall() {
mov fs, r11"
: : : : "intel", "volatile");
inner();
// Get reference to stack variables
let rsp: usize;
asm!("" : "={rsp}"(rsp) : : : "intel", "volatile");
inner(&mut *(rsp as *mut SyscallStack));
// Interrupt return
asm!("pop fs
......@@ -53,6 +53,23 @@ pub unsafe extern fn syscall() {
: : : : "intel", "volatile");
}
#[allow(dead_code)]
#[repr(packed)]
pub struct SyscallStack {
pub fs: usize,
pub r11: usize,
pub r10: usize,
pub r9: usize,
pub r8: usize,
pub rsi: usize,
pub rdi: usize,
pub rdx: usize,
pub rcx: usize,
pub rip: usize,
pub cs: usize,
pub rflags: usize,
}
#[naked]
pub unsafe extern fn clone_ret() -> usize {
asm!("pop rbp"
......
......@@ -85,7 +85,7 @@ macro_rules! interrupt_stack {
#[naked]
pub unsafe extern fn $name () {
#[inline(never)]
unsafe fn inner($stack: &$crate::macros::InterruptStack) {
unsafe fn inner($stack: &mut $crate::macros::InterruptStack) {
$func
}
......@@ -109,7 +109,7 @@ macro_rules! interrupt_stack {
asm!("" : "={rsp}"(rsp) : : : "intel", "volatile");
// Call inner rust function
inner(&*(rsp as *const $crate::macros::InterruptStack));
inner(&mut *(rsp as *mut $crate::macros::InterruptStack));
// Pop scratch registers and return
asm!("pop fs
......
......@@ -172,7 +172,7 @@ pub unsafe fn usermode(ip: usize, sp: usize, arg: usize) -> ! {
: "{r10}"(gdt::GDT_USER_DATA << 3 | 3), // Data segment
"{r11}"(gdt::GDT_USER_TLS << 3 | 3), // TLS segment
"{r12}"(sp), // Stack pointer
"{r13}"(3 << 12 | 1 << 9), // Flags - Set IOPL and interrupt enable flag
"{r13}"(0 << 12 | 1 << 9), // Flags - Set IOPL and interrupt enable flag
"{r14}"(gdt::GDT_USER_CODE << 3 | 3), // Code segment
"{r15}"(ip) // IP
"{rdi}"(arg) // Argument
......
use interrupt::syscall::SyscallStack;
use memory::{allocate_frames, deallocate_frames, Frame};
use paging::{entry, ActivePageTable, PhysicalAddress, VirtualAddress};
use context;
use context::memory::Grant;
use syscall::error::{Error, EFAULT, ENOMEM, EPERM, ESRCH, Result};
use syscall::error::{Error, EFAULT, EINVAL, ENOMEM, EPERM, ESRCH, Result};
use syscall::flag::{MAP_WRITE, MAP_WRITE_COMBINE};
fn enforce_root() -> Result<()> {
......@@ -16,10 +17,15 @@ fn enforce_root() -> Result<()> {
}
}
pub fn iopl(_level: usize, _stack_base: usize) -> Result<usize> {
pub fn iopl(level: usize, stack: &mut SyscallStack) -> Result<usize> {
enforce_root()?;
//TODO
if level > 3 {
return Err(Error::new(EINVAL));
}
stack.rflags = (stack.rflags & !(3 << 12)) | ((level & 3) << 12);
Ok(0)
}
......
......@@ -17,6 +17,7 @@ use self::error::{Error, Result, ENOSYS};
use self::number::*;
use context::ContextId;
use interrupt::syscall::SyscallStack;
use scheme::{FileHandle, SchemeNamespace};
/// Driver syscalls
......@@ -41,9 +42,9 @@ pub mod time;
pub mod validate;
#[no_mangle]
pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, stack: usize) -> usize {
pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, bp: usize, stack: &mut SyscallStack) -> usize {
#[inline(always)]
fn inner(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, stack: usize) -> Result<usize> {
fn inner(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, bp: usize, stack: &mut SyscallStack) -> Result<usize> {
match a & SYS_CLASS {
SYS_CLASS_FILE => {
let fd = FileHandle::from(b);
......@@ -83,7 +84,7 @@ pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize
SYS_BRK => brk(b),
SYS_GETPID => getpid().map(ContextId::into),
SYS_GETPPID => getppid().map(ContextId::into),
SYS_CLONE => clone(b, stack).map(ContextId::into),
SYS_CLONE => clone(b, bp).map(ContextId::into),
SYS_EXIT => exit((b & 0xFF) << 8),
SYS_KILL => kill(ContextId::from(b), c),
SYS_WAITPID => waitpid(ContextId::from(b), c, d).map(ContextId::into),
......@@ -127,7 +128,7 @@ pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize
}
}
let result = inner(a, b, c, d, e, f, stack);
let result = inner(a, b, c, d, e, f, bp, stack);
/*
if let Err(ref err) = result {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment