@@ -74,7 +74,7 @@ firehose_client_notify(firehose_client_t fc, mach_port_t reply_port)
74
74
firehose_atomic_max2o (fc , fc_io_sent_flushed_pos ,
75
75
push_reply .fpr_io_flushed_pos , relaxed );
76
76
77
- if (fc -> fc_is_kernel ) {
77
+ if (! fc -> fc_pid ) {
78
78
if (ioctl (server_config .fs_kernel_fd , LOGFLUSHED , & push_reply ) < 0 ) {
79
79
dispatch_assume_zero (errno );
80
80
}
@@ -209,18 +209,25 @@ firehose_client_drain(firehose_client_t fc, mach_port_t port, uint32_t flags)
209
209
ref = (flushed + count ) & FIREHOSE_RING_POS_IDX_MASK ;
210
210
ref = os_atomic_load (& fbh_ring [ref ], relaxed );
211
211
ref &= FIREHOSE_RING_POS_IDX_MASK ;
212
- } while (fc -> fc_is_kernel && !ref );
212
+ } while (! fc -> fc_pid && !ref );
213
213
count ++ ;
214
214
if (!ref ) {
215
215
_dispatch_debug ("Ignoring invalid page reference in ring: %d" , ref );
216
216
continue ;
217
217
}
218
218
219
219
fbc = firehose_buffer_ref_to_chunk (fb , ref );
220
+ if (fbc -> fc_pos .fcp_stream == firehose_stream_metadata ) {
221
+ // serialize with firehose_client_metadata_stream_peek
222
+ os_unfair_lock_lock (& fc -> fc_lock );
223
+ }
220
224
server_config .fs_handler (fc , evt , fbc );
221
225
if (slowpath (snapshot )) {
222
226
snapshot -> handler (fc , evt , fbc );
223
227
}
228
+ if (fbc -> fc_pos .fcp_stream == firehose_stream_metadata ) {
229
+ os_unfair_lock_unlock (& fc -> fc_lock );
230
+ }
224
231
// clients not using notifications (single threaded) always drain fully
225
232
// because they use all their limit, always
226
233
} while (!fc -> fc_use_notifs || count < DRAIN_BATCH_SIZE || snapshot );
@@ -238,7 +245,7 @@ firehose_client_drain(firehose_client_t fc, mach_port_t port, uint32_t flags)
238
245
client_flushed = os_atomic_load2o (& fb -> fb_header ,
239
246
fbh_ring_tail .frp_mem_flushed , relaxed );
240
247
}
241
- if (fc -> fc_is_kernel ) {
248
+ if (! fc -> fc_pid ) {
242
249
// will fire firehose_client_notify() because port is MACH_PORT_DEAD
243
250
port = fc -> fc_sendp ;
244
251
} else if (!port && client_flushed == sent_flushed && fc -> fc_use_notifs ) {
@@ -253,7 +260,7 @@ firehose_client_drain(firehose_client_t fc, mach_port_t port, uint32_t flags)
253
260
if (port ) {
254
261
firehose_client_notify (fc , port );
255
262
}
256
- if (fc -> fc_is_kernel ) {
263
+ if (! fc -> fc_pid ) {
257
264
if (!(flags & FIREHOSE_DRAIN_POLL )) {
258
265
// see firehose_client_kernel_source_handle_event
259
266
dispatch_resume (fc -> fc_kernel_source );
@@ -283,7 +290,7 @@ firehose_client_drain(firehose_client_t fc, mach_port_t port, uint32_t flags)
283
290
// from now on all IO/mem drains depending on `for_io` will be no-op
284
291
// (needs_<for_io>_snapshot: false, memory_corrupted: true). we can safely
285
292
// silence the corresponding source of drain wake-ups.
286
- if (! fc -> fc_is_kernel ) {
293
+ if (fc -> fc_pid ) {
287
294
dispatch_source_cancel (for_io ? fc -> fc_io_source : fc -> fc_mem_source );
288
295
}
289
296
}
@@ -502,7 +509,7 @@ firehose_client_resume(firehose_client_t fc,
502
509
dispatch_assert_queue (server_config .fs_io_drain_queue );
503
510
TAILQ_INSERT_TAIL (& server_config .fs_clients , fc , fc_entry );
504
511
server_config .fs_handler (fc , FIREHOSE_EVENT_CLIENT_CONNECTED , (void * )fcci );
505
- if (fc -> fc_is_kernel ) {
512
+ if (! fc -> fc_pid ) {
506
513
dispatch_activate (fc -> fc_kernel_source );
507
514
} else {
508
515
dispatch_mach_connect (fc -> fc_mach_channel ,
@@ -553,14 +560,15 @@ _firehose_client_create(firehose_buffer_t fb)
553
560
}
554
561
555
562
static firehose_client_t
556
- firehose_client_create (firehose_buffer_t fb ,
563
+ firehose_client_create (firehose_buffer_t fb , pid_t pid ,
557
564
mach_port_t comm_recvp , mach_port_t comm_sendp )
558
565
{
559
566
uint64_t unique_pid = fb -> fb_header .fbh_uniquepid ;
560
567
firehose_client_t fc = _firehose_client_create (fb );
561
568
dispatch_mach_t dm ;
562
569
dispatch_source_t ds ;
563
570
571
+ fc -> fc_pid = pid ;
564
572
ds = dispatch_source_create (DISPATCH_SOURCE_TYPE_DATA_OR , 0 , 0 ,
565
573
server_config .fs_mem_drain_queue );
566
574
_os_object_retain_internal_inline (& fc -> fc_as_os_object );
@@ -622,7 +630,6 @@ firehose_kernel_client_create(void)
622
630
}
623
631
624
632
fc = _firehose_client_create ((firehose_buffer_t )(uintptr_t )fb_map .fbmi_addr );
625
- fc -> fc_is_kernel = true;
626
633
ds = dispatch_source_create (DISPATCH_SOURCE_TYPE_READ , (uintptr_t )fd , 0 ,
627
634
fs -> fs_ipc_queue );
628
635
dispatch_set_context (ds , fc );
@@ -663,12 +670,9 @@ uint64_t
663
670
firehose_client_get_unique_pid (firehose_client_t fc , pid_t * pid_out )
664
671
{
665
672
firehose_buffer_header_t fbh = & fc -> fc_buffer -> fb_header ;
666
- if (fc -> fc_is_kernel ) {
667
- if (pid_out ) * pid_out = 0 ;
668
- return 0 ;
669
- }
670
- if (pid_out ) * pid_out = fbh -> fbh_pid ?: ~(pid_t )0 ;
671
- return fbh -> fbh_uniquepid ?: ~0ull ;
673
+ if (pid_out ) * pid_out = fc -> fc_pid ;
674
+ if (!fc -> fc_pid ) return 0 ;
675
+ return fbh -> fbh_uniquepid ? fbh -> fbh_uniquepid : ~0ull ;
672
676
}
673
677
674
678
void *
@@ -800,47 +804,42 @@ firehose_server_copy_queue(firehose_server_queue_t which)
800
804
801
805
void
802
806
firehose_client_metadata_stream_peek (firehose_client_t fc ,
803
- firehose_event_t context , bool (^peek_should_start )(void ),
807
+ OS_UNUSED firehose_event_t context , bool (^peek_should_start )(void ),
804
808
bool (^peek )(firehose_chunk_t fbc ))
805
809
{
806
- if (context != FIREHOSE_EVENT_MEM_BUFFER_RECEIVED ) {
807
- return dispatch_sync (server_config .fs_mem_drain_queue , ^{
808
- firehose_client_metadata_stream_peek (fc ,
809
- FIREHOSE_EVENT_MEM_BUFFER_RECEIVED , peek_should_start , peek );
810
- });
811
- }
810
+ os_unfair_lock_lock (& fc -> fc_lock );
812
811
813
- if (peek_should_start && !peek_should_start ()) {
814
- return ;
815
- }
816
-
817
- firehose_buffer_t fb = fc -> fc_buffer ;
818
- firehose_buffer_header_t fbh = & fb -> fb_header ;
819
- uint64_t bitmap = fbh -> fbh_bank .fbb_metadata_bitmap ;
812
+ if (peek_should_start && peek_should_start ()) {
813
+ firehose_buffer_t fb = fc -> fc_buffer ;
814
+ firehose_buffer_header_t fbh = & fb -> fb_header ;
815
+ uint64_t bitmap = fbh -> fbh_bank .fbb_metadata_bitmap ;
820
816
821
- while (bitmap ) {
822
- uint16_t ref = firehose_bitmap_first_set (bitmap );
823
- firehose_chunk_t fbc = firehose_buffer_ref_to_chunk (fb , ref );
824
- uint16_t fbc_length = fbc -> fc_pos .fcp_next_entry_offs ;
817
+ while (bitmap ) {
818
+ uint16_t ref = firehose_bitmap_first_set (bitmap );
819
+ firehose_chunk_t fbc = firehose_buffer_ref_to_chunk (fb , ref );
820
+ uint16_t fbc_length = fbc -> fc_pos .fcp_next_entry_offs ;
825
821
826
- bitmap &= ~(1ULL << ref );
827
- if (fbc -> fc_start + fbc_length <= fbc -> fc_data ) {
828
- // this page has its "recycle-requeue" done, but hasn't gone
829
- // through "recycle-reuse", or it has no data, ditch it
830
- continue ;
831
- }
832
- if (!((firehose_tracepoint_t )fbc -> fc_data )-> ft_length ) {
833
- // this thing has data, but the first tracepoint is unreadable
834
- // so also just ditch it
835
- continue ;
836
- }
837
- if (fbc -> fc_pos .fcp_stream != firehose_stream_metadata ) {
838
- continue ;
839
- }
840
- if (!peek (fbc )) {
841
- break ;
822
+ bitmap &= ~(1ULL << ref );
823
+ if (fbc -> fc_start + fbc_length <= fbc -> fc_data ) {
824
+ // this page has its "recycle-requeue" done, but hasn't gone
825
+ // through "recycle-reuse", or it has no data, ditch it
826
+ continue ;
827
+ }
828
+ if (!((firehose_tracepoint_t )fbc -> fc_data )-> ft_length ) {
829
+ // this thing has data, but the first tracepoint is unreadable
830
+ // so also just ditch it
831
+ continue ;
832
+ }
833
+ if (fbc -> fc_pos .fcp_stream != firehose_stream_metadata ) {
834
+ continue ;
835
+ }
836
+ if (!peek (fbc )) {
837
+ break ;
838
+ }
842
839
}
843
840
}
841
+
842
+ os_unfair_lock_unlock (& fc -> fc_lock );
844
843
}
845
844
846
845
OS_NOINLINE OS_COLD
@@ -925,7 +924,7 @@ firehose_snapshot_start(void *ctxt)
925
924
// 1. mark all the clients participating in the current snapshot
926
925
// and enter the group for each bit set
927
926
TAILQ_FOREACH (fci , & server_config .fs_clients , fc_entry ) {
928
- if (fci -> fc_is_kernel ) {
927
+ if (! fci -> fc_pid ) {
929
928
#if TARGET_OS_SIMULATOR
930
929
continue ;
931
930
#endif
@@ -965,7 +964,7 @@ firehose_snapshot_start(void *ctxt)
965
964
// were removed from the list have already left the group
966
965
// (see firehose_client_finalize())
967
966
TAILQ_FOREACH (fcj , & server_config .fs_clients , fc_entry ) {
968
- if (fcj -> fc_is_kernel ) {
967
+ if (! fcj -> fc_pid ) {
969
968
#if !TARGET_OS_SIMULATOR
970
969
firehose_client_kernel_source_handle_event (fcj );
971
970
#endif
@@ -1028,7 +1027,8 @@ kern_return_t
1028
1027
firehose_server_register (mach_port_t server_port OS_UNUSED ,
1029
1028
mach_port_t mem_port , mach_vm_size_t mem_size ,
1030
1029
mach_port_t comm_recvp , mach_port_t comm_sendp ,
1031
- mach_port_t extra_info_port , mach_vm_size_t extra_info_size )
1030
+ mach_port_t extra_info_port , mach_vm_size_t extra_info_size ,
1031
+ audit_token_t atoken )
1032
1032
{
1033
1033
mach_vm_address_t base_addr = 0 ;
1034
1034
firehose_client_t fc = NULL ;
@@ -1077,7 +1077,9 @@ firehose_server_register(mach_port_t server_port OS_UNUSED,
1077
1077
fcci .fcci_size = (size_t )extra_info_size ;
1078
1078
}
1079
1079
1080
- fc = firehose_client_create ((firehose_buffer_t )base_addr ,
1080
+ pid_t pid = (pid_t )atoken .val [5 ]; // same as audit_token_to_pid()
1081
+ if (pid == 0 ) pid = ~0 ;
1082
+ fc = firehose_client_create ((firehose_buffer_t )base_addr , pid ,
1081
1083
comm_recvp , comm_sendp );
1082
1084
dispatch_async (server_config .fs_io_drain_queue , ^{
1083
1085
firehose_client_resume (fc , & fcci );
0 commit comments