hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/arch/s390/kernel/process.c
....@@ -37,8 +37,10 @@
3737 #include <asm/irq.h>
3838 #include <asm/nmi.h>
3939 #include <asm/smp.h>
40
+#include <asm/stacktrace.h>
4041 #include <asm/switch_to.h>
4142 #include <asm/runtime_instr.h>
43
+#include <asm/unwind.h>
4244 #include "entry.h"
4345
4446 asmlinkage void ret_from_fork(void) asm ("ret_from_fork");
....@@ -75,11 +77,23 @@
7577
7678 memcpy(dst, src, arch_task_struct_size);
7779 dst->thread.fpu.regs = dst->thread.fpu.fprs;
80
+
81
+ /*
82
+ * Don't transfer over the runtime instrumentation or the guarded
83
+ * storage control block pointers. These fields are cleared here instead
84
+ * of in copy_thread() to avoid premature freeing of associated memory
85
+ * on fork() failure. Wait to clear the RI flag because ->stack still
86
+ * refers to the source thread.
87
+ */
88
+ dst->thread.ri_cb = NULL;
89
+ dst->thread.gs_cb = NULL;
90
+ dst->thread.gs_bc_cb = NULL;
91
+
7892 return 0;
7993 }
8094
81
-int copy_thread_tls(unsigned long clone_flags, unsigned long new_stackp,
82
- unsigned long arg, struct task_struct *p, unsigned long tls)
95
+int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
96
+ unsigned long arg, struct task_struct *p, unsigned long tls)
8397 {
8498 struct fake_frame
8599 {
....@@ -104,6 +118,7 @@
104118 p->thread.system_timer = 0;
105119 p->thread.hardirq_timer = 0;
106120 p->thread.softirq_timer = 0;
121
+ p->thread.last_break = 1;
107122
108123 frame->sf.back_chain = 0;
109124 /* new return point is ret_from_fork */
....@@ -112,7 +127,7 @@
112127 frame->sf.gprs[9] = (unsigned long) frame;
113128
114129 /* Store access registers to kernel stack of new process. */
115
- if (unlikely(p->flags & PF_KTHREAD)) {
130
+ if (unlikely(p->flags & (PF_KTHREAD | PF_IO_WORKER))) {
116131 /* kernel thread */
117132 memset(&frame->childregs, 0, sizeof(struct pt_regs));
118133 frame->childregs.psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT |
....@@ -131,13 +146,11 @@
131146 frame->childregs.flags = 0;
132147 if (new_stackp)
133148 frame->childregs.gprs[15] = new_stackp;
134
-
135
- /* Don't copy runtime instrumentation info */
136
- p->thread.ri_cb = NULL;
149
+ /*
150
+ * Clear the runtime instrumentation flag after the above childregs
151
+ * copy. The CB pointer was already cleared in arch_dup_task_struct().
152
+ */
137153 frame->childregs.psw.mask &= ~PSW_MASK_RI;
138
- /* Don't copy guarded storage control block */
139
- p->thread.gs_cb = NULL;
140
- p->thread.gs_bc_cb = NULL;
141154
142155 /* Set a new TLS ? */
143156 if (clone_flags & CLONE_SETTLS) {
....@@ -157,29 +170,10 @@
157170 asm volatile("sfpc %0" : : "d" (0));
158171 }
159172
160
-/*
161
- * fill in the FPU structure for a core dump.
162
- */
163
-int dump_fpu (struct pt_regs * regs, s390_fp_regs *fpregs)
164
-{
165
- save_fpu_regs();
166
- fpregs->fpc = current->thread.fpu.fpc;
167
- fpregs->pad = 0;
168
- if (MACHINE_HAS_VX)
169
- convert_vx_to_fp((freg_t *)&fpregs->fprs,
170
- current->thread.fpu.vxrs);
171
- else
172
- memcpy(&fpregs->fprs, current->thread.fpu.fprs,
173
- sizeof(fpregs->fprs));
174
- return 1;
175
-}
176
-EXPORT_SYMBOL(dump_fpu);
177
-
178173 unsigned long get_wchan(struct task_struct *p)
179174 {
180
- struct stack_frame *sf, *low, *high;
181
- unsigned long return_address;
182
- int count;
175
+ struct unwind_state state;
176
+ unsigned long ip = 0;
183177
184178 if (!p || p == current || p->state == TASK_RUNNING || !task_stack_page(p))
185179 return 0;
....@@ -187,26 +181,22 @@
187181 if (!try_get_task_stack(p))
188182 return 0;
189183
190
- low = task_stack_page(p);
191
- high = (struct stack_frame *) task_pt_regs(p);
192
- sf = (struct stack_frame *) p->thread.ksp;
193
- if (sf <= low || sf > high) {
194
- return_address = 0;
195
- goto out;
196
- }
197
- for (count = 0; count < 16; count++) {
198
- sf = (struct stack_frame *) sf->back_chain;
199
- if (sf <= low || sf > high) {
200
- return_address = 0;
201
- goto out;
184
+ unwind_for_each_frame(&state, p, NULL, 0) {
185
+ if (state.stack_info.type != STACK_TYPE_TASK) {
186
+ ip = 0;
187
+ break;
202188 }
203
- return_address = sf->gprs[8];
204
- if (!in_sched_functions(return_address))
205
- goto out;
189
+
190
+ ip = unwind_get_return_address(&state);
191
+ if (!ip)
192
+ break;
193
+
194
+ if (!in_sched_functions(ip))
195
+ break;
206196 }
207
-out:
197
+
208198 put_task_stack(p);
209
- return return_address;
199
+ return ip;
210200 }
211201
212202 unsigned long arch_align_stack(unsigned long sp)