kstack.h 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. #ifndef _KSTACK_H
  2. #define _KSTACK_H
  3. #include <linux/thread_info.h>
  4. #include <linux/sched.h>
  5. #include <asm/ptrace.h>
  6. #include <asm/irq.h>
  7. /* SP must be STACK_BIAS adjusted already. */
  8. static inline bool kstack_valid(struct thread_info *tp, unsigned long sp)
  9. {
  10. unsigned long base = (unsigned long) tp;
  11. /* Stack pointer must be 16-byte aligned. */
  12. if (sp & (16UL - 1))
  13. return false;
  14. if (sp >= (base + sizeof(struct thread_info)) &&
  15. sp <= (base + THREAD_SIZE - sizeof(struct sparc_stackf)))
  16. return true;
  17. if (hardirq_stack[tp->cpu]) {
  18. base = (unsigned long) hardirq_stack[tp->cpu];
  19. if (sp >= base &&
  20. sp <= (base + THREAD_SIZE - sizeof(struct sparc_stackf)))
  21. return true;
  22. base = (unsigned long) softirq_stack[tp->cpu];
  23. if (sp >= base &&
  24. sp <= (base + THREAD_SIZE - sizeof(struct sparc_stackf)))
  25. return true;
  26. }
  27. return false;
  28. }
  29. /* Does "regs" point to a valid pt_regs trap frame? */
  30. static inline bool kstack_is_trap_frame(struct thread_info *tp, struct pt_regs *regs)
  31. {
  32. unsigned long base = (unsigned long) tp;
  33. unsigned long addr = (unsigned long) regs;
  34. if (addr >= base &&
  35. addr <= (base + THREAD_SIZE - sizeof(*regs)))
  36. goto check_magic;
  37. if (hardirq_stack[tp->cpu]) {
  38. base = (unsigned long) hardirq_stack[tp->cpu];
  39. if (addr >= base &&
  40. addr <= (base + THREAD_SIZE - sizeof(*regs)))
  41. goto check_magic;
  42. base = (unsigned long) softirq_stack[tp->cpu];
  43. if (addr >= base &&
  44. addr <= (base + THREAD_SIZE - sizeof(*regs)))
  45. goto check_magic;
  46. }
  47. return false;
  48. check_magic:
  49. if ((regs->magic & ~0x1ff) == PT_REGS_MAGIC)
  50. return true;
  51. return false;
  52. }
  53. static inline __attribute__((always_inline)) void *set_hardirq_stack(void)
  54. {
  55. void *orig_sp, *sp = hardirq_stack[smp_processor_id()];
  56. __asm__ __volatile__("mov %%sp, %0" : "=r" (orig_sp));
  57. if (orig_sp < sp ||
  58. orig_sp > (sp + THREAD_SIZE)) {
  59. sp += THREAD_SIZE - 192 - STACK_BIAS;
  60. __asm__ __volatile__("mov %0, %%sp" : : "r" (sp));
  61. }
  62. return orig_sp;
  63. }
  64. static inline __attribute__((always_inline)) void restore_hardirq_stack(void *orig_sp)
  65. {
  66. __asm__ __volatile__("mov %0, %%sp" : : "r" (orig_sp));
  67. }
  68. #endif /* _KSTACK_H */