struct work_struct              work;
        struct user_event_mm            *mm;
        struct user_event_enabler       *enabler;
+       int                             attempt;
 };
 
 static struct kmem_cache *fault_cache;
        kfree(enabler);
 }
 
-static int user_event_mm_fault_in(struct user_event_mm *mm, unsigned long uaddr)
+static int user_event_mm_fault_in(struct user_event_mm *mm, unsigned long uaddr,
+                                 int attempt)
 {
        bool unlocked;
        int ret;
 
+       /*
+        * Normally this is low, ensure that it cannot be taken advantage of by
+        * bad user processes to cause excessive looping.
+        */
+       if (attempt > 10)
+               return -EFAULT;
+
        mmap_read_lock(mm->mm);
 
        /* Ensure MM has tasks, cannot use after exit_mm() */
 
 static int user_event_enabler_write(struct user_event_mm *mm,
                                    struct user_event_enabler *enabler,
-                                   bool fixup_fault);
+                                   bool fixup_fault, int *attempt);
 
 static void user_event_enabler_fault_fixup(struct work_struct *work)
 {
        struct user_event_enabler *enabler = fault->enabler;
        struct user_event_mm *mm = fault->mm;
        unsigned long uaddr = enabler->addr;
+       int attempt = fault->attempt;
        int ret;
 
-       ret = user_event_mm_fault_in(mm, uaddr);
+       ret = user_event_mm_fault_in(mm, uaddr, attempt);
 
        if (ret && ret != -ENOENT) {
                struct user_event *user = enabler->event;
 
        if (!ret) {
                mmap_read_lock(mm->mm);
-               user_event_enabler_write(mm, enabler, true);
+               user_event_enabler_write(mm, enabler, true, &attempt);
                mmap_read_unlock(mm->mm);
        }
 out:
 }
 
 static bool user_event_enabler_queue_fault(struct user_event_mm *mm,
-                                          struct user_event_enabler *enabler)
+                                          struct user_event_enabler *enabler,
+                                          int attempt)
 {
        struct user_event_enabler_fault *fault;
 
        INIT_WORK(&fault->work, user_event_enabler_fault_fixup);
        fault->mm = user_event_mm_get(mm);
        fault->enabler = enabler;
+       fault->attempt = attempt;
 
        /* Don't try to queue in again while we have a pending fault */
        set_bit(ENABLE_VAL_FAULTING_BIT, ENABLE_BITOPS(enabler));
 
 static int user_event_enabler_write(struct user_event_mm *mm,
                                    struct user_event_enabler *enabler,
-                                   bool fixup_fault)
+                                   bool fixup_fault, int *attempt)
 {
        unsigned long uaddr = enabler->addr;
        unsigned long *ptr;
        lockdep_assert_held(&event_mutex);
        mmap_assert_locked(mm->mm);
 
+       *attempt += 1;
+
        /* Ensure MM has tasks, cannot use after exit_mm() */
        if (refcount_read(&mm->tasks) == 0)
                return -ENOENT;
                if (!fixup_fault)
                        return -EFAULT;
 
-               if (!user_event_enabler_queue_fault(mm, enabler))
+               if (!user_event_enabler_queue_fault(mm, enabler, *attempt))
                        pr_warn("user_events: Unable to queue fault handler\n");
 
                return -EFAULT;
        struct user_event_enabler *enabler;
        struct user_event_mm *mm = user_event_mm_get_all(user);
        struct user_event_mm *next;
+       int attempt;
 
        while (mm) {
                next = mm->next;
                mmap_read_lock(mm->mm);
                rcu_read_lock();
 
-               list_for_each_entry_rcu(enabler, &mm->enablers, link)
-                       if (enabler->event == user)
-                               user_event_enabler_write(mm, enabler, true);
+               list_for_each_entry_rcu(enabler, &mm->enablers, link) {
+                       if (enabler->event == user) {
+                               attempt = 0;
+                               user_event_enabler_write(mm, enabler, true, &attempt);
+                       }
+               }
 
                rcu_read_unlock();
                mmap_read_unlock(mm->mm);
        struct user_event_enabler *enabler;
        struct user_event_mm *user_mm;
        unsigned long uaddr = (unsigned long)reg->enable_addr;
+       int attempt = 0;
 
        user_mm = current_user_event_mm();
 
 
        /* Attempt to reflect the current state within the process */
        mmap_read_lock(user_mm->mm);
-       *write_result = user_event_enabler_write(user_mm, enabler, false);
+       *write_result = user_event_enabler_write(user_mm, enabler, false,
+                                                &attempt);
        mmap_read_unlock(user_mm->mm);
 
        /*
 
        if (*write_result) {
                /* Attempt to fault-in and retry if it worked */
-               if (!user_event_mm_fault_in(user_mm, uaddr))
+               if (!user_event_mm_fault_in(user_mm, uaddr, attempt))
                        goto retry;
 
                kfree(enabler);
 {
        struct user_event_enabler enabler;
        int result;
+       int attempt = 0;
 
        memset(&enabler, 0, sizeof(enabler));
        enabler.addr = uaddr;
 
        /* Force the bit to be cleared, since no event is attached */
        mmap_read_lock(user_mm->mm);
-       result = user_event_enabler_write(user_mm, &enabler, false);
+       result = user_event_enabler_write(user_mm, &enabler, false, &attempt);
        mmap_read_unlock(user_mm->mm);
 
        mutex_unlock(&event_mutex);
 
        if (result) {
                /* Attempt to fault-in and retry if it worked */
-               if (!user_event_mm_fault_in(user_mm, uaddr))
+               if (!user_event_mm_fault_in(user_mm, uaddr, attempt))
                        goto retry;
        }