]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - arch/x86/include/asm/unwind.h
x86/cpu/bugs: Use __initconst for 'const' init data
[mirror_ubuntu-bionic-kernel.git] / arch / x86 / include / asm / unwind.h
index c1688c2d0a128f063053697dc60bcbfbca509765..499578f7e6d7bb5020fe0c503c70b1be0f5b95f1 100644 (file)
@@ -23,6 +23,12 @@ struct unwind_state {
 #elif defined(CONFIG_UNWINDER_FRAME_POINTER)
        bool got_irq;
        unsigned long *bp, *orig_sp, ip;
+       /*
+        * If non-NULL: The current frame is incomplete and doesn't contain a
+        * valid BP. When looking for the next frame, use this instead of the
+        * non-existent saved BP.
+        */
+       unsigned long *next_bp;
        struct pt_regs *regs;
 #else
        unsigned long *sp;
@@ -56,18 +62,27 @@ void unwind_start(struct unwind_state *state, struct task_struct *task,
 
 #if defined(CONFIG_UNWINDER_ORC) || defined(CONFIG_UNWINDER_FRAME_POINTER)
 /*
- * WARNING: The entire pt_regs may not be safe to dereference.  In some cases,
- * only the iret frame registers are accessible.  Use with caution!
+ * If 'partial' returns true, only the iret frame registers are valid.
  */
-static inline struct pt_regs *unwind_get_entry_regs(struct unwind_state *state)
+static inline struct pt_regs *unwind_get_entry_regs(struct unwind_state *state,
+                                                   bool *partial)
 {
        if (unwind_done(state))
                return NULL;
 
+       if (partial) {
+#ifdef CONFIG_UNWINDER_ORC
+               *partial = !state->full_regs;
+#else
+               *partial = false;
+#endif
+       }
+
        return state->regs;
 }
 #else
-static inline struct pt_regs *unwind_get_entry_regs(struct unwind_state *state)
+static inline struct pt_regs *unwind_get_entry_regs(struct unwind_state *state,
+                                                   bool *partial)
 {
        return NULL;
 }