@@ -22,7 +22,6 @@ use hyperlight_common::flatbuffer_wrappers::function_call::{FunctionCall, Functi
2222use hyperlight_common:: flatbuffer_wrappers:: function_types:: { FunctionCallResult , ParameterType } ;
2323use hyperlight_common:: flatbuffer_wrappers:: guest_error:: { ErrorCode , GuestError } ;
2424use hyperlight_guest:: error:: { HyperlightGuestError , Result } ;
25- use hyperlight_guest:: exit:: halt;
2625use tracing:: { Span , instrument} ;
2726
2827use crate :: { GUEST_HANDLE , REGISTERED_GUEST_FUNCTIONS } ;
@@ -79,14 +78,17 @@ pub(crate) fn call_guest_function(function_call: FunctionCall) -> Result<Vec<u8>
7978 }
8079}
8180
82- // This function is marked as no_mangle/inline to prevent the compiler from inlining it , if its inlined the epilogue will not be called
83- // and we will leak memory as the epilogue will not be called as halt() is not going to return.
84- //
85- // This function may panic, as we have no other ways of dealing with errors at this level
86- #[ unsafe( no_mangle) ]
87- #[ inline( never) ]
88- #[ instrument( skip_all, parent = Span :: current( ) , level= "Trace" ) ]
89- fn internal_dispatch_function ( ) {
81+ pub ( crate ) fn internal_dispatch_function ( ) {
82+ // Read the current TSC to report it to the host with the spans/events
83+ // This helps calculating the timestamps relative to the guest call
84+ #[ cfg( feature = "trace_guest" ) ]
85+ {
86+ let guest_start_tsc = hyperlight_guest_tracing:: invariant_tsc:: read_tsc ( ) ;
87+ // Reset the trace state for the new guest function call with the new start TSC
88+ // This clears any existing spans/events from previous calls ensuring a clean state
89+ hyperlight_guest_tracing:: new_call ( guest_start_tsc) ;
90+ }
91+
9092 let handle = unsafe { GUEST_HANDLE } ;
9193
9294 #[ cfg( debug_assertions) ]
@@ -114,35 +116,9 @@ fn internal_dispatch_function() {
114116 . expect ( "Failed to serialize function call result" ) ;
115117 }
116118 }
117- }
118-
119- // This is implemented as a separate function to make sure that epilogue in the internal_dispatch_function is called before the halt()
120- // which if it were included in the internal_dispatch_function cause the epilogue to not be called because the halt() would not return
121- // when running in the hypervisor.
122- #[ instrument( skip_all, parent = Span :: current( ) , level= "Trace" ) ]
123- pub ( crate ) extern "C" fn dispatch_function ( ) {
124- // The hyperlight host likes to use one partition and reset it in
125- // various ways; if that has happened, there might stale TLB
126- // entries hanging around from the former user of the
127- // partition. Flushing the TLB here is not quite the right thing
128- // to do, since incorrectly cached entries could make even this
129- // code not exist, but regrettably there is not a simple way for
130- // the host to trigger flushing when it ought to happen, so for
131- // now this works in practice, since the text segment is always
132- // part of the big identity-mapped region at the base of the
133- // guest.
134- crate :: paging:: flush_tlb ( ) ;
135-
136- // Read the current TSC to report it to the host with the spans/events
137- // This helps calculating the timestamps relative to the guest call
138- #[ cfg( feature = "trace_guest" ) ]
139- {
140- let guest_start_tsc = hyperlight_guest_tracing:: invariant_tsc:: read_tsc ( ) ;
141- // Reset the trace state for the new guest function call with the new start TSC
142- // This clears any existing spans/events from previous calls ensuring a clean state
143- hyperlight_guest_tracing:: new_call ( guest_start_tsc) ;
144- }
145119
146- internal_dispatch_function ( ) ;
147- halt ( ) ;
120+ // Ensure that any tracing output during the call is flushed to
121+ // the host, if necessary.
122+ #[ cfg( all( feature = "trace_guest" , target_arch = "x86_64" ) ) ]
123+ hyperlight_guest_tracing:: flush ( ) ;
148124}
0 commit comments