Skip to content

Commit

Permalink
Add bash port
Browse files Browse the repository at this point in the history
Rework signals and task termination handling
  • Loading branch information
rafalmiel committed Oct 18, 2023
1 parent bd9aea2 commit fc9c6e4
Show file tree
Hide file tree
Showing 52 changed files with 1,769 additions and 816 deletions.
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ cross_stack := sysroot/build/stack
cross_nyancat := sysroot/build/nyancat
cross_ttytest := sysroot/build/ttytest
cross_fork := sysroot/build/fork
cross_forktest := sysroot/build/forktest

usb_dev := /dev/sdb1

Expand Down Expand Up @@ -117,6 +118,7 @@ hello: $(cross_cpp) sysroot/test.c sysroot/test.cpp sysroot/hello.cpp sysroot/st
$(cross_cpp) sysroot/test.cpp -o $(cross_testcpp)
$(cross_c) sysroot/ttytest.c -o $(cross_ttytest)
$(cross_c) sysroot/fork.c -o $(cross_fork)
$(cross_c) sysroot/forktest.c -o $(cross_forktest)
$(cross_c) sysroot/stat.c -o sysroot/build/stat
sysroot/build.sh cykusz_nyancat
$(cross_strip) $(cross_hello)
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ https://user-images.githubusercontent.com/3881998/183302450-65193783-b10f-4ddd-8
- [x] gcc (<https://github.com/rafalmiel/gcc/tree/cykusz>)
- [x] nyancat (<https://github.com/rafalmiel/nyancat/tree/cykusz>)
- [x] ncurses (<https://github.com/rafalmiel/ncurses/tree/cykusz>)
- [x] bash (<https://github.com/rafalmiel/bash/tree/cykusz>)
- [x] nano (<https://github.com/rafalmiel/nano/tree/cykusz>)
- [x] doom (<https://github.com/rafalmiel/doomgeneric/tree/cykusz>)

Expand Down
10 changes: 7 additions & 3 deletions cykusz-rs/src/arch/x86_64/acpi/rsdt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,13 @@ impl<T: RsdtPtrType> Rsdt<T> {
assert!(i < self.entries_count());

unsafe {
PhysAddr((self.raw_entries().offset(i as isize)).read_unaligned().as_usize())
.to_mapped()
.read_ref::<AcpiStdHeader>()
PhysAddr(
(self.raw_entries().offset(i as isize))
.read_unaligned()
.as_usize(),
)
.to_mapped()
.read_ref::<AcpiStdHeader>()
}
}

Expand Down
1 change: 0 additions & 1 deletion cykusz-rs/src/arch/x86_64/asm/syscall.asm
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ extern fast_syscall_handler
extern restore_user_fs

global asm_update_kern_fs_base
extern arch_sys_check_signals

%include "cykusz-rs/src/arch/x86_64/asm/regs.inc"

Expand Down
13 changes: 7 additions & 6 deletions cykusz-rs/src/arch/x86_64/idt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,6 @@ fn page_fault(frame: &mut idt::InterruptFrame, regs: &mut RegsFrame, err: u64) {
if virt.is_user() {
// page fault originated in userspace
// let the task try handle it

let task = current_task();

//println!("user pagefault {:#x} {} {:?} pid: {}", frame.ip, virt, reason, task.tid());
Expand All @@ -526,11 +525,6 @@ fn page_fault(frame: &mut idt::InterruptFrame, regs: &mut RegsFrame, err: u64) {
frame.ip,
err
);
if VirtAddr(frame.ip as usize).is_user() {
task.signal(syscall_defs::signal::SIGSEGV);

return;
}
}
//println!("user pagefault failed");
} else if reason.contains(PageFaultReason::PRESENT | PageFaultReason::WRITE) {
Expand All @@ -548,6 +542,13 @@ fn page_fault(frame: &mut idt::InterruptFrame, regs: &mut RegsFrame, err: u64) {
}
}

if VirtAddr(frame.ip as usize).is_user() {
let task = current_task();
task.signal(syscall_defs::signal::SIGSEGV);

return;
}

println!(
"PAGE FAULT! 0x{:x} CPU: {}, rip: {:?} virt: {}",
err,
Expand Down
12 changes: 4 additions & 8 deletions cykusz-rs/src/arch/x86_64/mm/phys/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,7 @@ impl PhysPage {
pub fn page_item(&self) -> Option<PageCacheItemArc> {
let _lock = self.lock_pt();

unsafe {
self.this().p_cache.upgrade()
}
unsafe { self.this().p_cache.upgrade() }
}

pub fn inc_vm_use_count(&self) {
Expand Down Expand Up @@ -105,20 +103,18 @@ impl PhysPage {
pub fn vm_use_count(&self) -> usize {
let _lock = self.lock_pt();

unsafe {
self.this().vm_use_count as usize
}
unsafe { self.this().vm_use_count as usize }
}
}

impl Default for PhysPage {
fn default() -> Self {
PhysPage {
pt_lock: Spin::new(()),
data: UnsafeCell::new(PhysPageData{
data: UnsafeCell::new(PhysPageData {
p_cache: PageCacheItemWeak::empty(),
vm_use_count: 0,
})
}),
}
}
}
Expand Down
24 changes: 24 additions & 0 deletions cykusz-rs/src/arch/x86_64/output/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,3 +233,27 @@ macro_rules! log {
$crate::arch::output::log_fmt(format_args!($($arg)*)).unwrap();
});
}
#[macro_export]
macro_rules! logln2 {
($fmt:expr) => (log2!(concat!($fmt, "\n")));
($fmt:expr, $($arg:tt)*) => (log2!(concat!($fmt, "\n"), $($arg)*));
}

#[macro_export]
macro_rules! log2 {
($($arg:tt)*) => {{
//$crate::arch::output::log_fmt(format_args!($($arg)*)).unwrap();
}};
}
#[macro_export]
macro_rules! logln3 {
($fmt:expr) => (log3!(concat!($fmt, "\n")));
($fmt:expr, $($arg:tt)*) => (log3!(concat!($fmt, "\n"), $($arg)*));
}

#[macro_export]
macro_rules! log3 {
($($arg:tt)*) => {{
//$crate::arch::output::log_fmt(format_args!($($arg)*)).unwrap();
}};
}
161 changes: 98 additions & 63 deletions cykusz-rs/src/arch/x86_64/signal.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use syscall_defs::{SyscallError, SyscallResult};
use syscall_defs::{SyscallFrom, SyscallInto, SyscallRestartable, SyscallResult};

use crate::arch::idt::RegsFrame;
use crate::arch::raw::idt::InterruptFrame;
use crate::arch::syscall::SyscallFrame;
use crate::arch::utils::StackHelper;
use crate::kernel::sched::current_task_ref;
use crate::kernel::signal::DoSignalsResult;

const SYSCALL_INSTRUCTION_SIZE: u64 = 2;
const REDZONE_SIZE: u64 = 128;
Expand Down Expand Up @@ -58,88 +59,119 @@ impl SignalFrame {
}

pub fn arch_int_check_signals(frame: &mut InterruptFrame, regs: &mut RegsFrame) {
if let Some((sig, entry)) = crate::kernel::signal::do_signals() {
if let syscall_defs::signal::SignalHandler::Handle(f) = entry.handler() {
let signals = current_task_ref().signals();
let old_mask = signals.blocked_mask();
match crate::kernel::signal::do_signals(false, 0) {
DoSignalsResult::Entry((sig, entry)) => {
if let syscall_defs::signal::SignalHandler::Handle(f) = entry.handler() {
let signals = current_task_ref().signals();
let old_mask = signals.blocked_mask();

let signal_frame = SignalFrame::from_interrupt(frame, regs, old_mask);
let signal_frame = SignalFrame::from_interrupt(frame, regs, old_mask);

signals.set_mask(syscall_defs::signal::SigProcMask::Block, 1u64 << sig, None);
signals.set_mask(
syscall_defs::signal::SigProcMask::Block,
Some(1u64 << (sig - 1)),
None,
);

let mut writer = StackHelper::new(&mut frame.sp);
let mut writer = StackHelper::new(&mut frame.sp);

writer.skip_by(REDZONE_SIZE);
unsafe {
writer.write(signal_frame);
writer.write(entry.sigreturn());
}

frame.ip = f as u64;
writer.skip_by(REDZONE_SIZE);
unsafe {
writer.write(signal_frame);
writer.write(entry.sigreturn());
}

// Signal param
regs.rdi = sig as u64;
frame.ip = f as u64;

logln!("do signal!!!");
// Signal param
regs.rdi = sig as u64;
}
}
DoSignalsResult::Default | DoSignalsResult::Ignore => {
arch_int_check_signals(frame, regs);
}
_ => {}
}
}

#[no_mangle]
pub extern "C" fn arch_sys_check_signals(
syscall_result: isize,
pub fn arch_sys_check_signals(
syscall_result: SyscallResult,
sys_frame: &mut SyscallFrame,
regs: &mut RegsFrame,
) {
if let Some((sig, entry)) = crate::kernel::signal::do_signals() {
if let syscall_defs::signal::SignalHandler::Handle(f) = entry.handler() {
let signals = current_task_ref().signals();
let old_mask = signals.blocked_mask();

let res: SyscallResult = syscall_defs::SyscallFrom::syscall_from(syscall_result);

signals.set_mask(syscall_defs::signal::SigProcMask::Block, 1u64 << sig, None);

let restart = res == Err(SyscallError::EINTR)
&& entry
.flags()
.contains(syscall_defs::signal::SignalFlags::RESTART);

let signal_frame = SignalFrame::from_syscall(
restart,
syscall_result as u64,
sys_frame,
regs,
old_mask,
);

let mut writer = StackHelper::new(&mut sys_frame.rsp);

writer.skip_by(REDZONE_SIZE);
unsafe {
writer.write(signal_frame);
writer.write(entry.sigreturn());
) -> bool {
match crate::kernel::signal::do_signals(true, regs.rax as usize) {
DoSignalsResult::Entry((sig, entry)) => {
if let syscall_defs::signal::SignalHandler::Handle(f) = entry.handler() {
let signals = current_task_ref().signals();
let old_mask = signals.blocked_mask();

signals.set_mask(
syscall_defs::signal::SigProcMask::Block,
Some(1u64 << (sig - 1)),
None,
);

let restart = syscall_result.is_restart(
true,
entry
.flags()
.contains(syscall_defs::signal::SignalFlags::RESTART),
);

let signal_frame = SignalFrame::from_syscall(
restart,
syscall_result.syscall_into() as u64,
sys_frame,
regs,
old_mask,
);

let mut writer = StackHelper::new(&mut sys_frame.rsp);

writer.skip_by(REDZONE_SIZE);
unsafe {
writer.write(signal_frame);
writer.write(entry.sigreturn());
}

logln_disabled!("sys_frame set rip: {:#x}", f as usize);
sys_frame.rip = f as u64;

// Signal param
regs.rdi = sig as u64;

logln2!("do signal!!! {} FROM SYSCALL", sig);
}
return false;
}
DoSignalsResult::Default | DoSignalsResult::Ignore => {
if syscall_result.is_restart(false, false) {
sys_frame.rip -= SYSCALL_INSTRUCTION_SIZE;
return true;
} else {
arch_sys_check_signals(syscall_result, sys_frame, regs);
return false;
}

logln_disabled!("sys_frame set rip: {:#x}", f as usize);
sys_frame.rip = f as u64;

// Signal param
regs.rdi = sig as u64;

logln!("do signal!!!");
}
_ => {
// Store syscall result in rax
regs.rax = syscall_result.syscall_into() as u64;
return false;
}
}
}

pub fn arch_sys_sigreturn(sys_frame: &mut SyscallFrame, user_regs: &mut RegsFrame) -> isize {
pub fn arch_sys_sigreturn(
sys_frame: &mut SyscallFrame,
user_regs: &mut RegsFrame,
) -> (SyscallResult, bool) {
let mut writer = StackHelper::new(&mut sys_frame.rsp);

let signal_frame = unsafe { writer.restore::<SignalFrame>() };

current_task_ref().signals().set_mask(
syscall_defs::signal::SigProcMask::Set,
signal_frame.sigmask,
Some(signal_frame.sigmask),
None,
);

Expand All @@ -152,9 +184,12 @@ pub fn arch_sys_sigreturn(sys_frame: &mut SyscallFrame, user_regs: &mut RegsFram
sys_frame.rflags = signal_frame.rflags;
sys_frame.rip = signal_frame.rip;

if signal_frame.restart_syscall != u64::MAX {
let was_restart = if signal_frame.restart_syscall != u64::MAX {
sys_frame.rip -= SYSCALL_INSTRUCTION_SIZE as u64;
}
true
} else {
false
};

return result;
return (SyscallResult::syscall_from(result), was_restart);
}
15 changes: 10 additions & 5 deletions cykusz-rs/src/arch/x86_64/syscall.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use syscall_defs::{SyscallError, SyscallResult};
use syscall_defs::{SyscallError, SyscallInto, SyscallResult};

use crate::arch::idt::RegsFrame;
use crate::arch::signal::arch_sys_check_signals;
use crate::kernel::mm::VirtAddr;
use crate::kernel::sched::current_task_ref;
use crate::kernel::sync::IrqGuard;
Expand Down Expand Up @@ -40,9 +41,16 @@ pub struct SyscallFrame {
pub extern "C" fn fast_syscall_handler(sys_frame: &mut SyscallFrame, regs: &mut RegsFrame) {
if regs.rax == syscall_defs::SYS_SIGRETURN as u64 {
// Store syscall result in rax
regs.rax = crate::arch::signal::arch_sys_sigreturn(sys_frame, regs) as u64
let (res, was_restart) = crate::arch::signal::arch_sys_sigreturn(sys_frame, regs);

if !was_restart {
arch_sys_check_signals(res, sys_frame, regs);
} else {
regs.rax = res.syscall_into() as u64;
}
} else {
//logln!("syscall {:?} {:?}", regs, sys_frame);
logln!("syscall {}, ret: 0x{:x}", regs.rax, sys_frame.rip);

let res = crate::kernel::syscall::syscall_handler(
regs.rax, regs.rdi, regs.rsi, regs.rdx, regs.r10, regs.r8, regs.r9,
Expand All @@ -51,9 +59,6 @@ pub extern "C" fn fast_syscall_handler(sys_frame: &mut SyscallFrame, regs: &mut
logln_disabled!("done syscall {} = {}", regs.rax, res);

crate::arch::signal::arch_sys_check_signals(res, sys_frame, regs);

// Store syscall result in rax
regs.rax = res as u64
}
}

Expand Down
2 changes: 1 addition & 1 deletion cykusz-rs/src/arch/x86_64/task/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ impl Context {
}

fn task_finished() {
crate::kernel::sched::exit(0);
crate::kernel::sched::exit(syscall_defs::waitpid::Status::Exited(0));
}

fn prepare_p4<'a>() -> &'a mut P4Table {
Expand Down
Loading

0 comments on commit fc9c6e4

Please sign in to comment.