@@ -746,26 +746,33 @@ static const struct file_operations kcov_fops = {
746
746
* In turns kcov_remote_stop() clears those pointers from task_struct to stop
747
747
* collecting coverage and copies all collected coverage into the kcov area.
748
748
*/
749
+
750
+ static inline bool kcov_mode_enabled (unsigned int mode )
751
+ {
752
+ return (mode & ~KCOV_IN_CTXSW ) != KCOV_MODE_DISABLED ;
753
+ }
754
+
749
755
void kcov_remote_start (u64 handle )
750
756
{
757
+ struct task_struct * t = current ;
751
758
struct kcov_remote * remote ;
752
759
struct kcov * kcov ;
760
+ unsigned int mode ;
753
761
void * area ;
754
- struct task_struct * t ;
755
762
unsigned int size ;
756
- enum kcov_mode mode ;
757
763
int sequence ;
758
764
759
765
if (WARN_ON (!kcov_check_handle (handle , true, true, true)))
760
766
return ;
761
767
if (WARN_ON (!in_task ()))
762
768
return ;
763
- t = current ;
769
+
764
770
/*
765
771
* Check that kcov_remote_start is not called twice
766
772
* nor called by user tasks (with enabled kcov).
767
773
*/
768
- if (WARN_ON (t -> kcov ))
774
+ mode = READ_ONCE (t -> kcov_mode );
775
+ if (WARN_ON (kcov_mode_enabled (mode )))
769
776
return ;
770
777
771
778
kcov_debug ("handle = %llx\n" , handle );
@@ -863,13 +870,20 @@ static void kcov_move_area(enum kcov_mode mode, void *dst_area,
863
870
void kcov_remote_stop (void )
864
871
{
865
872
struct task_struct * t = current ;
866
- struct kcov * kcov = t -> kcov ;
867
- void * area = t -> kcov_area ;
868
- unsigned int size = t -> kcov_size ;
869
- int sequence = t -> kcov_sequence ;
873
+ struct kcov * kcov ;
874
+ unsigned int mode ;
875
+ void * area ;
876
+ unsigned int size ;
877
+ int sequence ;
870
878
871
- if (!kcov )
879
+ mode = READ_ONCE (t -> kcov_mode );
880
+ barrier ();
881
+ if (!kcov_mode_enabled (mode ))
872
882
return ;
883
+ kcov = t -> kcov ;
884
+ area = t -> kcov_area ;
885
+ size = t -> kcov_size ;
886
+ sequence = t -> kcov_sequence ;
873
887
874
888
kcov_stop (t );
875
889
0 commit comments