[kernel][rust] Expand the ProcessDispatcher impl This adds additional functions to the ProcessDispatcher impl that are required to implement functionality in userboot. Bug: 507423574 Bug: 521547950 Change-Id: I302967f78f1b22f45fbea9cfedaefb9f855e1a6e Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/1739009 Reviewed-by: Adrian Danis <adanis@google.com> Commit-Queue: Abdulla Kamar <abdulla@google.com> Fuchsia-Auto-Submit: Abdulla Kamar <abdulla@google.com>
diff --git a/zircon/kernel/object/include/object/process_dispatcher.h b/zircon/kernel/object/include/object/process_dispatcher.h index 7317cc4..0b48aea 100644 --- a/zircon/kernel/object/include/object/process_dispatcher.h +++ b/zircon/kernel/object/include/object/process_dispatcher.h
@@ -429,6 +429,10 @@ extern "C" { ProcessDispatcher* cpp_process_dispatcher_current(); bool cpp_process_dispatcher_is_current(const ProcessDispatcher* process); +zx_status_t cpp_process_dispatcher_start(ProcessDispatcher* process, ThreadDispatcher* thread, + zx_vaddr_t pc, zx_vaddr_t sp, Handle* arg_handle, + uintptr_t arg2); +void cpp_process_dispatcher_kill(ProcessDispatcher* process, int64_t retcode); zx_status_t cpp_process_dispatcher_suspend(ProcessDispatcher* process); void cpp_process_dispatcher_resume(ProcessDispatcher* process); zx_status_t cpp_process_dispatcher_make_and_add_handle(ProcessDispatcher* process, @@ -443,6 +447,7 @@ zx_status_t cpp_process_dispatcher_enforce_basic_policy(const ProcessDispatcher* process, uint32_t policy); int64_t cpp_process_dispatcher_get_timer_slack_policy_amount(const ProcessDispatcher* process); +zx_info_process_t cpp_process_dispatcher_get_info(const ProcessDispatcher* process); } #endif // ZIRCON_KERNEL_OBJECT_INCLUDE_OBJECT_PROCESS_DISPATCHER_H_
diff --git a/zircon/kernel/object/process_dispatcher.rs b/zircon/kernel/object/process_dispatcher.rs index dc51198..89281aa 100644 --- a/zircon/kernel/object/process_dispatcher.rs +++ b/zircon/kernel/object/process_dispatcher.rs
@@ -5,14 +5,16 @@ // https://opensource.org/licenses/MIT use super::dispatcher::DispatcherOps; -use super::handle::{HandleValue, KernelHandle}; +use super::handle::{HandleOwner, HandleValue, KernelHandle}; use super::process_dispatcher_ffi::{ cpp_process_dispatcher_current, cpp_process_dispatcher_enforce_basic_policy, - cpp_process_dispatcher_is_current, cpp_process_dispatcher_make_and_add_handle, - cpp_process_dispatcher_resume, cpp_process_dispatcher_suspend, + cpp_process_dispatcher_get_info, cpp_process_dispatcher_is_current, + cpp_process_dispatcher_kill, cpp_process_dispatcher_make_and_add_handle, + cpp_process_dispatcher_resume, cpp_process_dispatcher_start, cpp_process_dispatcher_suspend, }; +use super::thread_dispatcher::ThreadDispatcher; use zx_status::Status; -use zx_types::zx_rights_t; +use zx_types::{zx_info_process_t, zx_rights_t, zx_vaddr_t}; crate::object::dispatcher::impl_dispatcher_facade!( pub struct ProcessDispatcher, @@ -33,6 +35,35 @@ unsafe { cpp_process_dispatcher_is_current(self as *const _) } } + /// Starts execution of this process. + pub fn start( + &self, + thread: &ThreadDispatcher, + pc: zx_vaddr_t, + sp: zx_vaddr_t, + arg_handle: HandleOwner, + arg2: usize, + ) -> Result<(), Status> { + // SAFETY: `self` and `thread` are valid references, and `arg_handle` ownership is transferred to C++. + let status = unsafe { + cpp_process_dispatcher_start( + self as *const _, + thread as *const _, + pc, + sp, + arg_handle.release(), + arg2, + ) + }; + Status::ok(status) + } + + /// Kills this process with the given return code. + pub fn kill(&self, retcode: i64) { + // SAFETY: `self` is a valid `ProcessDispatcher` reference. + unsafe { cpp_process_dispatcher_kill(self as *const _, retcode) } + } + /// Suspends execution of this process. /// /// # Errors @@ -119,4 +150,10 @@ ) } } + + /// Returns information about this process. + pub fn get_info(&self) -> zx_info_process_t { + // SAFETY: `self` is a valid `ProcessDispatcher` reference. + unsafe { cpp_process_dispatcher_get_info(self as *const _) } + } }
diff --git a/zircon/kernel/object/process_dispatcher_ffi.cc b/zircon/kernel/object/process_dispatcher_ffi.cc index ce96070..bd8c760 100644 --- a/zircon/kernel/object/process_dispatcher_ffi.cc +++ b/zircon/kernel/object/process_dispatcher_ffi.cc
@@ -6,6 +6,7 @@ #include <object/handle.h> #include <object/process_dispatcher.h> +#include <object/thread_dispatcher.h> extern "C" { @@ -15,6 +16,17 @@ return process == ProcessDispatcher::GetCurrent(); } +zx_status_t cpp_process_dispatcher_start(ProcessDispatcher* process, ThreadDispatcher* thread, + zx_vaddr_t pc, zx_vaddr_t sp, Handle* arg_handle, + uintptr_t arg2) { + return process->Start(fbl::RefPtr<ThreadDispatcher>(thread), pc, sp, HandleOwner(arg_handle), + arg2); +} + +void cpp_process_dispatcher_kill(ProcessDispatcher* process, int64_t retcode) { + process->Kill(retcode); +} + zx_status_t cpp_process_dispatcher_suspend(ProcessDispatcher* process) { return process->Suspend(); } @@ -50,4 +62,8 @@ return process->GetTimerSlackPolicy().amount(); } +zx_info_process_t cpp_process_dispatcher_get_info(const ProcessDispatcher* process) { + return process->GetInfo(); +} + } // extern "C"
diff --git a/zircon/kernel/object/process_dispatcher_ffi.rs b/zircon/kernel/object/process_dispatcher_ffi.rs index e81b26b..69c3de4 100644 --- a/zircon/kernel/object/process_dispatcher_ffi.rs +++ b/zircon/kernel/object/process_dispatcher_ffi.rs
@@ -7,7 +7,8 @@ use super::dispatcher::Dispatcher; use super::handle::{HandleValue, KernelHandle}; use super::process_dispatcher::ProcessDispatcher; -use zx_types::{zx_rights_t, zx_status_t}; +use super::thread_dispatcher::ThreadDispatcher; +use zx_types::{zx_info_process_t, zx_rights_t, zx_status_t, zx_vaddr_t}; unsafe extern "C" { /// Returns a raw pointer to the current process dispatcher. @@ -24,6 +25,29 @@ /// `process` must point to a valid `ProcessDispatcher`. pub(crate) fn cpp_process_dispatcher_is_current(process: *const ProcessDispatcher) -> bool; + /// Calls into C++ implementation to start a process. + /// + /// # Safety + /// + /// `process` must point to a valid `ProcessDispatcher`. + /// `thread` must point to a valid `ThreadDispatcher`. + /// `arg_handle` must point to a valid raw handle or be null. + pub(crate) fn cpp_process_dispatcher_start( + process: *const ProcessDispatcher, + thread: *const ThreadDispatcher, + pc: zx_vaddr_t, + sp: zx_vaddr_t, + arg_handle: *mut core::ffi::c_void, + arg2: usize, + ) -> zx_status_t; + + /// Calls into C++ implementation to kill a process. + /// + /// # Safety + /// + /// `process` must point to a valid `ProcessDispatcher`. + pub(crate) fn cpp_process_dispatcher_kill(process: *const ProcessDispatcher, retcode: i64); + /// Calls into C++ implementation to suspend a process. /// /// # Safety @@ -99,4 +123,13 @@ pub(crate) fn cpp_process_dispatcher_get_timer_slack_policy_amount( process: *const ProcessDispatcher, ) -> i64; + + /// Retrieves process info from C++. + /// + /// # Safety + /// + /// `process` must point to a valid `ProcessDispatcher`. + pub(crate) fn cpp_process_dispatcher_get_info( + process: *const ProcessDispatcher, + ) -> zx_info_process_t; }