check_signal: system call restart is done only once
Fujitsu: POSTK_TEMP_FIX_66 Refs: #1009 Change-Id: Ic0f04ac6b7f6c6bb01b55fb389bf9befd56b1dd9
This commit is contained in:
committed by
Masamichi Takagi
parent
c25fb2aa39
commit
e4da71010c
@ -847,9 +847,6 @@ void setup_x86_ap(void (*next_func)(void))
|
|||||||
}
|
}
|
||||||
|
|
||||||
void arch_show_interrupt_context(const void *reg);
|
void arch_show_interrupt_context(const void *reg);
|
||||||
void set_signal(int sig, void *regs, struct siginfo *info);
|
|
||||||
void check_signal(unsigned long, void *, int);
|
|
||||||
void check_sig_pending();
|
|
||||||
extern void tlb_flush_handler(int vector);
|
extern void tlb_flush_handler(int vector);
|
||||||
|
|
||||||
void __show_stack(uintptr_t *sp) {
|
void __show_stack(uintptr_t *sp) {
|
||||||
@ -877,7 +874,7 @@ void interrupt_exit(struct x86_user_context *regs)
|
|||||||
cpu_enable_interrupt();
|
cpu_enable_interrupt();
|
||||||
check_sig_pending();
|
check_sig_pending();
|
||||||
check_need_resched();
|
check_need_resched();
|
||||||
check_signal(0, regs, 0);
|
check_signal(0, regs, -1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
check_sig_pending();
|
check_sig_pending();
|
||||||
|
|||||||
@ -36,8 +36,6 @@
|
|||||||
void terminate_mcexec(int, int);
|
void terminate_mcexec(int, int);
|
||||||
extern long do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact);
|
extern long do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact);
|
||||||
long syscall(int num, ihk_mc_user_context_t *ctx);
|
long syscall(int num, ihk_mc_user_context_t *ctx);
|
||||||
void set_signal(int sig, void *regs0, siginfo_t *info);
|
|
||||||
void check_signal(unsigned long rc, void *regs0, int num);
|
|
||||||
extern unsigned long do_fork(int, unsigned long, unsigned long, unsigned long,
|
extern unsigned long do_fork(int, unsigned long, unsigned long, unsigned long,
|
||||||
unsigned long, unsigned long, unsigned long);
|
unsigned long, unsigned long, unsigned long);
|
||||||
extern int get_xsave_size();
|
extern int get_xsave_size();
|
||||||
@ -261,7 +259,7 @@ SYSCALL_DECLARE(rt_sigreturn)
|
|||||||
info.si_code = TRAP_TRACE;
|
info.si_code = TRAP_TRACE;
|
||||||
set_signal(SIGTRAP, regs, &info);
|
set_signal(SIGTRAP, regs, &info);
|
||||||
check_need_resched();
|
check_need_resched();
|
||||||
check_signal(0, regs, 0);
|
check_signal(0, regs, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ksigsp.fpregs && xsavesize){
|
if(ksigsp.fpregs && xsavesize){
|
||||||
@ -286,7 +284,6 @@ SYSCALL_DECLARE(rt_sigreturn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern struct cpu_local_var *clv;
|
extern struct cpu_local_var *clv;
|
||||||
extern unsigned long do_kill(struct thread *thread, int pid, int tid, int sig, struct siginfo *info, int ptracecont);
|
|
||||||
extern void interrupt_syscall(struct thread *, int sig);
|
extern void interrupt_syscall(struct thread *, int sig);
|
||||||
extern void terminate(int, int);
|
extern void terminate(int, int);
|
||||||
extern int num_processors;
|
extern int num_processors;
|
||||||
@ -643,11 +640,13 @@ arch_ptrace(long request, int pid, long addr, long data)
|
|||||||
static int
|
static int
|
||||||
isrestart(int num, unsigned long rc, int sig, int restart)
|
isrestart(int num, unsigned long rc, int sig, int restart)
|
||||||
{
|
{
|
||||||
if(sig == SIGKILL || sig == SIGSTOP)
|
if (sig == SIGKILL || sig == SIGSTOP)
|
||||||
return 0;
|
return 0;
|
||||||
if(num == 0 || rc != -EINTR)
|
if (num < 0 || rc != -EINTR)
|
||||||
return 0;
|
return 0;
|
||||||
switch(num){
|
if (sig == SIGCHLD)
|
||||||
|
return 1;
|
||||||
|
switch (num) {
|
||||||
case __NR_pause:
|
case __NR_pause:
|
||||||
case __NR_rt_sigsuspend:
|
case __NR_rt_sigsuspend:
|
||||||
case __NR_rt_sigtimedwait:
|
case __NR_rt_sigtimedwait:
|
||||||
@ -668,14 +667,12 @@ isrestart(int num, unsigned long rc, int sig, int restart)
|
|||||||
case __NR_io_getevents:
|
case __NR_io_getevents:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(sig == SIGCHLD)
|
if (restart)
|
||||||
return 1;
|
|
||||||
if(restart)
|
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int
|
||||||
do_signal(unsigned long rc, void *regs0, struct thread *thread, struct sig_pending *pending, int num)
|
do_signal(unsigned long rc, void *regs0, struct thread *thread, struct sig_pending *pending, int num)
|
||||||
{
|
{
|
||||||
struct x86_user_context *regs = regs0;
|
struct x86_user_context *regs = regs0;
|
||||||
@ -687,6 +684,7 @@ do_signal(unsigned long rc, void *regs0, struct thread *thread, struct sig_pendi
|
|||||||
int ptraceflag = 0;
|
int ptraceflag = 0;
|
||||||
struct mcs_rwlock_node_irqsave lock;
|
struct mcs_rwlock_node_irqsave lock;
|
||||||
struct mcs_rwlock_node_irqsave mcs_rw_node;
|
struct mcs_rwlock_node_irqsave mcs_rw_node;
|
||||||
|
int restart = 0;
|
||||||
|
|
||||||
for(w = pending->sigmask.__val[0], sig = 0; w; sig++, w >>= 1);
|
for(w = pending->sigmask.__val[0], sig = 0; w; sig++, w >>= 1);
|
||||||
dkprintf("do_signal(): tid=%d, pid=%d, sig=%d\n", thread->tid, proc->pid, sig);
|
dkprintf("do_signal(): tid=%d, pid=%d, sig=%d\n", thread->tid, proc->pid, sig);
|
||||||
@ -715,7 +713,7 @@ do_signal(unsigned long rc, void *regs0, struct thread *thread, struct sig_pendi
|
|||||||
if(k->sa.sa_handler == SIG_IGN){
|
if(k->sa.sa_handler == SIG_IGN){
|
||||||
kfree(pending);
|
kfree(pending);
|
||||||
mcs_rwlock_writer_unlock(&thread->sigcommon->lock, &mcs_rw_node);
|
mcs_rwlock_writer_unlock(&thread->sigcommon->lock, &mcs_rw_node);
|
||||||
return;
|
goto out;
|
||||||
}
|
}
|
||||||
else if(k->sa.sa_handler){
|
else if(k->sa.sa_handler){
|
||||||
unsigned long *usp; /* user stack */
|
unsigned long *usp; /* user stack */
|
||||||
@ -765,9 +763,8 @@ do_signal(unsigned long rc, void *regs0, struct thread *thread, struct sig_pendi
|
|||||||
memcpy(&ksigsp.sigstack, &thread->sigstack, sizeof(stack_t));
|
memcpy(&ksigsp.sigstack, &thread->sigstack, sizeof(stack_t));
|
||||||
ksigsp.sigrc = rc;
|
ksigsp.sigrc = rc;
|
||||||
ksigsp.num = num;
|
ksigsp.num = num;
|
||||||
ksigsp.restart = isrestart(num, rc, sig, k->sa.sa_flags & SA_RESTART);
|
restart = isrestart(num, rc, sig, k->sa.sa_flags & SA_RESTART);
|
||||||
if(num != 0 && rc == -EINTR && sig == SIGCHLD)
|
ksigsp.restart = restart;
|
||||||
ksigsp.restart = 1;
|
|
||||||
if(xsavesize){
|
if(xsavesize){
|
||||||
uint64_t xsave_mask = get_xsave_mask();
|
uint64_t xsave_mask = get_xsave_mask();
|
||||||
unsigned int low = (unsigned int)xsave_mask;
|
unsigned int low = (unsigned int)xsave_mask;
|
||||||
@ -780,7 +777,7 @@ do_signal(unsigned long rc, void *regs0, struct thread *thread, struct sig_pendi
|
|||||||
kfree(_kfpregs);
|
kfree(_kfpregs);
|
||||||
kprintf("do_signal,no space available\n");
|
kprintf("do_signal,no space available\n");
|
||||||
terminate(0, sig);
|
terminate(0, sig);
|
||||||
return;
|
goto out;
|
||||||
}
|
}
|
||||||
kfpregs = (void *)((((unsigned long)_kfpregs) + 63) & ~63);
|
kfpregs = (void *)((((unsigned long)_kfpregs) + 63) & ~63);
|
||||||
memset(kfpregs, '\0', xsavesize);
|
memset(kfpregs, '\0', xsavesize);
|
||||||
@ -790,7 +787,7 @@ do_signal(unsigned long rc, void *regs0, struct thread *thread, struct sig_pendi
|
|||||||
kfree(_kfpregs);
|
kfree(_kfpregs);
|
||||||
kprintf("do_signal,write_process_vm failed\n");
|
kprintf("do_signal,write_process_vm failed\n");
|
||||||
terminate(0, sig);
|
terminate(0, sig);
|
||||||
return;
|
goto out;
|
||||||
}
|
}
|
||||||
ksigsp.fpregs = (void *)fpregs;
|
ksigsp.fpregs = (void *)fpregs;
|
||||||
kfree(_kfpregs);
|
kfree(_kfpregs);
|
||||||
@ -802,7 +799,7 @@ do_signal(unsigned long rc, void *regs0, struct thread *thread, struct sig_pendi
|
|||||||
mcs_rwlock_writer_unlock(&thread->sigcommon->lock, &mcs_rw_node);
|
mcs_rwlock_writer_unlock(&thread->sigcommon->lock, &mcs_rw_node);
|
||||||
kprintf("do_signal,write_process_vm failed\n");
|
kprintf("do_signal,write_process_vm failed\n");
|
||||||
terminate(0, sig);
|
terminate(0, sig);
|
||||||
return;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
usp = (unsigned long *)sigsp;
|
usp = (unsigned long *)sigsp;
|
||||||
@ -832,7 +829,7 @@ do_signal(unsigned long rc, void *regs0, struct thread *thread, struct sig_pendi
|
|||||||
info.si_code = TRAP_TRACE;
|
info.si_code = TRAP_TRACE;
|
||||||
set_signal(SIGTRAP, regs, &info);
|
set_signal(SIGTRAP, regs, &info);
|
||||||
check_need_resched();
|
check_need_resched();
|
||||||
check_signal(0, regs, 0);
|
check_signal(0, regs, -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -940,6 +937,8 @@ do_signal(unsigned long rc, void *regs0, struct thread *thread, struct sig_pendi
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
out:
|
||||||
|
return restart;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct sig_pending *
|
static struct sig_pending *
|
||||||
@ -1019,6 +1018,12 @@ void save_syscall_return_value(int num, unsigned long rc)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** \brief check arrived signals and processing
|
||||||
|
*
|
||||||
|
* @param rc return value of syscall
|
||||||
|
* @param regs0 context
|
||||||
|
* @param num syscall number (-1: Not called on exiting system call)
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
check_signal(unsigned long rc, void *regs0, int num)
|
check_signal(unsigned long rc, void *regs0, int num)
|
||||||
{
|
{
|
||||||
@ -1059,7 +1064,9 @@ check_signal(unsigned long rc, void *regs0, int num)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
do_signal(rc, regs, thread, pending, num);
|
if (do_signal(rc, regs, thread, pending, num)) {
|
||||||
|
num = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
@ -1139,7 +1146,7 @@ check_sig_pending_thread(struct thread *thread)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
check_sig_pending()
|
check_sig_pending(void)
|
||||||
{
|
{
|
||||||
struct thread *thread;
|
struct thread *thread;
|
||||||
struct cpu_local_var *v;
|
struct cpu_local_var *v;
|
||||||
|
|||||||
@ -839,6 +839,13 @@ void chain_thread(struct thread *);
|
|||||||
void proc_init(void);
|
void proc_init(void);
|
||||||
void set_timer(int runq_locked);
|
void set_timer(int runq_locked);
|
||||||
struct sig_pending *hassigpending(struct thread *thread);
|
struct sig_pending *hassigpending(struct thread *thread);
|
||||||
|
extern int do_signal(unsigned long rc, void *regs0, struct thread *thread,
|
||||||
|
struct sig_pending *pending, int num);
|
||||||
|
extern void check_signal(unsigned long rc, void *regs0, int num);
|
||||||
|
extern unsigned long do_kill(struct thread *thread, int pid, int tid, int sig,
|
||||||
|
struct siginfo *info, int ptracecont);
|
||||||
|
extern void set_signal(int sig, void *regs, struct siginfo *info);
|
||||||
|
extern void check_sig_pending(void);
|
||||||
|
|
||||||
void release_fp_regs(struct thread *proc);
|
void release_fp_regs(struct thread *proc);
|
||||||
void save_fp_regs(struct thread *proc);
|
void save_fp_regs(struct thread *proc);
|
||||||
|
|||||||
@ -960,8 +960,6 @@ static struct ihk_mc_interrupt_handler query_free_mem_handler = {
|
|||||||
.priv = NULL,
|
.priv = NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
void set_signal(int sig, void *regs, struct siginfo *info);
|
|
||||||
void check_signal(unsigned long, void *, int);
|
|
||||||
int gencore(struct thread *, void *, struct coretable **, int *);
|
int gencore(struct thread *, void *, struct coretable **, int *);
|
||||||
void freecore(struct coretable **);
|
void freecore(struct coretable **);
|
||||||
|
|
||||||
@ -1221,7 +1219,7 @@ out:
|
|||||||
if(interrupt_from_user(regs)){
|
if(interrupt_from_user(regs)){
|
||||||
cpu_enable_interrupt();
|
cpu_enable_interrupt();
|
||||||
check_need_resched();
|
check_need_resched();
|
||||||
check_signal(0, regs, 0);
|
check_signal(0, regs, -1);
|
||||||
}
|
}
|
||||||
set_cputime(interrupt_from_user(regs)? 0: 1);
|
set_cputime(interrupt_from_user(regs)? 0: 1);
|
||||||
#ifdef PROFILE_ENABLE
|
#ifdef PROFILE_ENABLE
|
||||||
|
|||||||
@ -82,7 +82,6 @@ extern void lapic_timer_disable();
|
|||||||
extern int num_processors;
|
extern int num_processors;
|
||||||
extern ihk_spinlock_t cpuid_head_lock;
|
extern ihk_spinlock_t cpuid_head_lock;
|
||||||
int ptrace_detach(int pid, int data);
|
int ptrace_detach(int pid, int data);
|
||||||
extern unsigned long do_kill(struct thread *, int pid, int tid, int sig, struct siginfo *info, int ptracecont);
|
|
||||||
extern void procfs_create_thread(struct thread *);
|
extern void procfs_create_thread(struct thread *);
|
||||||
extern void procfs_delete_thread(struct thread *);
|
extern void procfs_delete_thread(struct thread *);
|
||||||
|
|
||||||
|
|||||||
@ -116,10 +116,7 @@ static ihk_spinlock_t tod_data_lock = SPIN_LOCK_UNLOCKED;
|
|||||||
static unsigned long uti_desc; /* Address of struct uti_desc object in syscall_intercept.c */
|
static unsigned long uti_desc; /* Address of struct uti_desc object in syscall_intercept.c */
|
||||||
static void calculate_time_from_tsc(struct timespec *ts);
|
static void calculate_time_from_tsc(struct timespec *ts);
|
||||||
|
|
||||||
void check_signal(unsigned long, void *, int);
|
|
||||||
void save_syscall_return_value(int num, unsigned long rc);
|
void save_syscall_return_value(int num, unsigned long rc);
|
||||||
void do_signal(long rc, void *regs, struct thread *thread, struct sig_pending *pending, int num);
|
|
||||||
extern unsigned long do_kill(struct thread *thread, int pid, int tid, int sig, struct siginfo *info, int ptracecont);
|
|
||||||
extern long alloc_debugreg(struct thread *thread);
|
extern long alloc_debugreg(struct thread *thread);
|
||||||
extern int num_processors;
|
extern int num_processors;
|
||||||
extern unsigned long ihk_mc_get_ns_per_tsc(void);
|
extern unsigned long ihk_mc_get_ns_per_tsc(void);
|
||||||
@ -4204,7 +4201,7 @@ SYSCALL_DECLARE(rt_sigtimedwait)
|
|||||||
list_del(&pending->list);
|
list_del(&pending->list);
|
||||||
thread->sigmask.__val[0] = bset;
|
thread->sigmask.__val[0] = bset;
|
||||||
mcs_rwlock_writer_unlock(lock, &mcs_rw_node);
|
mcs_rwlock_writer_unlock(lock, &mcs_rw_node);
|
||||||
do_signal(-EINTR, NULL, thread, pending, 0);
|
do_signal(-EINTR, NULL, thread, pending, -1);
|
||||||
return -EINTR;
|
return -EINTR;
|
||||||
}
|
}
|
||||||
mcs_rwlock_writer_unlock(lock, &mcs_rw_node);
|
mcs_rwlock_writer_unlock(lock, &mcs_rw_node);
|
||||||
@ -4317,7 +4314,7 @@ do_sigsuspend(struct thread *thread, const sigset_t *set)
|
|||||||
list_del(&pending->list);
|
list_del(&pending->list);
|
||||||
mcs_rwlock_writer_unlock(lock, &mcs_rw_node);
|
mcs_rwlock_writer_unlock(lock, &mcs_rw_node);
|
||||||
thread->sigmask.__val[0] = bset;
|
thread->sigmask.__val[0] = bset;
|
||||||
do_signal(-EINTR, NULL, thread, pending, 0);
|
do_signal(-EINTR, NULL, thread, pending, -1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return -EINTR;
|
return -EINTR;
|
||||||
@ -9549,7 +9546,7 @@ long syscall(int num, ihk_mc_user_context_t *ctx)
|
|||||||
if(cpu_local_var(current)->proc->status == PS_EXITED &&
|
if(cpu_local_var(current)->proc->status == PS_EXITED &&
|
||||||
(num != __NR_exit && num != __NR_exit_group)){
|
(num != __NR_exit && num != __NR_exit_group)){
|
||||||
save_syscall_return_value(num, -EINVAL);
|
save_syscall_return_value(num, -EINVAL);
|
||||||
check_signal(-EINVAL, NULL, 0);
|
check_signal(-EINVAL, NULL, -1);
|
||||||
set_cputime(0);
|
set_cputime(0);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|||||||
49
test/issues/1009/C1009.patch
Normal file
49
test/issues/1009/C1009.patch
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
diff --git a/arch/x86_64/kernel/syscall.c b/arch/x86_64/kernel/syscall.c
|
||||||
|
index 4b2742b..a3173c9 100644
|
||||||
|
--- a/arch/x86_64/kernel/syscall.c
|
||||||
|
+++ b/arch/x86_64/kernel/syscall.c
|
||||||
|
@@ -1670,6 +1670,11 @@ long do_arch_prctl(unsigned long code, unsigned long address)
|
||||||
|
break;
|
||||||
|
case ARCH_SET_GS:
|
||||||
|
return -ENOTSUPP;
|
||||||
|
+ case 999: {
|
||||||
|
+ struct thread *thread = cpu_local_var(current);
|
||||||
|
+ thread->proc->dblsig = (int)address;
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
diff --git a/kernel/include/process.h b/kernel/include/process.h
|
||||||
|
index 24acf1f..dd94469 100644
|
||||||
|
--- a/kernel/include/process.h
|
||||||
|
+++ b/kernel/include/process.h
|
||||||
|
@@ -580,6 +580,8 @@ struct process {
|
||||||
|
#endif // PROFILE_ENABLE
|
||||||
|
int nr_processes; /* For partitioned execution */
|
||||||
|
int process_rank; /* Rank in partition */
|
||||||
|
+
|
||||||
|
+ int dblsig;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
diff --git a/kernel/syscall.c b/kernel/syscall.c
|
||||||
|
index 15d4593..3d03fad 100644
|
||||||
|
--- a/kernel/syscall.c
|
||||||
|
+++ b/kernel/syscall.c
|
||||||
|
@@ -9632,6 +9632,15 @@ long syscall(int num, ihk_mc_user_context_t *ctx)
|
||||||
|
|
||||||
|
if (!list_empty(&thread->sigpending) ||
|
||||||
|
!list_empty(&thread->sigcommon->sigpending)) {
|
||||||
|
+ if (!list_empty(&thread->sigcommon->sigpending) &&
|
||||||
|
+ thread->proc->dblsig) {
|
||||||
|
+ kprintf("have a signal, waiting arrive more signal\n");
|
||||||
|
+ while (list_is_singular(
|
||||||
|
+ &thread->sigcommon->sigpending)) {
|
||||||
|
+ schedule();
|
||||||
|
+ }
|
||||||
|
+ kprintf("have some signals\n");
|
||||||
|
+ }
|
||||||
|
check_signal(l, NULL, num);
|
||||||
|
}
|
||||||
|
|
||||||
131
test/issues/1009/C1009.sh
Normal file
131
test/issues/1009/C1009.sh
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
BOOTPARAM="-c 1-7,17-23,9-15,25-31 -m 10G@0,10G@1"
|
||||||
|
USELTP=1
|
||||||
|
USEOSTEST=
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
BINDIR=
|
||||||
|
SBINDIR=
|
||||||
|
OSTESTDIR=
|
||||||
|
LTPDIR=
|
||||||
|
LTPBIN=
|
||||||
|
MCEXEC=
|
||||||
|
TESTMCK=
|
||||||
|
|
||||||
|
if [ -f $HOME/mck_test_config ]; then
|
||||||
|
. $HOME/mck_test_config
|
||||||
|
elif [ -f ../../../mck_test_config.sample ]; then
|
||||||
|
. ../../../mck_test_config.sample
|
||||||
|
else
|
||||||
|
BIN=
|
||||||
|
SBIN=
|
||||||
|
OSTEST=
|
||||||
|
LTP=
|
||||||
|
fi
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
if [ "x$BIN" = x ]; then
|
||||||
|
if [ -f ../../../config.h ]; then
|
||||||
|
str=`grep "^#define BINDIR " ../../../config.h | head -1 | sed 's/^#define BINDIR /BINDIR=/'`
|
||||||
|
eval $str
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
BINDIR="$BIN"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "x$SBIN" = x ]; then
|
||||||
|
if [ -f ../../../Makefile ]; then
|
||||||
|
str=`grep ^SBINDIR ../../../Makefile | head -1 | sed 's/ //g'`
|
||||||
|
eval $str
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
SBINDIR="$SBIN"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -x "$BINDIR/mcexec" ]; then
|
||||||
|
echo no mckernel found $BINDIR >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
MCEXEC="$BINDIR/mcexec"
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
if [ "x$USELTP" != x ]; then
|
||||||
|
if [ "x$LTP" = x ]; then
|
||||||
|
if [ -f "$HOME/ltp/testcases/bin/fork01" ]; then
|
||||||
|
LTPDIR="$HOME/ltp"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
LTPDIR="$LTP"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -x "$LTPDIR/testcases/bin/fork01" ]; then
|
||||||
|
echo no LTP found $LTPDIR >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
LTPBIN="$LTPDIR/testcases/bin"
|
||||||
|
fi
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
if [ "x$USEOSTEST" != x ]; then
|
||||||
|
if [ "x$OSTEST" = x ]; then
|
||||||
|
if [ -f "$HOME/ostest/bin/test_mck" ]; then
|
||||||
|
OSTESTDIR="$HOME/ostest"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
OSTESTDIR="$OSTEST"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -x "$OSTESTDIR"/bin/test_mck ]; then
|
||||||
|
echo no ostest found $OSTESTDIR >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
TESTMCK="$OSTESTDIR/bin/test_mck"
|
||||||
|
fi
|
||||||
|
|
||||||
|
#===============================================================================
|
||||||
|
if [ ! -x "$SBINDIR/mcstop+release.sh" ]; then
|
||||||
|
echo mcstop+release: not found >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo -n "mcstop+release.sh ... "
|
||||||
|
sudo "$SBINDIR/mcstop+release.sh"
|
||||||
|
echo "done"
|
||||||
|
|
||||||
|
if lsmod | grep mcctrl > /dev/null 2>&1; then
|
||||||
|
echo mckernel shutdown failed >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -x "$SBINDIR/mcreboot.sh" ]; then
|
||||||
|
echo mcreboot: not found >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo -n "mcreboot.sh $BOOTPARAM ... "
|
||||||
|
sudo "$SBINDIR/mcreboot.sh" $BOOTPARAM
|
||||||
|
echo "done"
|
||||||
|
|
||||||
|
if ! lsmod | grep mcctrl > /dev/null 2>&1; then
|
||||||
|
echo mckernel boot failed >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
$MCEXEC ./C1009T01
|
||||||
|
|
||||||
|
if [ x$LTPDIR = x ]; then
|
||||||
|
echo no LTP found >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
for i in kill01:02 kill12:03 pause02:04 sigaction01:05 ; do
|
||||||
|
tp=`echo $i|sed 's/:.*//'`
|
||||||
|
id=`echo $i|sed 's/.*://'`
|
||||||
|
$MCEXEC $LTPBIN/$tp 2>&1 | tee $tp.txt
|
||||||
|
ok=`grep TPASS $tp.txt | wc -l`
|
||||||
|
ng=`grep TFAIL $tp.txt | wc -l`
|
||||||
|
if [ $ng = 0 ]; then
|
||||||
|
echo "*** C1009T$id: $tp OK ($ok)"
|
||||||
|
else
|
||||||
|
echo "*** C1009T$id: $tp NG (ok=$ok ng=%ng)"
|
||||||
|
fi
|
||||||
|
done
|
||||||
24
test/issues/1009/C1009.txt
Normal file
24
test/issues/1009/C1009.txt
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
Script started on Mon Sep 10 15:12:28 2018
|
||||||
|
bash-4.2$ make test
|
||||||
|
gcc -g -Wall -o C1009T01 C1009T01.c
|
||||||
|
sh ./C1009.sh
|
||||||
|
SIGUSR2
|
||||||
|
SIGUSR1
|
||||||
|
read A OK
|
||||||
|
read B OK
|
||||||
|
*** C1009T01: OK
|
||||||
|
kill01 1 TPASS : received expected signal 9
|
||||||
|
*** C1009T02: kill01 OK (1)
|
||||||
|
kill12 1 TPASS : Test passed
|
||||||
|
*** C1009T03: kill12 OK (1)
|
||||||
|
pause02 1 TPASS : pause was interrupted correctly
|
||||||
|
*** C1009T04: pause02 OK (1)
|
||||||
|
sigaction01 1 TPASS : SA_RESETHAND did not cause SA_SIGINFO to be cleared
|
||||||
|
sigaction01 2 TPASS : SA_RESETHAND was masked when handler executed
|
||||||
|
sigaction01 3 TPASS : sig has been masked because sa_mask originally contained sig
|
||||||
|
sigaction01 4 TPASS : siginfo pointer non NULL
|
||||||
|
*** C1009T05: sigaction01 OK (4)
|
||||||
|
bash-4.2$ exit
|
||||||
|
exit
|
||||||
|
|
||||||
|
Script done on Mon Sep 10 15:12:54 2018
|
||||||
107
test/issues/1009/C1009T01.c
Normal file
107
test/issues/1009/C1009T01.c
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <asm/prctl.h>
|
||||||
|
#include <sys/prctl.h>
|
||||||
|
|
||||||
|
int arch_prctl(int code, unsigned long *addr);
|
||||||
|
|
||||||
|
void
|
||||||
|
sigusr(int sig)
|
||||||
|
{
|
||||||
|
if (sig == SIGUSR1) {
|
||||||
|
printf("SIGUSR1\n");
|
||||||
|
}
|
||||||
|
else if (sig == SIGUSR2) {
|
||||||
|
printf("SIGUSR2\n");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("other sig\n");
|
||||||
|
}
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
struct sigaction act;
|
||||||
|
pid_t pid1 = 0;
|
||||||
|
pid_t pid2 = 0;
|
||||||
|
pid_t parent;
|
||||||
|
int pfd[2];
|
||||||
|
char ch;
|
||||||
|
int rc;
|
||||||
|
unsigned long val;
|
||||||
|
|
||||||
|
memset(&act, '\0', sizeof(act));
|
||||||
|
act.sa_handler = sigusr;
|
||||||
|
act.sa_flags = SA_RESTART;
|
||||||
|
sigaction(SIGUSR1, &act, NULL);
|
||||||
|
sigaction(SIGUSR2, &act, NULL);
|
||||||
|
|
||||||
|
pipe(pfd);
|
||||||
|
|
||||||
|
parent = getpid();
|
||||||
|
val = 1;
|
||||||
|
if (arch_prctl(999, (unsigned long *)val) == -1) {
|
||||||
|
fprintf(stderr, "C1009T01 WARN: no mckernel patch detected.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((pid1 = fork())) {
|
||||||
|
pid2 = fork();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pid1 || !pid2) {
|
||||||
|
int sig;
|
||||||
|
|
||||||
|
close(pfd[0]);
|
||||||
|
if (pid1)
|
||||||
|
sig = SIGUSR2;
|
||||||
|
else
|
||||||
|
sig = SIGUSR1;
|
||||||
|
|
||||||
|
sleep(1);
|
||||||
|
kill(parent, sig);
|
||||||
|
if (pid1) {
|
||||||
|
sleep(2);
|
||||||
|
ch = 'B';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sleep(1);
|
||||||
|
ch = 'A';
|
||||||
|
}
|
||||||
|
write(pfd[1], &ch, 1);
|
||||||
|
close(pfd[1]);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
rc = read(pfd[0], &ch, 1);
|
||||||
|
if (rc != 1) {
|
||||||
|
printf("C1009T01 NG: read error rc=%d errno=%d\n", rc, errno);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (ch != 'A') {
|
||||||
|
printf("C1009T01 NG: read BAD DATA ch=%c\n", ch);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
val = 0;
|
||||||
|
arch_prctl(999, (unsigned long *)val);
|
||||||
|
printf("read %c OK\n", ch);
|
||||||
|
rc = read(pfd[0], &ch, 1);
|
||||||
|
if (rc != 1) {
|
||||||
|
printf("C1009T01 NG: read error rc=%d errno=%d\n", rc, errno);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (ch != 'B') {
|
||||||
|
printf("C1009T01 NG: read BAD DATA ch=%c\n", ch);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("read %c OK\n", ch);
|
||||||
|
printf("*** C1009T01: OK\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
13
test/issues/1009/Makefile
Normal file
13
test/issues/1009/Makefile
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
CC = gcc
|
||||||
|
TARGET = C1009T01
|
||||||
|
|
||||||
|
all:: $(TARGET)
|
||||||
|
|
||||||
|
C1009T01: C1009T01.c
|
||||||
|
$(CC) -g -Wall -o $@ $^
|
||||||
|
|
||||||
|
test:: all
|
||||||
|
sh ./C1009.sh
|
||||||
|
|
||||||
|
clean::
|
||||||
|
rm -f $(TARGET) *.o
|
||||||
27
test/issues/1009/README
Normal file
27
test/issues/1009/README
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
【Issue#1009 動作確認】
|
||||||
|
□ テスト内容
|
||||||
|
1. システムコール処理中にシグナルハンドラを呼び出す複数のシグナルを
|
||||||
|
受信し、当該システムコールを再処理するとき、当該システムコールが
|
||||||
|
1度しか処理されないことを確認する(指摘現象)。
|
||||||
|
尚、シグナルを同時に発行する状態を再現させるのが困難なため、本
|
||||||
|
テストは複数シグナルを待ち合わせるパッチを適用したカーネルで行う。
|
||||||
|
McKernel へのパッチファイルは C1009.patch である。
|
||||||
|
C1009T01 シグナルを複数受信したとき、システムコールの再処理を1度だけ行う確認
|
||||||
|
|
||||||
|
2. 変更が他のシグナル処理に影響しないことをLTPを用いて確認する。
|
||||||
|
C1009T02 kill01: kill の基本機能の確認
|
||||||
|
C1009T03 kill12: kill, wait, signal の組み合わせ確認
|
||||||
|
C1009T04 pause02: pause の基本機能の確認
|
||||||
|
C1009T05 sigaction01: sigaction の基本機能の確認
|
||||||
|
|
||||||
|
□ 実行手順
|
||||||
|
$ make test
|
||||||
|
|
||||||
|
実行できない場合は、C1009.shの以下の行を適切に書き換えた後に実行。
|
||||||
|
BIN= mcexec が存在するパス
|
||||||
|
SBIN= mcreboot.sh が存在するパス
|
||||||
|
LTP= LTP が存在するパス
|
||||||
|
|
||||||
|
□ 実行結果
|
||||||
|
C1009.txt 参照。
|
||||||
|
全ての項目が OK となっていることを確認。
|
||||||
Reference in New Issue
Block a user