[Devel] [PATCH RHEL7 COMMIT] Revert "ms/sched/x86: Add 'struct inactive_task_frame' to better document the sleeping task stack frame"

Konstantin Khorenko khorenko at virtuozzo.com
Wed Aug 30 14:11:43 MSK 2023


The commit is pushed to "branch-rh7-3.10.0-1160.95.1.vz7.210.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-1160.95.1.vz7.210.2
------>
commit 506593e939fdce795db7068017e825fa7f74e6f2
Author: Konstantin Khorenko <khorenko at virtuozzo.com>
Date:   Mon Aug 28 19:52:29 2023 +0300

    Revert "ms/sched/x86: Add 'struct inactive_task_frame' to better document the sleeping task stack frame"
    
    This reverts commit e318bc7bbcbb40076038ce34efd588cb4f7a4fd1.
    
    drgn expects 'struct inactive_task_frame' to have many fields if exists
    at all, so drgn just does not work if this patch is applied alone.
    
    The patch has been applied because it was easier to apply 226263231f8c
    ("ms/x86/unwind: Disable KASAN checks for non-current tasks") which we
    need for https://jira.vzint.dev/browse/HCI-171.
    
    So, rolling back the current patch, and will rework and re-apply
    226263231f8c ("ms/x86/unwind: Disable KASAN checks for non-current
    tasks") without the current commit which introduces 'struct
    inactive_task_frame' and confuces drgn.
    
    https://jira.vzint.dev/browse/PSBM-149932
    
    Signed-off-by: Konstantin Khorenko <khorenko at virtuozzo.com>
---
 arch/x86/include/asm/stacktrace.h | 4 ++--
 arch/x86/include/asm/switch_to.h  | 5 -----
 arch/x86/kernel/kgdb.c            | 3 +--
 arch/x86/kernel/process.c         | 3 +--
 4 files changed, 4 insertions(+), 11 deletions(-)

diff --git a/arch/x86/include/asm/stacktrace.h b/arch/x86/include/asm/stacktrace.h
index a4fe84fd293c..f8a383338352 100644
--- a/arch/x86/include/asm/stacktrace.h
+++ b/arch/x86/include/asm/stacktrace.h
@@ -8,7 +8,6 @@
 
 #include <linux/uaccess.h>
 #include <linux/ptrace.h>
-#include <asm/switch_to.h>
 
 enum stack_type {
 	STACK_TYPE_UNKNOWN,
@@ -59,7 +58,8 @@ get_frame_pointer(struct task_struct *task, struct pt_regs *regs)
 	if (task == current)
 		return __builtin_frame_address(0);
 
-	return ((struct inactive_task_frame *)task->thread.sp)->bp;
+	/* bp is the last reg pushed by switch_to */
+	return (unsigned long *)*(unsigned long *)task->thread.sp;
 }
 #else
 static inline unsigned long *
diff --git a/arch/x86/include/asm/switch_to.h b/arch/x86/include/asm/switch_to.h
index c8950d57a8f3..4ec45b3abba1 100644
--- a/arch/x86/include/asm/switch_to.h
+++ b/arch/x86/include/asm/switch_to.h
@@ -8,11 +8,6 @@ struct tss_struct;
 void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
 		      struct tss_struct *tss);
 
-/* data that is pointed to by thread.sp */
-struct inactive_task_frame {
-	unsigned long bp;
-};
-
 #ifdef CONFIG_X86_32
 
 #ifdef CONFIG_CC_STACKPROTECTOR
diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c
index 9b4e1dd2e3aa..7ec1d5f8d283 100644
--- a/arch/x86/kernel/kgdb.c
+++ b/arch/x86/kernel/kgdb.c
@@ -49,7 +49,6 @@
 #include <asm/apicdef.h>
 #include <asm/apic.h>
 #include <asm/nmi.h>
-#include <asm/switch_to.h>
 
 struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] =
 {
@@ -166,7 +165,7 @@ void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
 	gdb_regs[GDB_DX]	= 0;
 	gdb_regs[GDB_SI]	= 0;
 	gdb_regs[GDB_DI]	= 0;
-	gdb_regs[GDB_BP]	= ((struct inactive_task_frame *)p->thread.sp)->bp;
+	gdb_regs[GDB_BP]	= *(unsigned long *)p->thread.sp;
 #ifdef CONFIG_X86_32
 	gdb_regs[GDB_DS]	= __KERNEL_DS;
 	gdb_regs[GDB_ES]	= __KERNEL_DS;
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index d5e4ccbc15b7..c72d63098abe 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -32,7 +32,6 @@
 #include <asm/mce.h>
 #include <asm/prctl.h>
 #include <asm/spec_ctrl.h>
-#include <asm/switch_to.h>
 
 /*
  * per-CPU TSS segments. Threads are completely 'soft' on Linux,
@@ -753,7 +752,7 @@ unsigned long get_wchan(struct task_struct *p)
 	if (sp < bottom || sp > top)
 		return 0;
 
-	fp = READ_ONCE_NOCHECK(((struct inactive_task_frame *)sp)->bp);
+	fp = READ_ONCE_NOCHECK(*(unsigned long *)sp);
 	do {
 		if (fp < bottom || fp > top)
 			return 0;


More information about the Devel mailing list