Re: [RESEND PATCH v2 1/3] x86/fred: Allow variable-sized event frame

From: Xin Li
Date: Wed Mar 19 2025 - 02:48:14 EST


On 3/18/2025 6:53 AM, Brian Gerst wrote:
-#define INIT_THREAD_INFO(tsk) \
-{ \
- .flags = 0, \
+#define INIT_THREAD_INFO(tsk) \
+{ \
+ .flags = 0, \
+ .user_pt_regs = (struct pt_regs *)TOP_OF_INIT_STACK - 1, \

Use __top_init_kernel_stack here.

Will do.


}

#else /* !__ASSEMBLER__ */
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 91f6ff618852..58c1cd4ca60a 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -108,6 +108,28 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
return 0;
}

+/*
+ * Initialize thread_info.user_pt_regs for IDT event delivery.
+ *
+ * For IDT user level event delivery, a pt_regs structure is pushed by both
+ * hardware and software and always resides at a fixed offset from top of
+ * current task kernel stack, thus thread_info.user_pt_regs is a per-task
+ * constant and NEVER changes after initialization.
+ *
+ * While for FRED user level event delivery, user_pt_regs is updated in
+ * fred_entry_from_user() immediately after user level event delivery.
+ *
+ * Note: thread_info.user_pt_regs of the init task is initialized at build
+ * time.
+ */
+void arch_init_user_pt_regs(struct task_struct *tsk)
+{
+ unsigned long top_of_stack = (unsigned long)task_stack_page(tsk) + THREAD_SIZE;
+
+ top_of_stack -= TOP_OF_KERNEL_STACK_PADDING;
+ tsk->thread_info.user_pt_regs = (struct pt_regs *)top_of_stack - 1;
+}

Can this be put into arch_dup_task_struct() instead of creating another hook?

I wanted to do it at the beginning but task stack is no longer part of
the task_struct on x86. Make sense?

Thanks!
Xin