File tree Expand file tree Collapse file tree 4 files changed +66
-2
lines changed
tests/rust_guests/callbackguest/src Expand file tree Collapse file tree 4 files changed +66
-2
lines changed Original file line number Diff line number Diff line change @@ -631,7 +631,7 @@ impl Hypervisor for HypervLinuxDriver {
631631 let cancel_requested = self
632632 . interrupt_handle
633633 . cancel_requested
634- . swap ( false , Ordering :: Relaxed ) ;
634+ . load ( Ordering :: Relaxed ) ;
635635 // Note: if a `InterruptHandle::kill()` called while this thread is **here**
636636 // Then `cancel_requested` will be set to true again, which will cancel the **next vcpu run**.
637637 // Additionally signals will be sent to this thread until `running` is set to false.
@@ -722,6 +722,9 @@ impl Hypervisor for HypervLinuxDriver {
722722 // If cancellation was not requested for this specific vm, the vcpu was interrupted because of stale signal
723723 // that was meant to be delivered to a previous/other vcpu on this same thread, so let's ignore it
724724 if cancel_requested {
725+ self . interrupt_handle
726+ . cancel_requested
727+ . store ( false , Ordering :: Relaxed ) ;
725728 HyperlightExit :: Cancelled ( )
726729 } else {
727730 HyperlightExit :: Retry ( )
Original file line number Diff line number Diff line change @@ -560,7 +560,7 @@ impl Hypervisor for KVMDriver {
560560 let cancel_requested = self
561561 . interrupt_handle
562562 . cancel_requested
563- . swap ( false , Ordering :: Relaxed ) ;
563+ . load ( Ordering :: Relaxed ) ;
564564 // Note: if a `InterruptHandle::kill()` called while this thread is **here**
565565 // Then `cancel_requested` will be set to true again, which will cancel the **next vcpu run**.
566566 // Additionally signals will be sent to this thread until `running` is set to false.
@@ -625,6 +625,9 @@ impl Hypervisor for KVMDriver {
625625 // If cancellation was not requested for this specific vm, the vcpu was interrupted because of stale signal
626626 // that was meant to be delivered to a previous/other vcpu on this same thread, so let's ignore it
627627 if cancel_requested {
628+ self . interrupt_handle
629+ . cancel_requested
630+ . store ( false , Ordering :: Relaxed ) ;
628631 HyperlightExit :: Cancelled ( )
629632 } else {
630633 HyperlightExit :: Retry ( )
Original file line number Diff line number Diff line change @@ -327,6 +327,43 @@ fn interrupt_custom_signal_no_and_retry_delay() {
327327 thread. join ( ) . expect ( "Thread should finish" ) ;
328328}
329329
330+ #[ test]
331+ fn interrupt_spamming_host_call ( ) {
332+ let mut uninit = UninitializedSandbox :: new (
333+ GuestBinary :: FilePath ( callback_guest_as_string ( ) . unwrap ( ) ) ,
334+ None ,
335+ )
336+ . unwrap ( ) ;
337+
338+ uninit
339+ . register ( "HostFunc1" , || {
340+ // do nothing
341+ } )
342+ . unwrap ( ) ;
343+ let mut sbox1: MultiUseSandbox = uninit. evolve ( Noop :: default ( ) ) . unwrap ( ) ;
344+
345+ let interrupt_handle = sbox1. interrupt_handle ( ) ;
346+
347+ let barrier = Arc :: new ( Barrier :: new ( 2 ) ) ;
348+ let barrier2 = barrier. clone ( ) ;
349+
350+ let thread = thread:: spawn ( move || {
351+ barrier2. wait ( ) ;
352+ thread:: sleep ( Duration :: from_secs ( 1 ) ) ;
353+ interrupt_handle. kill ( ) ;
354+ } ) ;
355+
356+ barrier. wait ( ) ;
357+ // This guest call calls "HostFunc1" in a loop
358+ let res = sbox1
359+ . call_guest_function_by_name :: < i32 > ( "HostCallLoop" , "HostFunc1" . to_string ( ) )
360+ . unwrap_err ( ) ;
361+
362+ assert ! ( matches!( res, HyperlightError :: ExecutionCanceledByHost ( ) ) ) ;
363+
364+ thread. join ( ) . expect ( "Thread should finish" ) ;
365+ }
366+
330367#[ test]
331368fn print_four_args_c_guest ( ) {
332369 let path = c_simple_guest_as_string ( ) . unwrap ( ) ;
Original file line number Diff line number Diff line change @@ -157,6 +157,19 @@ fn call_host_spin(_: &FunctionCall) -> Result<Vec<u8>> {
157157 Ok ( get_flatbuffer_result ( ( ) ) )
158158}
159159
160+ fn host_call_loop ( function_call : & FunctionCall ) -> Result < Vec < u8 > > {
161+ if let ParameterValue :: String ( message) = & function_call. parameters . as_ref ( ) . unwrap ( ) [ 0 ] {
162+ loop {
163+ call_host_function :: < ( ) > ( message, None , ReturnType :: Void ) . unwrap ( ) ;
164+ }
165+ } else {
166+ Err ( HyperlightGuestError :: new (
167+ ErrorCode :: GuestFunctionParameterTypeMismatch ,
168+ "Invalid parameters passed to host_call_loop" . to_string ( ) ,
169+ ) )
170+ }
171+ }
172+
160173#[ no_mangle]
161174pub extern "C" fn hyperlight_main ( ) {
162175 let print_output_def = GuestFunctionDefinition :: new (
@@ -234,6 +247,14 @@ pub extern "C" fn hyperlight_main() {
234247 call_host_spin as usize ,
235248 ) ;
236249 register_function ( call_host_spin_def) ;
250+
251+ let host_call_loop_def = GuestFunctionDefinition :: new (
252+ "HostCallLoop" . to_string ( ) ,
253+ Vec :: from ( & [ ParameterType :: String ] ) ,
254+ ReturnType :: Void ,
255+ host_call_loop as usize ,
256+ ) ;
257+ register_function ( host_call_loop_def) ;
237258}
238259
239260#[ no_mangle]
You can’t perform that action at this time.
0 commit comments