@@ -775,26 +775,44 @@ static __always_inline void debug_exit(unsigned long dr7)
775
775
*
776
776
* May run on IST stack.
777
777
*/
778
- static void noinstr handle_debug (struct pt_regs * regs , unsigned long dr6 ,
779
- bool user_icebp )
778
+ static void handle_debug (struct pt_regs * regs , unsigned long dr6 , bool user )
780
779
{
781
780
struct task_struct * tsk = current ;
781
+ bool user_icebp ;
782
782
int si_code ;
783
783
784
+ /*
785
+ * The SDM says "The processor clears the BTF flag when it
786
+ * generates a debug exception." Clear TIF_BLOCKSTEP to keep
787
+ * TIF_BLOCKSTEP in sync with the hardware BTF flag.
788
+ */
789
+ clear_thread_flag (TIF_BLOCKSTEP );
790
+
791
+ /*
792
+ * If DR6 is zero, no point in trying to handle it. The kernel is
793
+ * not using INT1.
794
+ */
795
+ if (!user && !dr6 )
796
+ return ;
797
+
798
+ /*
799
+ * If dr6 has no reason to give us about the origin of this trap,
800
+ * then it's very likely the result of an icebp/int01 trap.
801
+ * User wants a sigtrap for that.
802
+ */
803
+ user_icebp = user && !dr6 ;
804
+
784
805
/* Store the virtualized DR6 value */
785
806
tsk -> thread .debugreg6 = dr6 ;
786
807
787
- instrumentation_begin ();
788
808
#ifdef CONFIG_KPROBES
789
809
if (kprobe_debug_handler (regs )) {
790
- instrumentation_end ();
791
810
return ;
792
811
}
793
812
#endif
794
813
795
814
if (notify_die (DIE_DEBUG , "debug" , regs , (long )& dr6 , 0 ,
796
815
SIGTRAP ) == NOTIFY_STOP ) {
797
- instrumentation_end ();
798
816
return ;
799
817
}
800
818
@@ -825,7 +843,6 @@ static void noinstr handle_debug(struct pt_regs *regs, unsigned long dr6,
825
843
826
844
out :
827
845
cond_local_irq_disable (regs );
828
- instrumentation_end ();
829
846
}
830
847
831
848
static __always_inline void exc_debug_kernel (struct pt_regs * regs ,
@@ -834,14 +851,6 @@ static __always_inline void exc_debug_kernel(struct pt_regs *regs,
834
851
nmi_enter ();
835
852
instrumentation_begin ();
836
853
trace_hardirqs_off_finish ();
837
- instrumentation_end ();
838
-
839
- /*
840
- * The SDM says "The processor clears the BTF flag when it
841
- * generates a debug exception." Clear TIF_BLOCKSTEP to keep
842
- * TIF_BLOCKSTEP in sync with the hardware BTF flag.
843
- */
844
- clear_thread_flag (TIF_BLOCKSTEP );
845
854
846
855
/*
847
856
* Catch SYSENTER with TF set and clear DR_STEP. If this hit a
@@ -850,14 +859,8 @@ static __always_inline void exc_debug_kernel(struct pt_regs *regs,
850
859
if ((dr6 & DR_STEP ) && is_sysenter_singlestep (regs ))
851
860
dr6 &= ~DR_STEP ;
852
861
853
- /*
854
- * If DR6 is zero, no point in trying to handle it. The kernel is
855
- * not using INT1.
856
- */
857
- if (dr6 )
858
- handle_debug (regs , dr6 , false);
862
+ handle_debug (regs , dr6 , false);
859
863
860
- instrumentation_begin ();
861
864
if (regs -> flags & X86_EFLAGS_IF )
862
865
trace_hardirqs_on_prepare ();
863
866
instrumentation_end ();
@@ -868,14 +871,10 @@ static __always_inline void exc_debug_user(struct pt_regs *regs,
868
871
unsigned long dr6 )
869
872
{
870
873
idtentry_enter_user (regs );
871
- clear_thread_flag ( TIF_BLOCKSTEP );
874
+ instrumentation_begin ( );
872
875
873
- /*
874
- * If dr6 has no reason to give us about the origin of this trap,
875
- * then it's very likely the result of an icebp/int01 trap.
876
- * User wants a sigtrap for that.
877
- */
878
- handle_debug (regs , dr6 , !dr6 );
876
+ handle_debug (regs , dr6 , true);
877
+ instrumentation_end ();
879
878
idtentry_exit_user (regs );
880
879
}
881
880
0 commit comments