sdei_api_event_context(i, ®s->regs[i]);
}
- /*
- * We didn't take an exception to get here, set PAN. UAO will be cleared
- * by sdei_event_handler()s force_uaccess_begin() call.
- */
- __uaccess_enable_hw_pan();
-
err = sdei_event_handler(regs, arg);
if (err)
return SDEI_EV_FAILED;
__sdei_handler(struct pt_regs *regs, struct sdei_registered_event *arg)
{
unsigned long ret;
+ mm_segment_t orig_addr_limit;
+
+ /*
+ * We didn't take an exception to get here, so the HW hasn't set PAN or
+ * cleared UAO, and the exception entry code hasn't reset addr_limit.
+ * Set PAN, then use force_uaccess_begin() to clear UAO and reset
+ * addr_limit.
+ */
+ __uaccess_enable_hw_pan();
+ orig_addr_limit = force_uaccess_begin();
nmi_enter();
nmi_exit();
+ force_uaccess_end(orig_addr_limit);
+
return ret;
}