parisc: Move thread_info into task struct
This implements the CONFIG_THREAD_INFO_IN_TASK option. With this change: - before thread_info was part of the stack and located at the beginning of the stack - now the thread_info struct is moved and located inside the task_struct structure - the stack is allocated and handled like the major other platforms - drop the cpu field of thread_info and use instead the one in task_struct Signed-off-by: Helge Deller <deller@gmx.de> Signed-off-by: Sven Schnelle <svens@stackframe.org>
This commit is contained in:
parent
bc294838cc
commit
2214c0e772
@ -20,7 +20,7 @@
|
|||||||
| nds32: | ok |
|
| nds32: | ok |
|
||||||
| nios2: | TODO |
|
| nios2: | TODO |
|
||||||
| openrisc: | TODO |
|
| openrisc: | TODO |
|
||||||
| parisc: | TODO |
|
| parisc: | ok |
|
||||||
| powerpc: | ok |
|
| powerpc: | ok |
|
||||||
| riscv: | ok |
|
| riscv: | ok |
|
||||||
| s390: | ok |
|
| s390: | ok |
|
||||||
|
@ -56,6 +56,7 @@ config PARISC
|
|||||||
select HAVE_UNSTABLE_SCHED_CLOCK if SMP
|
select HAVE_UNSTABLE_SCHED_CLOCK if SMP
|
||||||
select LEGACY_TIMER_TICK
|
select LEGACY_TIMER_TICK
|
||||||
select CPU_NO_EFFICIENT_FFS
|
select CPU_NO_EFFICIENT_FFS
|
||||||
|
select THREAD_INFO_IN_TASK
|
||||||
select NEED_DMA_MAP_STATE
|
select NEED_DMA_MAP_STATE
|
||||||
select NEED_SG_DMA_LENGTH
|
select NEED_SG_DMA_LENGTH
|
||||||
select HAVE_ARCH_KGDB
|
select HAVE_ARCH_KGDB
|
||||||
|
19
arch/parisc/include/asm/current.h
Normal file
19
arch/parisc/include/asm/current.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0 */
|
||||||
|
#ifndef _ASM_PARISC_CURRENT_H
|
||||||
|
#define _ASM_PARISC_CURRENT_H
|
||||||
|
|
||||||
|
#include <asm/special_insns.h>
|
||||||
|
|
||||||
|
#ifndef __ASSEMBLY__
|
||||||
|
struct task_struct;
|
||||||
|
|
||||||
|
static __always_inline struct task_struct *get_current(void)
|
||||||
|
{
|
||||||
|
return (struct task_struct *) mfctl(30);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define current get_current()
|
||||||
|
|
||||||
|
#endif /* __ASSEMBLY__ */
|
||||||
|
|
||||||
|
#endif /* _ASM_PARISC_CURRENT_H */
|
@ -102,8 +102,6 @@ DECLARE_PER_CPU(struct cpuinfo_parisc, cpu_data);
|
|||||||
|
|
||||||
#define CPU_HVERSION ((boot_cpu_data.hversion >> 4) & 0x0FFF)
|
#define CPU_HVERSION ((boot_cpu_data.hversion >> 4) & 0x0FFF)
|
||||||
|
|
||||||
#define ARCH_MIN_TASKALIGN FRAME_ALIGN
|
|
||||||
|
|
||||||
struct thread_struct {
|
struct thread_struct {
|
||||||
struct pt_regs regs;
|
struct pt_regs regs;
|
||||||
unsigned long task_size;
|
unsigned long task_size;
|
||||||
|
@ -34,8 +34,23 @@ extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
|
|||||||
|
|
||||||
#endif /* !ASSEMBLY */
|
#endif /* !ASSEMBLY */
|
||||||
|
|
||||||
#define raw_smp_processor_id() (current_thread_info()->cpu)
|
/*
|
||||||
|
* This is particularly ugly: it appears we can't actually get the definition
|
||||||
|
* of task_struct here, but we need access to the CPU this task is running on.
|
||||||
|
* Instead of using task_struct we're using TASK_CPU which is extracted from
|
||||||
|
* asm-offsets.h by kbuild to get the current processor ID.
|
||||||
|
*
|
||||||
|
* This also needs to be safeguarded when building asm-offsets.s because at
|
||||||
|
* that time TASK_CPU is not defined yet. It could have been guarded by
|
||||||
|
* TASK_CPU itself, but we want the build to fail if TASK_CPU is missing
|
||||||
|
* when building something else than asm-offsets.s
|
||||||
|
*/
|
||||||
|
#ifdef GENERATING_ASM_OFFSETS
|
||||||
|
#define raw_smp_processor_id() (0)
|
||||||
|
#else
|
||||||
|
#include <asm/asm-offsets.h>
|
||||||
|
#define raw_smp_processor_id() (*(unsigned int *)((void *)current + TASK_CPU))
|
||||||
|
#endif
|
||||||
#else /* CONFIG_SMP */
|
#else /* CONFIG_SMP */
|
||||||
|
|
||||||
static inline void smp_send_all_nop(void) { return; }
|
static inline void smp_send_all_nop(void) { return; }
|
||||||
|
@ -9,23 +9,16 @@
|
|||||||
#include <asm/special_insns.h>
|
#include <asm/special_insns.h>
|
||||||
|
|
||||||
struct thread_info {
|
struct thread_info {
|
||||||
struct task_struct *task; /* main task structure */
|
|
||||||
unsigned long flags; /* thread_info flags (see TIF_*) */
|
unsigned long flags; /* thread_info flags (see TIF_*) */
|
||||||
__u32 cpu; /* current CPU */
|
|
||||||
int preempt_count; /* 0=premptable, <0=BUG; will also serve as bh-counter */
|
int preempt_count; /* 0=premptable, <0=BUG; will also serve as bh-counter */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define INIT_THREAD_INFO(tsk) \
|
#define INIT_THREAD_INFO(tsk) \
|
||||||
{ \
|
{ \
|
||||||
.task = &tsk, \
|
|
||||||
.flags = 0, \
|
.flags = 0, \
|
||||||
.cpu = 0, \
|
|
||||||
.preempt_count = INIT_PREEMPT_COUNT, \
|
.preempt_count = INIT_PREEMPT_COUNT, \
|
||||||
}
|
}
|
||||||
|
|
||||||
/* how to get the thread information struct from C */
|
|
||||||
#define current_thread_info() ((struct thread_info *)mfctl(30))
|
|
||||||
|
|
||||||
#endif /* !__ASSEMBLY */
|
#endif /* !__ASSEMBLY */
|
||||||
|
|
||||||
/* thread information allocation */
|
/* thread information allocation */
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
* Copyright (C) 2003 James Bottomley <jejb at parisc-linux.org>
|
* Copyright (C) 2003 James Bottomley <jejb at parisc-linux.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define GENERATING_ASM_OFFSETS /* asm/smp.h */
|
||||||
|
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
#include <linux/thread_info.h>
|
#include <linux/thread_info.h>
|
||||||
@ -35,13 +37,16 @@
|
|||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
DEFINE(TASK_THREAD_INFO, offsetof(struct task_struct, stack));
|
DEFINE(TASK_TI_FLAGS, offsetof(struct task_struct, thread_info.flags));
|
||||||
DEFINE(TASK_FLAGS, offsetof(struct task_struct, flags));
|
|
||||||
DEFINE(TASK_SIGPENDING, offsetof(struct task_struct, pending));
|
DEFINE(TASK_SIGPENDING, offsetof(struct task_struct, pending));
|
||||||
DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace));
|
DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace));
|
||||||
DEFINE(TASK_MM, offsetof(struct task_struct, mm));
|
DEFINE(TASK_MM, offsetof(struct task_struct, mm));
|
||||||
DEFINE(TASK_PERSONALITY, offsetof(struct task_struct, personality));
|
DEFINE(TASK_PERSONALITY, offsetof(struct task_struct, personality));
|
||||||
DEFINE(TASK_PID, offsetof(struct task_struct, pid));
|
DEFINE(TASK_PID, offsetof(struct task_struct, pid));
|
||||||
|
DEFINE(TASK_STACK, offsetof(struct task_struct, stack));
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
DEFINE(TASK_CPU, offsetof(struct task_struct, cpu));
|
||||||
|
#endif
|
||||||
BLANK();
|
BLANK();
|
||||||
DEFINE(TASK_REGS, offsetof(struct task_struct, thread.regs));
|
DEFINE(TASK_REGS, offsetof(struct task_struct, thread.regs));
|
||||||
DEFINE(TASK_PT_PSW, offsetof(struct task_struct, thread.regs.gr[ 0]));
|
DEFINE(TASK_PT_PSW, offsetof(struct task_struct, thread.regs.gr[ 0]));
|
||||||
@ -129,10 +134,6 @@ int main(void)
|
|||||||
DEFINE(TASK_PT_ISR, offsetof(struct task_struct, thread.regs.isr));
|
DEFINE(TASK_PT_ISR, offsetof(struct task_struct, thread.regs.isr));
|
||||||
DEFINE(TASK_PT_IOR, offsetof(struct task_struct, thread.regs.ior));
|
DEFINE(TASK_PT_IOR, offsetof(struct task_struct, thread.regs.ior));
|
||||||
BLANK();
|
BLANK();
|
||||||
DEFINE(TASK_SZ, sizeof(struct task_struct));
|
|
||||||
/* TASK_SZ_ALGN includes space for a stack frame. */
|
|
||||||
DEFINE(TASK_SZ_ALGN, align_frame(sizeof(struct task_struct), FRAME_ALIGN));
|
|
||||||
BLANK();
|
|
||||||
DEFINE(PT_PSW, offsetof(struct pt_regs, gr[ 0]));
|
DEFINE(PT_PSW, offsetof(struct pt_regs, gr[ 0]));
|
||||||
DEFINE(PT_GR1, offsetof(struct pt_regs, gr[ 1]));
|
DEFINE(PT_GR1, offsetof(struct pt_regs, gr[ 1]));
|
||||||
DEFINE(PT_GR2, offsetof(struct pt_regs, gr[ 2]));
|
DEFINE(PT_GR2, offsetof(struct pt_regs, gr[ 2]));
|
||||||
@ -217,17 +218,11 @@ int main(void)
|
|||||||
DEFINE(PT_IIR, offsetof(struct pt_regs, iir));
|
DEFINE(PT_IIR, offsetof(struct pt_regs, iir));
|
||||||
DEFINE(PT_ISR, offsetof(struct pt_regs, isr));
|
DEFINE(PT_ISR, offsetof(struct pt_regs, isr));
|
||||||
DEFINE(PT_IOR, offsetof(struct pt_regs, ior));
|
DEFINE(PT_IOR, offsetof(struct pt_regs, ior));
|
||||||
DEFINE(PT_SIZE, sizeof(struct pt_regs));
|
|
||||||
/* PT_SZ_ALGN includes space for a stack frame. */
|
/* PT_SZ_ALGN includes space for a stack frame. */
|
||||||
DEFINE(PT_SZ_ALGN, align_frame(sizeof(struct pt_regs), FRAME_ALIGN));
|
DEFINE(PT_SZ_ALGN, align_frame(sizeof(struct pt_regs), FRAME_ALIGN));
|
||||||
BLANK();
|
BLANK();
|
||||||
DEFINE(TI_TASK, offsetof(struct thread_info, task));
|
|
||||||
DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
|
DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
|
||||||
DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
|
DEFINE(TI_PRE_COUNT, offsetof(struct task_struct, thread_info.preempt_count));
|
||||||
DEFINE(TI_PRE_COUNT, offsetof(struct thread_info, preempt_count));
|
|
||||||
DEFINE(THREAD_SZ, sizeof(struct thread_info));
|
|
||||||
/* THREAD_SZ_ALGN includes space for a stack frame. */
|
|
||||||
DEFINE(THREAD_SZ_ALGN, align_frame(sizeof(struct thread_info), FRAME_ALIGN));
|
|
||||||
BLANK();
|
BLANK();
|
||||||
DEFINE(ICACHE_BASE, offsetof(struct pdc_cache_info, ic_base));
|
DEFINE(ICACHE_BASE, offsetof(struct pdc_cache_info, ic_base));
|
||||||
DEFINE(ICACHE_STRIDE, offsetof(struct pdc_cache_info, ic_stride));
|
DEFINE(ICACHE_STRIDE, offsetof(struct pdc_cache_info, ic_stride));
|
||||||
|
@ -63,8 +63,8 @@
|
|||||||
* Need to set up a kernel stack, so call the
|
* Need to set up a kernel stack, so call the
|
||||||
* get_stack_use_cr30 macro to set up a pointer
|
* get_stack_use_cr30 macro to set up a pointer
|
||||||
* to the pt_regs structure contained within the
|
* to the pt_regs structure contained within the
|
||||||
* task pointer pointed to by cr30. Set the stack
|
* task pointer pointed to by cr30. Load the stack
|
||||||
* pointer to point to the end of the task structure.
|
* pointer from the task structure.
|
||||||
*
|
*
|
||||||
* Note that we use shadowed registers for temps until
|
* Note that we use shadowed registers for temps until
|
||||||
* we can save %r26 and %r29. %r26 is used to preserve
|
* we can save %r26 and %r29. %r26 is used to preserve
|
||||||
@ -76,8 +76,6 @@
|
|||||||
* or handle_interruption. %r29 is used to hold a pointer
|
* or handle_interruption. %r29 is used to hold a pointer
|
||||||
* the register save area, and once again, it needs to
|
* the register save area, and once again, it needs to
|
||||||
* be a non-shadowed register so that it survives the rfir.
|
* be a non-shadowed register so that it survives the rfir.
|
||||||
*
|
|
||||||
* N.B. TASK_SZ_ALGN and PT_SZ_ALGN include space for a stack frame.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.macro get_stack_use_cr30
|
.macro get_stack_use_cr30
|
||||||
@ -86,12 +84,11 @@
|
|||||||
|
|
||||||
copy %r30, %r17
|
copy %r30, %r17
|
||||||
mfctl %cr30, %r1
|
mfctl %cr30, %r1
|
||||||
ldo THREAD_SZ_ALGN(%r1), %r30
|
tophys %r1,%r9 /* task_struct */
|
||||||
mtsp %r0,%sr7
|
LDREG TASK_STACK(%r9),%r30
|
||||||
|
ldo PT_SZ_ALGN(%r30),%r30
|
||||||
|
mtsp %r0,%sr7 /* clear sr7 after kernel stack was set! */
|
||||||
mtsp %r16,%sr3
|
mtsp %r16,%sr3
|
||||||
tophys %r1,%r9
|
|
||||||
LDREG TI_TASK(%r9), %r1 /* thread_info -> task_struct */
|
|
||||||
tophys %r1,%r9
|
|
||||||
ldo TASK_REGS(%r9),%r9
|
ldo TASK_REGS(%r9),%r9
|
||||||
STREG %r17,PT_GR30(%r9)
|
STREG %r17,PT_GR30(%r9)
|
||||||
STREG %r29,PT_GR29(%r9)
|
STREG %r29,PT_GR29(%r9)
|
||||||
@ -733,7 +730,7 @@ ENTRY(ret_from_kernel_thread)
|
|||||||
BL schedule_tail, %r2
|
BL schedule_tail, %r2
|
||||||
nop
|
nop
|
||||||
|
|
||||||
LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1
|
mfctl %cr30,%r1 /* task_struct */
|
||||||
LDREG TASK_PT_GR25(%r1), %r26
|
LDREG TASK_PT_GR25(%r1), %r26
|
||||||
#ifdef CONFIG_64BIT
|
#ifdef CONFIG_64BIT
|
||||||
LDREG TASK_PT_GR27(%r1), %r27
|
LDREG TASK_PT_GR27(%r1), %r27
|
||||||
@ -764,7 +761,6 @@ ENTRY_CFI(_switch_to)
|
|||||||
|
|
||||||
STREG %r30, TASK_PT_KSP(%r26)
|
STREG %r30, TASK_PT_KSP(%r26)
|
||||||
LDREG TASK_PT_KSP(%r25), %r30
|
LDREG TASK_PT_KSP(%r25), %r30
|
||||||
LDREG TASK_THREAD_INFO(%r25), %r25
|
|
||||||
bv %r0(%r2)
|
bv %r0(%r2)
|
||||||
mtctl %r25,%cr30
|
mtctl %r25,%cr30
|
||||||
|
|
||||||
@ -795,8 +791,7 @@ ENDPROC_CFI(_switch_to)
|
|||||||
.align PAGE_SIZE
|
.align PAGE_SIZE
|
||||||
|
|
||||||
ENTRY_CFI(syscall_exit_rfi)
|
ENTRY_CFI(syscall_exit_rfi)
|
||||||
mfctl %cr30,%r16
|
mfctl %cr30,%r16 /* task_struct */
|
||||||
LDREG TI_TASK(%r16), %r16 /* thread_info -> task_struct */
|
|
||||||
ldo TASK_REGS(%r16),%r16
|
ldo TASK_REGS(%r16),%r16
|
||||||
/* Force iaoq to userspace, as the user has had access to our current
|
/* Force iaoq to userspace, as the user has had access to our current
|
||||||
* context via sigcontext. Also Filter the PSW for the same reason.
|
* context via sigcontext. Also Filter the PSW for the same reason.
|
||||||
@ -841,14 +836,14 @@ ENTRY_CFI(syscall_exit_rfi)
|
|||||||
ENTRY(intr_return)
|
ENTRY(intr_return)
|
||||||
/* check for reschedule */
|
/* check for reschedule */
|
||||||
mfctl %cr30,%r1
|
mfctl %cr30,%r1
|
||||||
LDREG TI_FLAGS(%r1),%r19 /* sched.h: TIF_NEED_RESCHED */
|
LDREG TASK_TI_FLAGS(%r1),%r19 /* sched.h: TIF_NEED_RESCHED */
|
||||||
bb,<,n %r19,31-TIF_NEED_RESCHED,intr_do_resched /* forward */
|
bb,<,n %r19,31-TIF_NEED_RESCHED,intr_do_resched /* forward */
|
||||||
|
|
||||||
.import do_notify_resume,code
|
.import do_notify_resume,code
|
||||||
intr_check_sig:
|
intr_check_sig:
|
||||||
/* As above */
|
/* As above */
|
||||||
mfctl %cr30,%r1
|
mfctl %cr30,%r1
|
||||||
LDREG TI_FLAGS(%r1),%r19
|
LDREG TASK_TI_FLAGS(%r1),%r19
|
||||||
ldi (_TIF_USER_WORK_MASK & ~_TIF_NEED_RESCHED), %r20
|
ldi (_TIF_USER_WORK_MASK & ~_TIF_NEED_RESCHED), %r20
|
||||||
and,COND(<>) %r19, %r20, %r0
|
and,COND(<>) %r19, %r20, %r0
|
||||||
b,n intr_restore /* skip past if we've nothing to do */
|
b,n intr_restore /* skip past if we've nothing to do */
|
||||||
@ -1692,7 +1687,7 @@ dtlb_fault:
|
|||||||
|
|
||||||
.macro fork_like name
|
.macro fork_like name
|
||||||
ENTRY_CFI(sys_\name\()_wrapper)
|
ENTRY_CFI(sys_\name\()_wrapper)
|
||||||
LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1
|
mfctl %cr30,%r1
|
||||||
ldo TASK_REGS(%r1),%r1
|
ldo TASK_REGS(%r1),%r1
|
||||||
reg_save %r1
|
reg_save %r1
|
||||||
mfctl %cr27, %r28
|
mfctl %cr27, %r28
|
||||||
@ -1712,7 +1707,7 @@ ENTRY(child_return)
|
|||||||
BL schedule_tail, %r2
|
BL schedule_tail, %r2
|
||||||
nop
|
nop
|
||||||
finish_child_return:
|
finish_child_return:
|
||||||
LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1
|
mfctl %cr30,%r1
|
||||||
ldo TASK_REGS(%r1),%r1 /* get pt regs */
|
ldo TASK_REGS(%r1),%r1 /* get pt regs */
|
||||||
|
|
||||||
LDREG PT_CR27(%r1), %r3
|
LDREG PT_CR27(%r1), %r3
|
||||||
@ -1723,7 +1718,7 @@ finish_child_return:
|
|||||||
END(child_return)
|
END(child_return)
|
||||||
|
|
||||||
ENTRY_CFI(sys_rt_sigreturn_wrapper)
|
ENTRY_CFI(sys_rt_sigreturn_wrapper)
|
||||||
LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r26
|
mfctl %cr30,%r26
|
||||||
ldo TASK_REGS(%r26),%r26 /* get pt regs */
|
ldo TASK_REGS(%r26),%r26 /* get pt regs */
|
||||||
/* Don't save regs, we are going to restore them from sigcontext. */
|
/* Don't save regs, we are going to restore them from sigcontext. */
|
||||||
STREG %r2, -RP_OFFSET(%r30)
|
STREG %r2, -RP_OFFSET(%r30)
|
||||||
@ -1740,7 +1735,7 @@ ENTRY_CFI(sys_rt_sigreturn_wrapper)
|
|||||||
LDREG -RP_OFFSET(%r30), %r2
|
LDREG -RP_OFFSET(%r30), %r2
|
||||||
|
|
||||||
/* FIXME: I think we need to restore a few more things here. */
|
/* FIXME: I think we need to restore a few more things here. */
|
||||||
LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
|
mfctl %cr30,%r1
|
||||||
ldo TASK_REGS(%r1),%r1 /* get pt regs */
|
ldo TASK_REGS(%r1),%r1 /* get pt regs */
|
||||||
reg_restore %r1
|
reg_restore %r1
|
||||||
|
|
||||||
@ -1759,9 +1754,7 @@ ENTRY(syscall_exit)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* save return value now */
|
/* save return value now */
|
||||||
|
|
||||||
mfctl %cr30, %r1
|
mfctl %cr30, %r1
|
||||||
LDREG TI_TASK(%r1),%r1
|
|
||||||
STREG %r28,TASK_PT_GR28(%r1)
|
STREG %r28,TASK_PT_GR28(%r1)
|
||||||
|
|
||||||
/* Seems to me that dp could be wrong here, if the syscall involved
|
/* Seems to me that dp could be wrong here, if the syscall involved
|
||||||
@ -1772,13 +1765,14 @@ ENTRY(syscall_exit)
|
|||||||
syscall_check_resched:
|
syscall_check_resched:
|
||||||
|
|
||||||
/* check for reschedule */
|
/* check for reschedule */
|
||||||
|
mfctl %cr30,%r19
|
||||||
LDREG TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19 /* long */
|
LDREG TASK_TI_FLAGS(%r19),%r19 /* long */
|
||||||
bb,<,n %r19, 31-TIF_NEED_RESCHED, syscall_do_resched /* forward */
|
bb,<,n %r19, 31-TIF_NEED_RESCHED, syscall_do_resched /* forward */
|
||||||
|
|
||||||
.import do_signal,code
|
.import do_signal,code
|
||||||
syscall_check_sig:
|
syscall_check_sig:
|
||||||
LDREG TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19
|
mfctl %cr30,%r19
|
||||||
|
LDREG TASK_TI_FLAGS(%r19),%r19
|
||||||
ldi (_TIF_USER_WORK_MASK & ~_TIF_NEED_RESCHED), %r26
|
ldi (_TIF_USER_WORK_MASK & ~_TIF_NEED_RESCHED), %r26
|
||||||
and,COND(<>) %r19, %r26, %r0
|
and,COND(<>) %r19, %r26, %r0
|
||||||
b,n syscall_restore /* skip past if we've nothing to do */
|
b,n syscall_restore /* skip past if we've nothing to do */
|
||||||
@ -1789,7 +1783,7 @@ syscall_do_signal:
|
|||||||
* consistent with all the relevant state of the process
|
* consistent with all the relevant state of the process
|
||||||
* before the syscall. We need to verify this.
|
* before the syscall. We need to verify this.
|
||||||
*/
|
*/
|
||||||
LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
|
mfctl %cr30,%r1
|
||||||
ldo TASK_REGS(%r1), %r26 /* struct pt_regs *regs */
|
ldo TASK_REGS(%r1), %r26 /* struct pt_regs *regs */
|
||||||
reg_save %r26
|
reg_save %r26
|
||||||
|
|
||||||
@ -1800,17 +1794,17 @@ syscall_do_signal:
|
|||||||
BL do_notify_resume,%r2
|
BL do_notify_resume,%r2
|
||||||
ldi 1, %r25 /* long in_syscall = 1 */
|
ldi 1, %r25 /* long in_syscall = 1 */
|
||||||
|
|
||||||
LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
|
mfctl %cr30,%r1
|
||||||
ldo TASK_REGS(%r1), %r20 /* reload pt_regs */
|
ldo TASK_REGS(%r1), %r20 /* reload pt_regs */
|
||||||
reg_restore %r20
|
reg_restore %r20
|
||||||
|
|
||||||
b,n syscall_check_sig
|
b,n syscall_check_sig
|
||||||
|
|
||||||
syscall_restore:
|
syscall_restore:
|
||||||
LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
|
mfctl %cr30,%r1
|
||||||
|
|
||||||
/* Are we being ptraced? */
|
/* Are we being ptraced? */
|
||||||
LDREG TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19
|
LDREG TASK_TI_FLAGS(%r1),%r19
|
||||||
ldi _TIF_SYSCALL_TRACE_MASK,%r2
|
ldi _TIF_SYSCALL_TRACE_MASK,%r2
|
||||||
and,COND(=) %r19,%r2,%r0
|
and,COND(=) %r19,%r2,%r0
|
||||||
b,n syscall_restore_rfi
|
b,n syscall_restore_rfi
|
||||||
|
@ -35,7 +35,8 @@ END(boot_args)
|
|||||||
__HEAD
|
__HEAD
|
||||||
|
|
||||||
.align 4
|
.align 4
|
||||||
.import init_thread_union,data
|
.import init_task,data
|
||||||
|
.import init_stack,data
|
||||||
.import fault_vector_20,code /* IVA parisc 2.0 32 bit */
|
.import fault_vector_20,code /* IVA parisc 2.0 32 bit */
|
||||||
#ifndef CONFIG_64BIT
|
#ifndef CONFIG_64BIT
|
||||||
.import fault_vector_11,code /* IVA parisc 1.1 32 bit */
|
.import fault_vector_11,code /* IVA parisc 1.1 32 bit */
|
||||||
@ -123,12 +124,12 @@ $pgt_fill_loop:
|
|||||||
load32 start_parisc,%r11
|
load32 start_parisc,%r11
|
||||||
|
|
||||||
/* And the initial task pointer */
|
/* And the initial task pointer */
|
||||||
load32 init_thread_union,%r6
|
load32 init_task,%r6
|
||||||
mtctl %r6,%cr30
|
mtctl %r6,%cr30
|
||||||
|
|
||||||
/* And the stack pointer too */
|
/* And the stack pointer too */
|
||||||
ldo THREAD_SZ_ALGN(%r6),%sp
|
load32 init_stack,%sp
|
||||||
|
tophys_r1 %sp
|
||||||
#if defined(CONFIG_64BIT) && defined(CONFIG_FUNCTION_TRACER)
|
#if defined(CONFIG_64BIT) && defined(CONFIG_FUNCTION_TRACER)
|
||||||
.import _mcount,data
|
.import _mcount,data
|
||||||
/* initialize mcount FPTR */
|
/* initialize mcount FPTR */
|
||||||
@ -186,12 +187,11 @@ common_stext:
|
|||||||
#endif /*CONFIG_SMP*/
|
#endif /*CONFIG_SMP*/
|
||||||
|
|
||||||
#ifdef CONFIG_64BIT
|
#ifdef CONFIG_64BIT
|
||||||
tophys_r1 %sp
|
mfctl %cr30,%r6 /* PCX-W2 firmware bug */
|
||||||
|
tophys_r1 %r6
|
||||||
|
|
||||||
/* Save the rfi target address */
|
/* Save the rfi target address */
|
||||||
ldd TI_TASK-THREAD_SZ_ALGN(%sp), %r10
|
STREG %r11, TASK_PT_GR11(%r6)
|
||||||
tophys_r1 %r10
|
|
||||||
std %r11, TASK_PT_GR11(%r10)
|
|
||||||
/* Switch to wide mode Superdome doesn't support narrow PDC
|
/* Switch to wide mode Superdome doesn't support narrow PDC
|
||||||
** calls.
|
** calls.
|
||||||
*/
|
*/
|
||||||
@ -206,7 +206,6 @@ common_stext:
|
|||||||
** Someday, palo might not do this for the Monarch either.
|
** Someday, palo might not do this for the Monarch either.
|
||||||
*/
|
*/
|
||||||
2:
|
2:
|
||||||
mfctl %cr30,%r6 /* PCX-W2 firmware bug */
|
|
||||||
|
|
||||||
ldo PDC_PSW(%r0),%arg0 /* 21 */
|
ldo PDC_PSW(%r0),%arg0 /* 21 */
|
||||||
ldo PDC_PSW_SET_DEFAULTS(%r0),%arg1 /* 2 */
|
ldo PDC_PSW_SET_DEFAULTS(%r0),%arg1 /* 2 */
|
||||||
@ -216,13 +215,9 @@ common_stext:
|
|||||||
copy %r0,%arg3
|
copy %r0,%arg3
|
||||||
|
|
||||||
stext_pdc_ret:
|
stext_pdc_ret:
|
||||||
|
LDREG TASK_PT_GR11(%r6), %r11
|
||||||
|
tovirt_r1 %r6
|
||||||
mtctl %r6,%cr30 /* restore task thread info */
|
mtctl %r6,%cr30 /* restore task thread info */
|
||||||
|
|
||||||
/* restore rfi target address*/
|
|
||||||
ldd TI_TASK-THREAD_SZ_ALGN(%sp), %r10
|
|
||||||
tophys_r1 %r10
|
|
||||||
ldd TASK_PT_GR11(%r10), %r11
|
|
||||||
tovirt_r1 %sp
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* PARANOID: clear user scratch/user space SR's */
|
/* PARANOID: clear user scratch/user space SR's */
|
||||||
@ -287,7 +282,9 @@ aligned_rfi:
|
|||||||
|
|
||||||
load32 KERNEL_PSW,%r10
|
load32 KERNEL_PSW,%r10
|
||||||
mtctl %r10,%ipsw
|
mtctl %r10,%ipsw
|
||||||
|
|
||||||
|
tovirt_r1 %sp
|
||||||
|
|
||||||
/* Jump through hyperspace to Virt Mode */
|
/* Jump through hyperspace to Virt Mode */
|
||||||
rfi
|
rfi
|
||||||
nop
|
nop
|
||||||
@ -343,12 +340,13 @@ smp_slave_stext:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Initialize the SP - monarch sets up smp_init_current_idle_task */
|
/* Initialize the SP - monarch sets up smp_init_current_idle_task */
|
||||||
load32 PA(smp_init_current_idle_task),%sp
|
load32 PA(smp_init_current_idle_task),%r6
|
||||||
LDREG 0(%sp),%sp /* load task address */
|
LDREG 0(%r6),%r6
|
||||||
|
mtctl %r6,%cr30
|
||||||
|
tophys_r1 %r6
|
||||||
|
LDREG TASK_STACK(%r6),%sp
|
||||||
tophys_r1 %sp
|
tophys_r1 %sp
|
||||||
LDREG TASK_THREAD_INFO(%sp),%sp
|
ldo FRAME_SIZE(%sp),%sp
|
||||||
mtctl %sp,%cr30 /* store in cr30 */
|
|
||||||
ldo THREAD_SZ_ALGN(%sp),%sp
|
|
||||||
|
|
||||||
/* point CPU to kernel page tables */
|
/* point CPU to kernel page tables */
|
||||||
load32 PA(swapper_pg_dir),%r4
|
load32 PA(swapper_pg_dir),%r4
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include <linux/kernel_stat.h>
|
#include <linux/kernel_stat.h>
|
||||||
#include <linux/seq_file.h>
|
#include <linux/seq_file.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
#include <linux/sched/task_stack.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
|
|
||||||
#include <asm/softirq_stack.h>
|
#include <asm/softirq_stack.h>
|
||||||
@ -399,8 +400,7 @@ static inline void stack_overflow_check(struct pt_regs *regs)
|
|||||||
#ifdef CONFIG_DEBUG_STACKOVERFLOW
|
#ifdef CONFIG_DEBUG_STACKOVERFLOW
|
||||||
#define STACK_MARGIN (256*6)
|
#define STACK_MARGIN (256*6)
|
||||||
|
|
||||||
/* Our stack starts directly behind the thread_info struct. */
|
unsigned long stack_start = (unsigned long) task_stack_page(current);
|
||||||
unsigned long stack_start = (unsigned long) current_thread_info();
|
|
||||||
unsigned long sp = regs->gr[30];
|
unsigned long sp = regs->gr[30];
|
||||||
unsigned long stack_usage;
|
unsigned long stack_usage;
|
||||||
unsigned int *last_usage;
|
unsigned int *last_usage;
|
||||||
@ -476,7 +476,7 @@ static void execute_on_irq_stack(void *func, unsigned long param1)
|
|||||||
union_ptr = &per_cpu(irq_stack_union, smp_processor_id());
|
union_ptr = &per_cpu(irq_stack_union, smp_processor_id());
|
||||||
irq_stack = (unsigned long) &union_ptr->stack;
|
irq_stack = (unsigned long) &union_ptr->stack;
|
||||||
irq_stack = ALIGN(irq_stack + sizeof(irq_stack_union.slock),
|
irq_stack = ALIGN(irq_stack + sizeof(irq_stack_union.slock),
|
||||||
64); /* align for stack frame usage */
|
FRAME_ALIGN); /* align for stack frame usage */
|
||||||
|
|
||||||
/* We may be called recursive. If we are already using the irq stack,
|
/* We may be called recursive. If we are already using the irq stack,
|
||||||
* just continue to use it. Use spinlocks to serialize
|
* just continue to use it. Use spinlocks to serialize
|
||||||
|
@ -205,7 +205,7 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
|
|||||||
/* Must exit via ret_from_kernel_thread in order
|
/* Must exit via ret_from_kernel_thread in order
|
||||||
* to call schedule_tail()
|
* to call schedule_tail()
|
||||||
*/
|
*/
|
||||||
cregs->ksp = (unsigned long)stack + THREAD_SZ_ALGN + FRAME_SIZE;
|
cregs->ksp = (unsigned long) stack + FRAME_SIZE + PT_SZ_ALGN;
|
||||||
cregs->kpc = (unsigned long) &ret_from_kernel_thread;
|
cregs->kpc = (unsigned long) &ret_from_kernel_thread;
|
||||||
/*
|
/*
|
||||||
* Copy function and argument to be called from
|
* Copy function and argument to be called from
|
||||||
@ -228,7 +228,7 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
|
|||||||
if (likely(usp))
|
if (likely(usp))
|
||||||
cregs->gr[30] = usp;
|
cregs->gr[30] = usp;
|
||||||
}
|
}
|
||||||
cregs->ksp = (unsigned long)stack + THREAD_SZ_ALGN + FRAME_SIZE;
|
cregs->ksp = (unsigned long) stack + FRAME_SIZE;
|
||||||
cregs->kpc = (unsigned long) &child_return;
|
cregs->kpc = (unsigned long) &child_return;
|
||||||
|
|
||||||
/* Setup thread TLS area */
|
/* Setup thread TLS area */
|
||||||
|
@ -324,7 +324,7 @@ int smp_boot_one_cpu(int cpuid, struct task_struct *idle)
|
|||||||
const struct cpuinfo_parisc *p = &per_cpu(cpu_data, cpuid);
|
const struct cpuinfo_parisc *p = &per_cpu(cpu_data, cpuid);
|
||||||
long timeout;
|
long timeout;
|
||||||
|
|
||||||
task_thread_info(idle)->cpu = cpuid;
|
idle->cpu = cpuid;
|
||||||
|
|
||||||
/* Let _start know what logical CPU we're booting
|
/* Let _start know what logical CPU we're booting
|
||||||
** (offset into init_tasks[],cpu_data[])
|
** (offset into init_tasks[],cpu_data[])
|
||||||
|
@ -139,9 +139,9 @@ linux_gateway_entry:
|
|||||||
xor %r1,%r30,%r30 /* ye olde xor trick */
|
xor %r1,%r30,%r30 /* ye olde xor trick */
|
||||||
xor %r1,%r30,%r1
|
xor %r1,%r30,%r1
|
||||||
xor %r1,%r30,%r30
|
xor %r1,%r30,%r30
|
||||||
|
|
||||||
ldo THREAD_SZ_ALGN+FRAME_SIZE(%r30),%r30 /* set up kernel stack */
|
|
||||||
|
|
||||||
|
LDREG TASK_STACK(%r30),%r30 /* set up kernel stack */
|
||||||
|
ldo FRAME_SIZE(%r30),%r30
|
||||||
/* N.B.: It is critical that we don't set sr7 to 0 until r30
|
/* N.B.: It is critical that we don't set sr7 to 0 until r30
|
||||||
* contains a valid kernel stack pointer. It is also
|
* contains a valid kernel stack pointer. It is also
|
||||||
* critical that we don't start using the kernel stack
|
* critical that we don't start using the kernel stack
|
||||||
@ -152,7 +152,6 @@ linux_gateway_entry:
|
|||||||
ssm PSW_SM_I, %r0 /* enable interrupts */
|
ssm PSW_SM_I, %r0 /* enable interrupts */
|
||||||
STREGM %r1,FRAME_SIZE(%r30) /* save r1 (usp) here for now */
|
STREGM %r1,FRAME_SIZE(%r30) /* save r1 (usp) here for now */
|
||||||
mfctl %cr30,%r1 /* get task ptr in %r1 */
|
mfctl %cr30,%r1 /* get task ptr in %r1 */
|
||||||
LDREG TI_TASK(%r1),%r1
|
|
||||||
|
|
||||||
/* Save some registers for sigcontext and potential task
|
/* Save some registers for sigcontext and potential task
|
||||||
switch (see entry.S for the details of which ones are
|
switch (see entry.S for the details of which ones are
|
||||||
@ -207,7 +206,7 @@ linux_gateway_entry:
|
|||||||
|
|
||||||
/* Are we being ptraced? */
|
/* Are we being ptraced? */
|
||||||
mfctl %cr30, %r1
|
mfctl %cr30, %r1
|
||||||
LDREG TI_FLAGS(%r1),%r1
|
LDREG TASK_TI_FLAGS(%r1),%r1
|
||||||
ldi _TIF_SYSCALL_TRACE_MASK, %r19
|
ldi _TIF_SYSCALL_TRACE_MASK, %r19
|
||||||
and,COND(=) %r1, %r19, %r0
|
and,COND(=) %r1, %r19, %r0
|
||||||
b,n .Ltracesys
|
b,n .Ltracesys
|
||||||
@ -272,8 +271,7 @@ tracesys:
|
|||||||
* C bit set, a non-straced syscall entry results in C and D clear
|
* C bit set, a non-straced syscall entry results in C and D clear
|
||||||
* in the saved PSW.
|
* in the saved PSW.
|
||||||
*/
|
*/
|
||||||
ldo -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr */
|
mfctl %cr30,%r1 /* get task ptr */
|
||||||
LDREG TI_TASK(%r1), %r1
|
|
||||||
ssm 0,%r2
|
ssm 0,%r2
|
||||||
STREG %r2,TASK_PT_PSW(%r1) /* Lower 8 bits only!! */
|
STREG %r2,TASK_PT_PSW(%r1) /* Lower 8 bits only!! */
|
||||||
mfsp %sr0,%r2
|
mfsp %sr0,%r2
|
||||||
@ -327,8 +325,7 @@ tracesys_next:
|
|||||||
*/
|
*/
|
||||||
copy %ret0,%r20
|
copy %ret0,%r20
|
||||||
|
|
||||||
ldo -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr */
|
mfctl %cr30,%r1 /* get task ptr */
|
||||||
LDREG TI_TASK(%r1), %r1
|
|
||||||
LDREG TASK_PT_GR28(%r1), %r28 /* Restore return value */
|
LDREG TASK_PT_GR28(%r1), %r28 /* Restore return value */
|
||||||
LDREG TASK_PT_GR26(%r1), %r26 /* Restore the users args */
|
LDREG TASK_PT_GR26(%r1), %r26 /* Restore the users args */
|
||||||
LDREG TASK_PT_GR25(%r1), %r25
|
LDREG TASK_PT_GR25(%r1), %r25
|
||||||
@ -385,16 +382,14 @@ tracesys_next:
|
|||||||
makes a direct call to syscall_trace. */
|
makes a direct call to syscall_trace. */
|
||||||
|
|
||||||
tracesys_exit:
|
tracesys_exit:
|
||||||
ldo -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr */
|
mfctl %cr30,%r1 /* get task ptr */
|
||||||
LDREG TI_TASK(%r1), %r1
|
|
||||||
#ifdef CONFIG_64BIT
|
#ifdef CONFIG_64BIT
|
||||||
ldo -16(%r30),%r29 /* Reference param save area */
|
ldo -16(%r30),%r29 /* Reference param save area */
|
||||||
#endif
|
#endif
|
||||||
ldo TASK_REGS(%r1),%r26
|
ldo TASK_REGS(%r1),%r26
|
||||||
BL do_syscall_trace_exit,%r2
|
BL do_syscall_trace_exit,%r2
|
||||||
STREG %r28,TASK_PT_GR28(%r1) /* save return value now */
|
STREG %r28,TASK_PT_GR28(%r1) /* save return value now */
|
||||||
ldo -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr */
|
mfctl %cr30,%r1 /* get task ptr */
|
||||||
LDREG TI_TASK(%r1), %r1
|
|
||||||
LDREG TASK_PT_GR28(%r1), %r28 /* Restore return val. */
|
LDREG TASK_PT_GR28(%r1), %r28 /* Restore return val. */
|
||||||
|
|
||||||
ldil L%syscall_exit,%r1
|
ldil L%syscall_exit,%r1
|
||||||
@ -407,8 +402,7 @@ tracesys_exit:
|
|||||||
ldo R%tracesys_sigexit(%r2),%r2
|
ldo R%tracesys_sigexit(%r2),%r2
|
||||||
|
|
||||||
tracesys_sigexit:
|
tracesys_sigexit:
|
||||||
ldo -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr */
|
mfctl %cr30,%r1 /* get task ptr */
|
||||||
LDREG TI_TASK(%r1), %r1
|
|
||||||
#ifdef CONFIG_64BIT
|
#ifdef CONFIG_64BIT
|
||||||
ldo -16(%r30),%r29 /* Reference param save area */
|
ldo -16(%r30),%r29 /* Reference param save area */
|
||||||
#endif
|
#endif
|
||||||
|
@ -144,7 +144,7 @@ void show_regs(struct pt_regs *regs)
|
|||||||
printk("%s IIR: %08lx ISR: " RFMT " IOR: " RFMT "\n",
|
printk("%s IIR: %08lx ISR: " RFMT " IOR: " RFMT "\n",
|
||||||
level, regs->iir, regs->isr, regs->ior);
|
level, regs->iir, regs->isr, regs->ior);
|
||||||
printk("%s CPU: %8d CR30: " RFMT " CR31: " RFMT "\n",
|
printk("%s CPU: %8d CR30: " RFMT " CR31: " RFMT "\n",
|
||||||
level, current_thread_info()->cpu, cr30, cr31);
|
level, task_cpu(current), cr30, cr31);
|
||||||
printk("%s ORIG_R28: " RFMT "\n", level, regs->orig_r28);
|
printk("%s ORIG_R28: " RFMT "\n", level, regs->orig_r28);
|
||||||
|
|
||||||
if (user) {
|
if (user) {
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/sort.h>
|
#include <linux/sort.h>
|
||||||
|
#include <linux/sched/task_stack.h>
|
||||||
|
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
#include <asm/assembly.h>
|
#include <asm/assembly.h>
|
||||||
@ -299,12 +300,9 @@ static void unwind_frame_regs(struct unwind_frame_info *info)
|
|||||||
info->prev_sp = sp - 64;
|
info->prev_sp = sp - 64;
|
||||||
info->prev_ip = 0;
|
info->prev_ip = 0;
|
||||||
|
|
||||||
/* The stack is at the end inside the thread_union
|
/* Check if stack is inside kernel stack area */
|
||||||
* struct. If we reach data, we have reached the
|
if ((info->prev_sp - (unsigned long) task_stack_page(info->t))
|
||||||
* beginning of the stack and should stop unwinding. */
|
>= THREAD_SIZE) {
|
||||||
if (info->prev_sp >= (unsigned long) task_thread_info(info->t) &&
|
|
||||||
info->prev_sp < ((unsigned long) task_thread_info(info->t)
|
|
||||||
+ THREAD_SZ_ALGN)) {
|
|
||||||
info->prev_sp = 0;
|
info->prev_sp = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user