Commit cbc67add authored by Martin Schwidefsky's avatar Martin Schwidefsky Committed by Linus Torvalds

[PATCH] s390: base fixes.

s390 arch changes/bug fixes:
 * add sys_fadvise64 system call
 * add initialization of init_sighand
 * add support for clone option CLONE_SETTLS
 * make use of ptrace_notify
 * sig -> sighand rename
 * move ptrace_signal_deliver to the correct place
 * make eieio a memory barrier
 * fix race condition on cpu_vm_mask in __flush_tlb_mm
 * add missing KM_SOFTIRQ0, KM_SOFTIRQ1 in asm-s390x/kmap_types.h
 * add inline assmelby for _raw_write_trylock
parent a871d09c
......@@ -616,7 +616,8 @@ sys_call_table:
.long sys_epoll_ctl /* 250 */
.long sys_epoll_wait
.long sys_set_tid_address
.rept 255-252
.long sys_fadvise64
.rept 255-253
.long sys_ni_syscall
.endr
......
......@@ -16,6 +16,7 @@
static struct fs_struct init_fs = INIT_FS;
static struct files_struct init_files = INIT_FILES;
static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
struct mm_struct init_mm = INIT_MM(init_mm);
/*
......
......@@ -196,8 +196,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long new_stackp,
/* new return point is ret_from_fork */
frame->gprs[8] = (unsigned long) ret_from_fork;
/* start disabled because of schedule_tick and rq->lock being held */
frame->childregs.psw.mask &= ~0x03000000;
/* fake return stack for resume(), don't go back to schedule */
frame->gprs[9] = (unsigned long) frame;
......@@ -213,6 +211,10 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long new_stackp,
p->thread.ar4 = get_fs().ar4;
/* Don't copy debug registers */
memset(&p->thread.per_info,0,sizeof(p->thread.per_info));
/* Set a new TLS ? */
if (clone_flags & CLONE_SETTLS)
frame->childregs.acrs[0] = regs->gprs[6];
return 0;
}
......@@ -335,7 +337,7 @@ unsigned long get_wchan(struct task_struct *p)
int count = 0;
if (!p || p == current || p->state == TASK_RUNNING)
return 0;
stack_page = (unsigned long) p;
stack_page = (unsigned long) p->thread_info;
r15 = p->thread.ksp;
if (!stack_page || r15 < stack_page || r15 >= 8188+stack_page)
return 0;
......
......@@ -359,11 +359,9 @@ asmlinkage void syscall_trace(void)
return;
if (!(current->ptrace & PT_PTRACED))
return;
current->exit_code =
SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) ? 0x80 : 0);
current->state = TASK_STOPPED;
notify_parent(current, SIGCHLD);
schedule();
ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
? 0x80 : 0));
/*
* this isn't the same as continuing with a signal, but it will do
* for normal use. strace only continues with a signal if the
......
......@@ -391,7 +391,7 @@ static void
handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
struct pt_regs * regs)
{
struct k_sigaction *ka = &current->sig->action[sig-1];
struct k_sigaction *ka = &current->sighand->action[sig-1];
/* Are we from a system call? */
if (regs->trap == __LC_SVC_OLD_PSW) {
......
......@@ -644,7 +644,8 @@ sys_call_table:
.long SYSCALL(sys_epoll_ctl,sys_ni_syscall)
.long SYSCALL(sys_epoll_wait,sys_ni_syscall)
.long SYSCALL(sys_set_tid_address,sys_ni_syscall)
.rept 255-252
.long SYSCALL(sys_fadvise64,sys_ni_syscall)
.rept 255-253
.long SYSCALL(sys_ni_syscall,sys_ni_syscall)
.endr
......
......@@ -16,6 +16,7 @@
static struct fs_struct init_fs = INIT_FS;
static struct files_struct init_files = INIT_FILES;
static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
struct mm_struct init_mm = INIT_MM(init_mm);
/*
......
......@@ -203,6 +203,19 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long new_stackp,
p->thread.ar4 = get_fs().ar4;
/* Don't copy debug registers */
memset(&p->thread.per_info,0,sizeof(p->thread.per_info));
/* Set a new TLS ? */
if (clone_flags & CLONE_SETTLS) {
if (current->thread.flags & S390_FLAG_31BIT) {
frame->childregs.acrs[0] =
(unsigned int) regs->gprs[6];
} else {
frame->childregs.acrs[0] =
(unsigned int)(regs->gprs[6] >> 32);
frame->childregs.acrs[1] =
(unsigned int) regs->gprs[6];
}
}
return 0;
}
......@@ -319,7 +332,7 @@ unsigned long get_wchan(struct task_struct *p)
int count = 0;
if (!p || p == current || p->state == TASK_RUNNING)
return 0;
stack_page = (unsigned long) p;
stack_page = (unsigned long) p->thread_info;
r15 = p->thread.ksp;
if (!stack_page || r15 < stack_page || r15 >= 16380+stack_page)
return 0;
......
......@@ -598,11 +598,9 @@ asmlinkage void syscall_trace(void)
return;
if (!(current->ptrace & PT_PTRACED))
return;
current->exit_code =
SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) ? 0x80 : 0);
current->state = TASK_STOPPED;
notify_parent(current, SIGCHLD);
schedule();
ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
? 0x80 : 0));
/*
* this isn't the same as continuing with a signal, but it will do
* for normal use. strace only continues with a signal if the
......
......@@ -385,7 +385,7 @@ static void
handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
struct pt_regs * regs)
{
struct k_sigaction *ka = &current->sig->action[sig-1];
struct k_sigaction *ka = &current->sighand->action[sig-1];
/* Are we from a system call? */
if (regs->trap == __LC_SVC_OLD_PSW) {
......
......@@ -159,6 +159,9 @@ struct sigaction {
struct k_sigaction {
struct sigaction sa;
};
#define ptrace_signal_deliver(regs, cookie) do { } while (0)
#else
/* Here we must cater to libcs that poke about in kernel headers. */
......@@ -175,8 +178,6 @@ struct sigaction {
#define sa_handler _u._sa_handler
#define sa_sigaction _u._sa_sigaction
#define ptrace_signal_deliver(regs, cookie) do { } while (0)
#endif /* __KERNEL__ */
typedef struct sigaltstack {
......
......@@ -122,4 +122,17 @@ typedef struct {
: "+m" ((rw)->lock) : "a" (&(rw)->lock) \
: "2", "3", "cc" )
extern inline int _raw_write_trylock(rwlock_t *rw)
{
unsigned int result, reg;
__asm__ __volatile__(" lhi %0,1\n"
" sll %0,31\n"
" basr %1,0\n"
"0: cs %0,%1,0(%3)\n"
: "=&d" (result), "=&d" (reg), "+m" (rw->lock)
: "a" (&rw->lock) : "cc" );
return !result;
}
#endif /* __ASM_SPINLOCK_H */
......@@ -222,7 +222,7 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
* all memory ops have completed wrt other CPU's ( see 7-15 POP DJB ).
*/
#define eieio() __asm__ __volatile__ ("BCR 15,0")
#define eieio() __asm__ __volatile__ ( "bcr 15,0" : : : "memory" )
# define SYNC_OTHER_CORES(x) eieio()
#define mb() eieio()
#define rmb() eieio()
......
......@@ -91,15 +91,17 @@ static inline void global_flush_tlb(void)
static inline void __flush_tlb_mm(struct mm_struct * mm)
{
preempt_disable();
if (mm->cpu_vm_mask != (1UL << smp_processor_id())) {
/* mm was active on more than one cpu. */
if (mm == current->active_mm &&
atomic_read(&mm->mm_count) == 1)
atomic_read(&mm->mm_users) == 1)
/* this cpu is the only one using the mm. */
mm->cpu_vm_mask = 1UL << smp_processor_id();
global_flush_tlb();
} else
local_flush_tlb();
preempt_enable();
}
static inline void flush_tlb(void)
......
......@@ -248,6 +248,7 @@
#define __NR_epoll_ctl 250
#define __NR_epoll_wait 251
#define __NR_set_tid_address 252
#define __NR_fadvise64 253
/* user-visible error numbers are in the range -1 - -122: see <asm-s390/errno.h> */
......
......@@ -14,6 +14,8 @@ enum km_type {
KM_PTE1,
KM_IRQ0,
KM_IRQ1,
KM_SOFTIRQ0,
KM_SOFTIRQ1,
KM_TYPE_NR
};
......
......@@ -159,6 +159,9 @@ struct sigaction {
struct k_sigaction {
struct sigaction sa;
};
#define ptrace_signal_deliver(regs, cookie) do { } while (0)
#else
/* Here we must cater to libcs that poke about in kernel headers. */
......@@ -175,8 +178,6 @@ struct sigaction {
#define sa_handler _u._sa_handler
#define sa_sigaction _u._sa_sigaction
#define ptrace_signal_deliver(regs, cookie) do { } while (0)
#endif /* __KERNEL__ */
typedef struct sigaltstack {
......
......@@ -139,5 +139,17 @@ typedef struct {
: "a" (&(rw)->lock), "i" (__DIAG44_OPERAND) \
: "2", "3", "cc" )
extern inline int _raw_write_trylock(rwlock_t *rw)
{
unsigned int result, reg;
__asm__ __volatile__(" llihh %0,0x8000\n"
" basr %1,0\n"
"0: csg %0,%1,0(%3)\n"
: "=&d" (result), "=&d" (reg), "+m" (rw->lock)
: "a" (&rw->lock) : "cc" );
return !result;
}
#endif /* __ASM_SPINLOCK_H */
......@@ -233,7 +233,7 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
* all memory ops have completed wrt other CPU's ( see 7-15 POP DJB ).
*/
#define eieio() __asm__ __volatile__ ("BCR 15,0")
#define eieio() __asm__ __volatile__ ( "bcr 15,0" : : : "memory" )
# define SYNC_OTHER_CORES(x) eieio()
#define mb() eieio()
#define rmb() eieio()
......
......@@ -88,15 +88,17 @@ static inline void global_flush_tlb(void)
static inline void __flush_tlb_mm(struct mm_struct * mm)
{
preempt_disable();
if (mm->cpu_vm_mask != (1UL << smp_processor_id())) {
/* mm was active on more than one cpu. */
if (mm == current->active_mm &&
atomic_read(&mm->mm_count) == 1)
atomic_read(&mm->mm_users) == 1)
/* this cpu is the only one using the mm. */
mm->cpu_vm_mask = 1UL << smp_processor_id();
global_flush_tlb();
} else
local_flush_tlb();
preempt_enable();
}
static inline void flush_tlb(void)
......
......@@ -215,6 +215,7 @@
#define __NR_epoll_ctl 250
#define __NR_epoll_wait 251
#define __NR_set_tid_address 252
#define __NR_fadvise64 253
/* user-visible error numbers are in the range -1 - -122: see <asm-s390/errno.h> */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment