Pass syscall data to syscall, implement iopl
This commit is contained in:
@@ -1,23 +1,19 @@
|
||||
#[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
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
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 {
|
||||
|
||||
Reference in New Issue
Block a user