Skip to content

Commit

Permalink
Merge pull request rcore-os#145 from rcore-os/exception
Browse files Browse the repository at this point in the history
Refactor exception
  • Loading branch information
wangrunji0408 authored Aug 13, 2020
2 parents 171338b + 3b5c1c4 commit a8829ad
Show file tree
Hide file tree
Showing 17 changed files with 452 additions and 599 deletions.
100 changes: 25 additions & 75 deletions zircon-loader/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ pub struct Images<T: AsRef<[u8]>> {

pub fn run_userboot(images: &Images<impl AsRef<[u8]>>, cmdline: &str) -> Arc<Process> {
let job = Job::root();
let proc = Process::create(&job, "userboot", 0).unwrap();
let thread = Thread::create(&proc, "userboot", 0).unwrap();
let proc = Process::create(&job, "userboot").unwrap();
let thread = Thread::create(&proc, "userboot").unwrap();
let resource = Resource::create(
"root",
ResourceKind::ROOT,
Expand Down Expand Up @@ -176,37 +176,21 @@ fn spawn(thread: Arc<Thread>) {
let vmtoken = thread.proc().vmar().table_phys();
let future = async move {
kernel_hal::Thread::set_tid(thread.id(), thread.proc().id());
let mut exit = false;
if thread.get_first_thread() {
let proc_start_exception =
Exception::create(thread.clone(), ExceptionType::ProcessStarting, None);
if !proc_start_exception
if thread.is_first_thread() {
Exception::create(&thread, ExceptionType::ProcessStarting, None)
.handle_with_exceptionates(
false,
JobDebuggerIterator::new(thread.proc().job()),
true,
)
.await
{
exit = true;
}
.await;
};
let start_exception =
Exception::create(thread.clone(), ExceptionType::ThreadStarting, None);
if !start_exception
.handle_with_exceptionates(false, Some(thread.proc().get_debug_exceptionate()), false)
.await
{
exit = true;
}
while !exit {
Exception::create(&thread, ExceptionType::ThreadStarting, None)
.handle_with_exceptionates(false, Some(thread.proc().debug_exceptionate()), false)
.await;
loop {
let mut cx = thread.wait_for_run().await;
if thread.state() == ThreadState::Dying {
info!(
"proc={:?} thread={:?} was killed",
thread.proc().name(),
thread.name()
);
break;
}
trace!("go to user: {:#x?}", cx);
Expand All @@ -228,12 +212,12 @@ fn spawn(thread: Arc<Thread>) {
EXCEPTIONS_USER.add(1);
#[cfg(target_arch = "aarch64")]
match cx.trap_num {
0 => exit = handle_syscall(&thread, &mut cx.general).await,
0 => handle_syscall(&thread, &mut cx.general).await,
_ => unimplemented!(),
}
#[cfg(target_arch = "x86_64")]
match cx.trap_num {
0x100 => exit = handle_syscall(&thread, &mut cx.general).await,
0x100 => handle_syscall(&thread, &mut cx.general).await,
0x20..=0x3f => {
kernel_hal::InterruptManager::handle(cx.trap_num as u8);
if cx.trap_num == 0x20 {
Expand All @@ -252,34 +236,14 @@ fn spawn(thread: Arc<Thread>) {
// FIXME:
#[cfg(target_arch = "aarch64")]
let flags = MMUFlags::WRITE;
error!(
"page fualt from user mode {:#x} {:#x?}",
kernel_hal::fetch_fault_vaddr(),
flags
);
match thread
.proc()
.vmar()
.handle_page_fault(kernel_hal::fetch_fault_vaddr(), flags)
{
Ok(()) => {}
Err(e) => {
error!(
"proc={:?} thread={:?} err={:?}",
thread.proc().name(),
thread.name(),
e
);
error!("Page Fault from user mode {:#x?}", cx);
let exception = Exception::create(
thread.clone(),
ExceptionType::FatalPageFault,
Some(&cx),
);
if !exception.handle(true).await {
exit = true;
}
}
let fault_vaddr = kernel_hal::fetch_fault_vaddr();
error!("page fault from user mode {:#x} {:#x?}", fault_vaddr, flags);
let vmar = thread.proc().vmar();
if vmar.handle_page_fault(fault_vaddr, flags).is_err() {
error!("Page Fault from user mode: {:#x?}", cx);
let exception =
Exception::create(&thread, ExceptionType::FatalPageFault, Some(&cx));
exception.handle(true).await;
}
}
0x8 => {
Expand All @@ -293,39 +257,27 @@ fn spawn(thread: Arc<Thread>) {
0x17 => ExceptionType::UnalignedAccess,
_ => ExceptionType::General,
};
error!("User mode exception:{:?} {:#x?}", type_, cx);
let exception = Exception::create(thread.clone(), type_, Some(&cx));
if !exception.handle(true).await {
exit = true;
}
error!("User mode exception: {:?} {:#x?}", type_, cx);
let exception = Exception::create(&thread, type_, Some(&cx));
exception.handle(true).await;
}
}
thread.end_running(cx);
if exit {
info!(
"proc={:?} thread={:?} exited",
thread.proc().name(),
thread.name()
);
break;
}
}
let end_exception = Exception::create(thread.clone(), ExceptionType::ThreadExiting, None);
let end_exception = Exception::create(&thread, ExceptionType::ThreadExiting, None);
let handled = thread
.proc()
.get_debug_exceptionate()
.debug_exceptionate()
.send_exception(&end_exception);
if let Ok(future) = handled {
thread.dying_run(future).await.ok();
} else {
handled.ok();
}
thread.terminate();
};
kernel_hal::Thread::spawn(Box::pin(future), vmtoken);
}

async fn handle_syscall(thread: &Arc<Thread>, regs: &mut GeneralRegs) -> bool {
async fn handle_syscall(thread: &Arc<Thread>, regs: &mut GeneralRegs) {
#[cfg(target_arch = "x86_64")]
let num = regs.rax as u32;
#[cfg(target_arch = "aarch64")]
Expand Down Expand Up @@ -355,7 +307,6 @@ async fn handle_syscall(thread: &Arc<Thread>, regs: &mut GeneralRegs) -> bool {
regs,
thread: thread.clone(),
spawn_fn: spawn,
exit: false,
};
let ret = syscall.syscall(num, args).await as usize;
#[cfg(target_arch = "x86_64")]
Expand All @@ -366,5 +317,4 @@ async fn handle_syscall(thread: &Arc<Thread>, regs: &mut GeneralRegs) -> bool {
{
syscall.regs.x0 = ret;
}
syscall.exit
}
2 changes: 1 addition & 1 deletion zircon-object/src/hypervisor/vcpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ define_count_helper!(Vcpu);

impl Vcpu {
pub fn new(guest: Arc<Guest>, entry: u64, thread: Arc<Thread>) -> ZxResult<Arc<Self>> {
if thread.get_flags().contains(ThreadFlag::VCPU) {
if thread.flags().contains(ThreadFlag::VCPU) {
return Err(ZxError::BAD_STATE);
}
let inner = Mutex::new(VcpuInner::new(entry, guest.rvm_guest())?);
Expand Down
15 changes: 10 additions & 5 deletions zircon-object/src/signal/futex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -387,8 +387,8 @@ mod tests {
#[async_std::test]
async fn owner() {
let root_job = Job::root();
let proc = Process::create(&root_job, "proc", 0).expect("failed to create process");
let thread = Thread::create(&proc, "thread", 0).expect("failed to create thread");
let proc = Process::create(&root_job, "proc").expect("failed to create process");
let thread = Thread::create(&proc, "thread").expect("failed to create thread");

static VALUE: AtomicI32 = AtomicI32::new(1);
let futex = proc.get_futex(&VALUE);
Expand Down Expand Up @@ -423,14 +423,19 @@ mod tests {
#[async_std::test]
async fn time_out() {
let root_job = Job::root();
let proc = Process::create(&root_job, "proc", 0).expect("failed to create process");
let thread = Thread::create(&proc, "thread", 0).expect("failed to create thread");
let proc = Process::create(&root_job, "proc").expect("failed to create process");
let thread = Thread::create(&proc, "thread").expect("failed to create thread");

static VALUE: AtomicI32 = AtomicI32::new(1);
let futex = proc.get_futex(&VALUE);
let future = futex.wait_with_owner(1, Some(thread.clone()), Some(thread.clone()));
let result: ZxResult = thread
.blocking_run(future, ThreadState::BlockedFutex, Duration::from_millis(1))
.blocking_run(
future,
ThreadState::BlockedFutex,
Duration::from_millis(1),
None,
)
.await;
assert_eq!(result.unwrap_err(), ZxError::TIMED_OUT);
assert_eq!(futex.wake(1), 0);
Expand Down
Loading

0 comments on commit a8829ad

Please sign in to comment.