static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,
                                                      unsigned int n)
  {
 -      unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs);
 -      addr += n;
 -      if (regs_within_kernel_stack(regs, (unsigned long)addr))
 -              return *addr;
 -      else
 -              return 0;
 +      unsigned long *addr;
 +      unsigned long val;
 +      long ret;
 +
 +      addr = regs_get_kernel_stack_nth_addr(regs, n);
 +      if (addr) {
 +              ret = probe_kernel_read(&val, addr, sizeof(val));
 +              if (!ret)
 +                      return val;
 +      }
 +      return 0;
  }
  
+ /**
+  * regs_get_kernel_argument() - get Nth function argument in kernel
+  * @regs:     pt_regs of that context
+  * @n:                function argument number (start from 0)
+  *
+  * regs_get_argument() returns @n th argument of the function call.
+  * Note that this chooses most probably assignment, in some case
+  * it can be incorrect.
+  * This is expected to be called from kprobes or ftrace with regs
+  * where the top of stack is the return address.
+  */
+ static inline unsigned long regs_get_kernel_argument(struct pt_regs *regs,
+                                                    unsigned int n)
+ {
+       static const unsigned int argument_offs[] = {
+ #ifdef __i386__
+               offsetof(struct pt_regs, ax),
+               offsetof(struct pt_regs, cx),
+               offsetof(struct pt_regs, dx),
+ #define NR_REG_ARGUMENTS 3
+ #else
+               offsetof(struct pt_regs, di),
+               offsetof(struct pt_regs, si),
+               offsetof(struct pt_regs, dx),
+               offsetof(struct pt_regs, cx),
+               offsetof(struct pt_regs, r8),
+               offsetof(struct pt_regs, r9),
+ #define NR_REG_ARGUMENTS 6
+ #endif
+       };
+ 
+       if (n >= NR_REG_ARGUMENTS) {
+               n -= NR_REG_ARGUMENTS - 1;
+               return regs_get_kernel_stack_nth(regs, n);
+       } else
+               return regs_get_register(regs, argument_offs[n]);
+ }
+ 
  #define arch_has_single_step()        (1)
  #ifdef CONFIG_X86_DEBUGCTLMSR
  #define arch_has_block_step() (1)