Skip to content

Commit 5cb4ee1

Browse files
authored
Clean up ContinueOperation (#502)
Some clean up in preparation for more task/signal work: * Define one `ContinueOperation` for all shims, with just `ContinueGuest` and `ExitThread`. * Remove exit status from `ExitThread`--this, plus the distinction between thread and process exit, will be communicated separately in future PRs, on a per-shim basis. * Unify Linux shim entry/exit code. * Record the `is_exiting` state of a Linux thread in `Task` and use it to determine whether to return `ExitThread` from a shim entrypoint. This is a more natural fit for Linux signal/termination handling.
1 parent 94e1024 commit 5cb4ee1

File tree

11 files changed

+134
-218
lines changed

11 files changed

+134
-218
lines changed

litebox/src/shim.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,6 @@ pub trait EnterShim: Send + Sync {
1919
///
2020
/// FUTURE: use a single per-architecture type for all shims and platforms.
2121
type ExecutionContext;
22-
/// The operation the platform should take after returning from the shim.
23-
///
24-
/// FUTURE: use a single per-LiteBox type for all shims and platforms.
25-
type ContinueOperation;
2622

2723
/// Initialize a new thread. Must be called by the platform exactly once
2824
/// before running the thread in the guest for the first time.
@@ -41,13 +37,13 @@ pub trait EnterShim: Send + Sync {
4137
/// crate::platform::ThreadProvider::spawn_thread
4238
/// [`ThreadProvider::current_thread`]:
4339
/// crate::platform::ThreadProvider::current_thread
44-
fn init(&self, ctx: &mut Self::ExecutionContext) -> Self::ContinueOperation;
40+
fn init(&self, ctx: &mut Self::ExecutionContext) -> ContinueOperation;
4541

4642
/// Handle a syscall.
4743
///
4844
/// The platform should call this in response to `syscall` on x86_64 and
4945
/// `int 0x80` on x86.
50-
fn syscall(&self, ctx: &mut Self::ExecutionContext) -> Self::ContinueOperation;
46+
fn syscall(&self, ctx: &mut Self::ExecutionContext) -> ContinueOperation;
5147

5248
/// Handle a hardware exception.
5349
///
@@ -56,15 +52,24 @@ pub trait EnterShim: Send + Sync {
5652
&self,
5753
ctx: &mut Self::ExecutionContext,
5854
info: &ExceptionInfo,
59-
) -> Self::ContinueOperation;
55+
) -> ContinueOperation;
6056

6157
/// Handle an interrupt signaled by
6258
/// [`ThreadProvider::interrupt_thread`](crate::platform::ThreadProvider::interrupt_thread).
6359
///
6460
/// Note that if another event occurs (e.g., a syscall or exception) while
6561
/// the thread is interrupted, the platform may just call the corresponding
6662
/// handler instead of this one.
67-
fn interrupt(&self, ctx: &mut Self::ExecutionContext) -> Self::ContinueOperation;
63+
fn interrupt(&self, ctx: &mut Self::ExecutionContext) -> ContinueOperation;
64+
}
65+
66+
/// The operation to perform after returning from a shim handler
67+
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
68+
pub enum ContinueOperation {
69+
/// Resume execution of the guest.
70+
ResumeGuest,
71+
/// Exit the current thread.
72+
ExitThread,
6873
}
6974

7075
/// Information about a hardware exception.

litebox_common_linux/src/lib.rs

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1915,9 +1915,7 @@ pub enum SyscallRequest<Platform: litebox::platform::RawPointerProvider> {
19151915
oldact: Option<Platform::RawMutPointer<SigAction>>,
19161916
sigsetsize: usize,
19171917
},
1918-
RtSigreturn {
1919-
stack: usize,
1920-
},
1918+
RtSigreturn,
19211919
Ioctl {
19221920
fd: i32,
19231921
arg: IoctlArg<Platform>,
@@ -2246,13 +2244,6 @@ pub enum SyscallRequest<Platform: litebox::platform::RawPointerProvider> {
22462244
},
22472245
}
22482246

2249-
pub enum ContinueOperation {
2250-
ResumeGuest,
2251-
ExitThread(i32),
2252-
ExitProcess(i32),
2253-
RtSigreturn(usize), // TEMP: remove once this is handled natively by the shim
2254-
}
2255-
22562247
impl<Platform: litebox::platform::RawPointerProvider> SyscallRequest<Platform> {
22572248
/// Take the raw syscall number and arguments, and provide a stronger-typed `SyscallRequest`.
22582249
///
@@ -2388,10 +2379,7 @@ impl<Platform: litebox::platform::RawPointerProvider> SyscallRequest<Platform> {
23882379
return Err(errno::Errno::EINVAL);
23892380
}
23902381
}
2391-
#[cfg(target_arch = "x86_64")]
2392-
Sysno::rt_sigreturn => SyscallRequest::RtSigreturn { stack: ctx.rsp },
2393-
#[cfg(target_arch = "x86")]
2394-
Sysno::rt_sigreturn => SyscallRequest::RtSigreturn { stack: ctx.esp },
2382+
Sysno::rt_sigreturn => SyscallRequest::RtSigreturn,
23952383
Sysno::ioctl => SyscallRequest::Ioctl {
23962384
fd: ctx.sys_req_arg(0),
23972385
arg: {

litebox_common_optee/src/lib.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -124,12 +124,6 @@ pub enum SyscallRequest<Platform: litebox::platform::RawPointerProvider> {
124124
},
125125
}
126126

127-
pub enum ContinueOperation {
128-
ResumeGuest,
129-
ExitThread(usize),
130-
ExitProcess(usize),
131-
}
132-
133127
// `litebox_common_optee` does use error codes for OP-TEE-like world (TAs) and Linux-like world (the LVBS platform).
134128
// for the below syscall handling, we use Linux error codes (i.e., `Errno`) because any errors will be returned
135129
// to the LVBS platform or runner.

litebox_platform_linux_userland/src/lib.rs

Lines changed: 5 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -13,30 +13,17 @@ use litebox::fs::OFlags;
1313
use litebox::platform::UnblockedOrTimedOut;
1414
use litebox::platform::page_mgmt::{FixedAddressBehavior, MemoryRegionPermissions};
1515
use litebox::platform::{ImmediatelyWokenUp, RawConstPointer};
16+
use litebox::shim::ContinueOperation;
1617
use litebox::utils::{ReinterpretSignedExt, ReinterpretUnsignedExt as _, TruncateExt};
1718
use litebox_common_linux::{MRemapFlags, MapFlags, ProtFlags, PunchthroughSyscall};
1819

1920
mod syscall_intercept;
2021

2122
extern crate alloc;
2223

23-
cfg_if::cfg_if! {
24-
if #[cfg(feature = "linux_syscall")] {
25-
use litebox_common_linux::ContinueOperation;
26-
pub type SyscallReturnType = litebox_common_linux::ContinueOperation;
27-
} else if #[cfg(feature = "optee_syscall")] {
28-
use litebox_common_optee::ContinueOperation;
29-
pub type SyscallReturnType = litebox_common_optee::ContinueOperation;
30-
} else {
31-
compile_error!(r##"No syscall handler specified."##);
32-
}
33-
}
3424
/// The syscall handler passed down from the shim.
3525
static SHIM: std::sync::OnceLock<
36-
&'static dyn litebox::shim::EnterShim<
37-
ExecutionContext = litebox_common_linux::PtRegs,
38-
ContinueOperation = ContinueOperation,
39-
>,
26+
&'static dyn litebox::shim::EnterShim<ExecutionContext = litebox_common_linux::PtRegs>,
4027
> = const { std::sync::OnceLock::new() };
4128

4229
/// The userland Linux platform.
@@ -185,10 +172,7 @@ impl LinuxUserland {
185172
/// Panics if the function has already been invoked earlier.
186173
pub fn register_shim(
187174
&self,
188-
shim: &'static dyn litebox::shim::EnterShim<
189-
ExecutionContext = litebox_common_linux::PtRegs,
190-
ContinueOperation = ContinueOperation,
191-
>,
175+
shim: &'static dyn litebox::shim::EnterShim<ExecutionContext = litebox_common_linux::PtRegs>,
192176
) {
193177
SHIM.set(shim)
194178
.ok()
@@ -1674,10 +1658,7 @@ extern "C-unwind" fn interrupt_handler(ctx: &mut litebox_common_linux::PtRegs) {
16741658
fn call_shim(
16751659
ctx: &mut litebox_common_linux::PtRegs,
16761660
f: impl FnOnce(
1677-
&dyn litebox::shim::EnterShim<
1678-
ContinueOperation = ContinueOperation,
1679-
ExecutionContext = litebox_common_linux::PtRegs,
1680-
>,
1661+
&dyn litebox::shim::EnterShim<ExecutionContext = litebox_common_linux::PtRegs>,
16811662
&mut litebox_common_linux::PtRegs,
16821663
) -> ContinueOperation,
16831664
) {
@@ -1703,24 +1684,7 @@ fn call_shim(
17031684
let op = f(shim, ctx);
17041685
match op {
17051686
ContinueOperation::ResumeGuest => unsafe { switch_to_guest(ctx) },
1706-
ContinueOperation::ExitThread(status) | ContinueOperation::ExitProcess(status) => {
1707-
#[cfg(target_arch = "x86_64")]
1708-
{
1709-
cfg_if::cfg_if! {
1710-
if #[cfg(feature = "linux_syscall")] {
1711-
ctx.rax = status.reinterpret_as_unsigned() as usize;
1712-
} else if #[cfg(feature = "optee_syscall")] {
1713-
ctx.rax = status;
1714-
}
1715-
}
1716-
}
1717-
#[cfg(target_arch = "x86")]
1718-
{
1719-
ctx.eax = status.reinterpret_as_unsigned() as usize;
1720-
}
1721-
}
1722-
#[cfg(feature = "linux_syscall")]
1723-
ContinueOperation::RtSigreturn(..) => unreachable!(),
1687+
ContinueOperation::ExitThread => {}
17241688
}
17251689
}
17261690

litebox_platform_lvbs/src/lib.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -381,10 +381,7 @@ impl<Host: HostInterface> LinuxKernel<Host> {
381381
/// Register the shim. This function must be called for each core to program
382382
/// its MSRs.
383383
pub fn register_shim(
384-
shim: &'static dyn litebox::shim::EnterShim<
385-
ExecutionContext = litebox_common_linux::PtRegs,
386-
ContinueOperation = syscall_entry::SyscallReturnType,
387-
>,
384+
shim: &'static dyn litebox::shim::EnterShim<ExecutionContext = litebox_common_linux::PtRegs>,
388385
) {
389386
syscall_entry::init(shim);
390387
}

litebox_platform_lvbs/src/syscall_entry.rs

Lines changed: 5 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use crate::{
55
user_context::UserSpaceManagement,
66
};
77
use core::arch::{asm, naked_asm};
8+
use litebox::shim::ContinueOperation;
89
use litebox_common_linux::PtRegs;
910
use litebox_common_optee::SyscallContext;
1011
use x86_64::{
@@ -38,24 +39,8 @@ use x86_64::{
3839
// r11: userspace rflags
3940
// Note. rsp should point to the userspace stack before calling `sysretq`
4041

41-
cfg_if::cfg_if! {
42-
if #[cfg(feature = "linux_syscall")] {
43-
use litebox_common_linux::ContinueOperation;
44-
pub type SyscallReturnType = ContinueOperation;
45-
} else if #[cfg(feature = "optee_syscall")] {
46-
use litebox_common_optee::ContinueOperation;
47-
pub type SyscallReturnType = ContinueOperation;
48-
} else {
49-
compile_error!(r##"No syscall handler specified."##);
50-
}
51-
}
52-
53-
static SHIM: spin::Once<
54-
&'static dyn litebox::shim::EnterShim<
55-
ExecutionContext = PtRegs,
56-
ContinueOperation = ContinueOperation,
57-
>,
58-
> = spin::Once::new();
42+
static SHIM: spin::Once<&'static dyn litebox::shim::EnterShim<ExecutionContext = PtRegs>> =
43+
spin::Once::new();
5944

6045
#[cfg(target_arch = "x86_64")]
6146
#[derive(Clone, Copy, Debug)]
@@ -171,20 +156,7 @@ fn syscall_entry(sysnr: u64, ctx_raw: *const SyscallContextRaw) -> usize {
171156

172157
// call the syscall handler passed down from the shim
173158
let sysret = match shim.syscall(&mut ctx) {
174-
ContinueOperation::ResumeGuest => ctx.rax,
175-
ContinueOperation::ExitThread(status) | ContinueOperation::ExitProcess(status) => {
176-
cfg_if::cfg_if! {
177-
if #[cfg(feature = "linux_syscall")] {
178-
status.cast_unsigned() as usize
179-
} else if #[cfg(feature = "optee_syscall")] {
180-
status
181-
} else {
182-
compile_error!(r##"No syscall handler specified."##);
183-
}
184-
}
185-
}
186-
#[cfg(feature = "linux_syscall")]
187-
ContinueOperation::RtSigreturn(..) => unreachable!(),
159+
ContinueOperation::ResumeGuest | ContinueOperation::ExitThread => ctx.rax,
188160
};
189161

190162
// TODO: We should decide whether we place this function here, OP-TEE shim, or separate it into
@@ -257,12 +229,7 @@ const STACK_ALIGNMENT: isize = -16;
257229
/// # Panics
258230
/// Panics if GDT is not initialized for the current core.
259231
#[cfg(target_arch = "x86_64")]
260-
pub(crate) fn init(
261-
shim: &'static dyn litebox::shim::EnterShim<
262-
ExecutionContext = PtRegs,
263-
ContinueOperation = ContinueOperation,
264-
>,
265-
) {
232+
pub(crate) fn init(shim: &'static dyn litebox::shim::EnterShim<ExecutionContext = PtRegs>) {
266233
SHIM.call_once(|| shim);
267234

268235
// enable 64-bit syscall/sysret

litebox_platform_windows_userland/src/lib.rs

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ use litebox::platform::page_mgmt::{
1818
AllocationError, FixedAddressBehavior, MemoryRegionPermissions,
1919
};
2020
use litebox::platform::{ImmediatelyWokenUp, RawMutPointer};
21-
use litebox::shim::Exception;
22-
use litebox::utils::{ReinterpretUnsignedExt as _, TruncateExt as _};
23-
use litebox_common_linux::{ContinueOperation, PunchthroughSyscall};
21+
use litebox::shim::{ContinueOperation, Exception};
22+
use litebox::utils::TruncateExt as _;
23+
use litebox_common_linux::PunchthroughSyscall;
2424

2525
use windows_sys::Win32::Foundation::{self as Win32_Foundation, FILETIME};
2626
use windows_sys::Win32::{
@@ -46,10 +46,7 @@ thread_local! {
4646

4747
/// The registered shim.
4848
static SHIM: std::sync::OnceLock<
49-
&'static dyn litebox::shim::EnterShim<
50-
ExecutionContext = litebox_common_linux::PtRegs,
51-
ContinueOperation = ContinueOperation,
52-
>,
49+
&'static dyn litebox::shim::EnterShim<ExecutionContext = litebox_common_linux::PtRegs>,
5350
> = std::sync::OnceLock::new();
5451

5552
/// The userland Windows platform.
@@ -256,10 +253,7 @@ impl WindowsUserland {
256253
/// Panics if the function has already been invoked earlier.
257254
pub fn register_shim(
258255
&self,
259-
shim: &'static dyn litebox::shim::EnterShim<
260-
ExecutionContext = litebox_common_linux::PtRegs,
261-
ContinueOperation = ContinueOperation,
262-
>,
256+
shim: &'static dyn litebox::shim::EnterShim<ExecutionContext = litebox_common_linux::PtRegs>,
263257
) {
264258
SHIM.set(shim)
265259
.ok()
@@ -1744,10 +1738,7 @@ unsafe extern "C-unwind" fn interrupt_handler(ctx: &mut litebox_common_linux::Pt
17441738
fn call_shim(
17451739
ctx: &mut litebox_common_linux::PtRegs,
17461740
f: impl FnOnce(
1747-
&dyn litebox::shim::EnterShim<
1748-
ContinueOperation = ContinueOperation,
1749-
ExecutionContext = litebox_common_linux::PtRegs,
1750-
>,
1741+
&dyn litebox::shim::EnterShim<ExecutionContext = litebox_common_linux::PtRegs>,
17511742
&mut litebox_common_linux::PtRegs,
17521743
bool,
17531744
) -> ContinueOperation,
@@ -1760,10 +1751,7 @@ fn call_shim(
17601751
let op = f(shim, ctx, interrupt);
17611752
match op {
17621753
ContinueOperation::ResumeGuest => unsafe { switch_to_guest(ctx) },
1763-
ContinueOperation::ExitThread(status) | ContinueOperation::ExitProcess(status) => {
1764-
ctx.rax = status.reinterpret_as_unsigned() as usize;
1765-
}
1766-
ContinueOperation::RtSigreturn(..) => unreachable!(),
1754+
ContinueOperation::ExitThread => {}
17671755
}
17681756
}
17691757

litebox_runner_snp/src/main.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,8 @@ mod globals;
88
extern crate alloc;
99

1010
use alloc::borrow::ToOwned;
11-
use litebox::shim::EnterShim as _;
11+
use litebox::shim::{ContinueOperation, EnterShim as _};
1212
use litebox::utils::{ReinterpretUnsignedExt as _, TruncateExt as _};
13-
use litebox_common_linux::ContinueOperation;
1413
use litebox_platform_linux_kernel::{HostInterface, host::snp::ghcb::ghcb_prints};
1514

1615
#[unsafe(no_mangle)]
@@ -171,11 +170,7 @@ pub extern "C" fn sandbox_task_exit() {
171170
#[unsafe(no_mangle)]
172171
pub extern "C" fn do_syscall_64(pt_regs: &mut litebox_common_linux::PtRegs) {
173172
match litebox_shim_linux::LinuxShimEntrypoints.syscall(pt_regs) {
174-
ContinueOperation::ResumeGuest => {}
175-
ContinueOperation::ExitThread(status) | ContinueOperation::ExitProcess(status) => {
176-
pt_regs.rax = status.cast_unsigned() as usize;
177-
}
178-
ContinueOperation::RtSigreturn(..) => unreachable!(),
173+
ContinueOperation::ResumeGuest | ContinueOperation::ExitThread => {}
179174
}
180175
}
181176

0 commit comments

Comments
 (0)