#include <asm/kdebug.h>
 
 typedef bool (*ex_handler_t)(const struct exception_table_entry *,
-                           struct pt_regs *, int);
+                           struct pt_regs *, int, unsigned long,
+                           unsigned long);
 
 static inline unsigned long
 ex_fixup_addr(const struct exception_table_entry *x)
 }
 
 __visible bool ex_handler_default(const struct exception_table_entry *fixup,
-                                 struct pt_regs *regs, int trapnr)
+                                 struct pt_regs *regs, int trapnr,
+                                 unsigned long error_code,
+                                 unsigned long fault_addr)
 {
        regs->ip = ex_fixup_addr(fixup);
        return true;
 EXPORT_SYMBOL(ex_handler_default);
 
 __visible bool ex_handler_fault(const struct exception_table_entry *fixup,
-                               struct pt_regs *regs, int trapnr)
+                               struct pt_regs *regs, int trapnr,
+                               unsigned long error_code,
+                               unsigned long fault_addr)
 {
        regs->ip = ex_fixup_addr(fixup);
        regs->ax = trapnr;
  * result of a refcount inc/dec/add/sub.
  */
 __visible bool ex_handler_refcount(const struct exception_table_entry *fixup,
-                                  struct pt_regs *regs, int trapnr)
+                                  struct pt_regs *regs, int trapnr,
+                                  unsigned long error_code,
+                                  unsigned long fault_addr)
 {
        /* First unconditionally saturate the refcount. */
        *(int *)regs->cx = INT_MIN / 2;
  * out all the FPU registers) if we can't restore from the task's FPU state.
  */
 __visible bool ex_handler_fprestore(const struct exception_table_entry *fixup,
-                                   struct pt_regs *regs, int trapnr)
+                                   struct pt_regs *regs, int trapnr,
+                                   unsigned long error_code,
+                                   unsigned long fault_addr)
 {
        regs->ip = ex_fixup_addr(fixup);
 
 EXPORT_SYMBOL_GPL(ex_handler_fprestore);
 
 __visible bool ex_handler_uaccess(const struct exception_table_entry *fixup,
-                                 struct pt_regs *regs, int trapnr)
+                                 struct pt_regs *regs, int trapnr,
+                                 unsigned long error_code,
+                                 unsigned long fault_addr)
 {
        regs->ip = ex_fixup_addr(fixup);
        return true;
 EXPORT_SYMBOL(ex_handler_uaccess);
 
 __visible bool ex_handler_ext(const struct exception_table_entry *fixup,
-                             struct pt_regs *regs, int trapnr)
+                             struct pt_regs *regs, int trapnr,
+                             unsigned long error_code,
+                             unsigned long fault_addr)
 {
        /* Special hack for uaccess_err */
        current->thread.uaccess_err = 1;
 EXPORT_SYMBOL(ex_handler_ext);
 
 __visible bool ex_handler_rdmsr_unsafe(const struct exception_table_entry *fixup,
-                                      struct pt_regs *regs, int trapnr)
+                                      struct pt_regs *regs, int trapnr,
+                                      unsigned long error_code,
+                                      unsigned long fault_addr)
 {
        if (pr_warn_once("unchecked MSR access error: RDMSR from 0x%x at rIP: 0x%lx (%pF)\n",
                         (unsigned int)regs->cx, regs->ip, (void *)regs->ip))
 EXPORT_SYMBOL(ex_handler_rdmsr_unsafe);
 
 __visible bool ex_handler_wrmsr_unsafe(const struct exception_table_entry *fixup,
-                                      struct pt_regs *regs, int trapnr)
+                                      struct pt_regs *regs, int trapnr,
+                                      unsigned long error_code,
+                                      unsigned long fault_addr)
 {
        if (pr_warn_once("unchecked MSR access error: WRMSR to 0x%x (tried to write 0x%08x%08x) at rIP: 0x%lx (%pF)\n",
                         (unsigned int)regs->cx, (unsigned int)regs->dx,
 EXPORT_SYMBOL(ex_handler_wrmsr_unsafe);
 
 __visible bool ex_handler_clear_fs(const struct exception_table_entry *fixup,
-                                  struct pt_regs *regs, int trapnr)
+                                  struct pt_regs *regs, int trapnr,
+                                  unsigned long error_code,
+                                  unsigned long fault_addr)
 {
        if (static_cpu_has(X86_BUG_NULL_SEG))
                asm volatile ("mov %0, %%fs" : : "rm" (__USER_DS));
        asm volatile ("mov %0, %%fs" : : "rm" (0));
-       return ex_handler_default(fixup, regs, trapnr);
+       return ex_handler_default(fixup, regs, trapnr, error_code, fault_addr);
 }
 EXPORT_SYMBOL(ex_handler_clear_fs);
 
        return handler == ex_handler_fault;
 }
 
-int fixup_exception(struct pt_regs *regs, int trapnr)
+int fixup_exception(struct pt_regs *regs, int trapnr, unsigned long error_code,
+                   unsigned long fault_addr)
 {
        const struct exception_table_entry *e;
        ex_handler_t handler;
                return 0;
 
        handler = ex_fixup_handler(e);
-       return handler(e, regs, trapnr);
+       return handler(e, regs, trapnr, error_code, fault_addr);
 }
 
 extern unsigned int early_recursion_flag;
         * result in a hard-to-debug panic.
         *
         * Keep in mind that not all vectors actually get here.  Early
-        * fage faults, for example, are special.
+        * page faults, for example, are special.
         */
-       if (fixup_exception(regs, trapnr))
+       if (fixup_exception(regs, trapnr, regs->orig_ax, 0))
                return;
 
        if (fixup_bug(regs, trapnr))