void lkdtm_STACKLEAK_ERASING(void)
 {
-       unsigned long *sp, left, found, i;
-       const unsigned long check_depth =
-                       STACKLEAK_SEARCH_DEPTH / sizeof(unsigned long);
+       const unsigned long task_stack_base = (unsigned long)task_stack_page(current);
+       const unsigned long task_stack_low = stackleak_task_low_bound(current);
+       const unsigned long task_stack_high = stackleak_task_high_bound(current);
+       const unsigned long current_sp = current_stack_pointer;
+       const unsigned long lowest_sp = current->lowest_stack;
+       unsigned long untracked_high;
+       unsigned long poison_high, poison_low;
        bool test_failed = false;
 
        /*
-        * For the details about the alignment of the poison values, see
-        * the comment in stackleak_track_stack().
+        * Depending on what has run prior to this test, the lowest recorded
+        * stack pointer could be above or below the current stack pointer.
+        * Start from the lowest of the two.
+        *
+        * Poison values are naturally-aligned unsigned longs. As the current
+        * stack pointer might not be sufficiently aligned, we must align
+        * downwards to find the lowest known stack pointer value. This is the
+        * high boundary for a portion of the stack which may have been used
+        * without being tracked, and has to be scanned for poison.
         */
-       sp = PTR_ALIGN(&i, sizeof(unsigned long));
-
-       left = ((unsigned long)sp & (THREAD_SIZE - 1)) / sizeof(unsigned long);
-       sp--;
+       untracked_high = min(current_sp, lowest_sp);
+       untracked_high = ALIGN_DOWN(untracked_high, sizeof(unsigned long));
 
        /*
-        * One 'long int' at the bottom of the thread stack is reserved
-        * and not poisoned.
+        * Find the top of the poison in the same way as the erasing code.
         */
-       if (left > 1) {
-               left--;
-       } else {
-               pr_err("FAIL: not enough stack space for the test\n");
-               test_failed = true;
-               goto end;
-       }
-
-       pr_info("checking unused part of the thread stack (%lu bytes)...\n",
-                                       left * sizeof(unsigned long));
+       poison_high = stackleak_find_top_of_poison(task_stack_low, untracked_high);
 
        /*
-        * Search for 'check_depth' poison values in a row (just like
-        * stackleak_erase() does).
+        * Check whether the poisoned portion of the stack (if any) consists
+        * entirely of poison. This verifies the entries that
+        * stackleak_find_top_of_poison() should have checked.
         */
-       for (i = 0, found = 0; i < left && found <= check_depth; i++) {
-               if (*(sp - i) == STACKLEAK_POISON)
-                       found++;
-               else
-                       found = 0;
-       }
+       poison_low = poison_high;
+       while (poison_low > task_stack_low) {
+               poison_low -= sizeof(unsigned long);
 
-       pr_info("the erased part begins after %lu not poisoned bytes\n",
-                               (i - found) * sizeof(unsigned long));
+               if (*(unsigned long *)poison_low == STACKLEAK_POISON)
+                       continue;
 
-       /* The rest of thread stack should be erased */
-       for (; i < left; i++) {
-               if (*(sp - i) != STACKLEAK_POISON) {
-                       pr_err("FAIL: bad value number %lu in the erased part: 0x%lx\n",
-                                                               i, *(sp - i));
-                       test_failed = true;
-               }
+               pr_err("FAIL: non-poison value %lu bytes below poison boundary: 0x%lx\n",
+                      poison_high - poison_low, *(unsigned long *)poison_low);
+               test_failed = true;
        }
 
-end:
+       pr_info("stackleak stack usage:\n"
+               "  high offset: %lu bytes\n"
+               "  current:     %lu bytes\n"
+               "  lowest:      %lu bytes\n"
+               "  tracked:     %lu bytes\n"
+               "  untracked:   %lu bytes\n"
+               "  poisoned:    %lu bytes\n"
+               "  low offset:  %lu bytes\n",
+               task_stack_base + THREAD_SIZE - task_stack_high,
+               task_stack_high - current_sp,
+               task_stack_high - lowest_sp,
+               task_stack_high - untracked_high,
+               untracked_high - poison_high,
+               poison_high - task_stack_low,
+               task_stack_low - task_stack_base);
+
        if (test_failed) {
                pr_err("FAIL: the thread stack is NOT properly erased!\n");
                pr_expected_config(CONFIG_GCC_PLUGIN_STACKLEAK);