[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;
 }