Guest User

x86 trap fix-single_step_syscall_32

a guest
Jul 2nd, 2020
182
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 2.66 KB | None | 0 0
  1.  
  2. ---
  3. arch/x86/kernel/traps.c | 49 +++++++++++++++++++----------------------
  4.  1 file changed, 23 insertions(+), 26 deletions(-)
  5.  
  6. diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
  7. index f58679e487f6..bb511836b929 100644
  8. --- a/arch/x86/kernel/traps.c
  9. +++ b/arch/x86/kernel/traps.c
  10. @@ -809,8 +809,17 @@ static void handle_debug(struct pt_regs *regs, unsigned long dr6, bool user)
  11.      * If DR6 is zero, no point in trying to handle it. The kernel is
  12.      * not using INT1.
  13.      */
  14. -   if (!user && !dr6)
  15. -       return;
  16. +   if (!user) {
  17. +       /*
  18. +        * Catch SYSENTER with TF set and clear DR_STEP. If this hit a
  19. +        * watchpoint at the same time then that will still be handled.
  20. +        */
  21. +       if ((dr6 & DR_STEP) && is_sysenter_singlestep(regs))
  22. +           dr6 &= ~DR_STEP;
  23. +
  24. +       if (!dr6)
  25. +           return;
  26. +   }
  27.  
  28.     /*
  29.      * If dr6 has no reason to give us about the origin of this trap,
  30. @@ -862,6 +871,7 @@ static void handle_debug(struct pt_regs *regs, unsigned long dr6, bool user)
  31.     cond_local_irq_disable(regs);
  32.  }
  33.  
  34. +#ifdef CONFIG_X86_64
  35.  static __always_inline void exc_debug_kernel(struct pt_regs *regs,
  36.                          unsigned long dr6)
  37.  {
  38. @@ -869,13 +879,6 @@ static __always_inline void exc_debug_kernel(struct pt_regs *regs,
  39.     instrumentation_begin();
  40.     trace_hardirqs_off_finish();
  41.  
  42. -   /*
  43. -    * Catch SYSENTER with TF set and clear DR_STEP. If this hit a
  44. -    * watchpoint at the same time then that will still be handled.
  45. -    */
  46. -   if ((dr6 & DR_STEP) && is_sysenter_singlestep(regs))
  47. -       dr6 &= ~DR_STEP;
  48. -
  49.     handle_debug(regs, dr6, false);
  50.  
  51.     if (regs->flags & X86_EFLAGS_IF)
  52. @@ -884,6 +887,16 @@ static __always_inline void exc_debug_kernel(struct pt_regs *regs,
  53.     nmi_exit();
  54.  }
  55.  
  56. +/* IST stack entry */
  57. +DEFINE_IDTENTRY_DEBUG(exc_debug)
  58. +{
  59. +   unsigned long dr6, dr7;
  60. +
  61. +   debug_enter(&dr6, &dr7);
  62. +   exc_debug_kernel(regs, dr6);
  63. +   debug_exit(dr7);
  64. +}
  65. +
  66.  static __always_inline void exc_debug_user(struct pt_regs *regs,
  67.                        unsigned long dr6)
  68.  {
  69. @@ -895,17 +908,6 @@ static __always_inline void exc_debug_user(struct pt_regs *regs,
  70.     idtentry_exit_user(regs);
  71.  }
  72.  
  73. -#ifdef CONFIG_X86_64
  74. -/* IST stack entry */
  75. -DEFINE_IDTENTRY_DEBUG(exc_debug)
  76. -{
  77. -   unsigned long dr6, dr7;
  78. -
  79. -   debug_enter(&dr6, &dr7);
  80. -   exc_debug_kernel(regs, dr6);
  81. -   debug_exit(dr7);
  82. -}
  83. -
  84.  /* User entry, runs on regular task stack */
  85.  DEFINE_IDTENTRY_DEBUG_USER(exc_debug)
  86.  {
  87. @@ -922,12 +924,7 @@ DEFINE_IDTENTRY_DEBUG(exc_debug)
  88.     unsigned long dr6, dr7;
  89.  
  90.     debug_enter(&dr6, &dr7);
  91. -
  92. -   if (user_mode(regs))
  93. -       exc_debug_user(regs, dr6);
  94. -   else
  95. -       exc_debug_kernel(regs, dr6);
  96. -
  97. +   handle_debug(regs, dr6, user_mode(regs));
  98.     debug_exit(dr7);
  99.  }
  100.  #endif
  101. --
  102. 2.27.0
Add Comment
Please, Sign In to add comment