Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 210844
b: refs/heads/master
c: 36ff4a5
h: refs/heads/master
v: v3
  • Loading branch information
Linus Torvalds committed Sep 20, 2010
1 parent a9b5433 commit 764a074
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 24 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: e3671ac429fe50cf0c1b4f1dc4b7237207f1d956
refs/heads/master: 36ff4a5517779355f4bd62030cdb8498c3954f29
51 changes: 31 additions & 20 deletions trunk/arch/frv/kernel/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,9 @@ static int restore_sigcontext(struct sigcontext __user *sc, int *_gr8)
struct user_context *user = current->thread.user;
unsigned long tbr, psr;

/* Always make any pending restarted system calls return -EINTR */
current_thread_info()->restart_block.fn = do_no_restart_syscall;

tbr = user->i.tbr;
psr = user->i.psr;
if (copy_from_user(user, &sc->sc_context, sizeof(sc->sc_context)))
Expand Down Expand Up @@ -250,6 +253,8 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
struct sigframe __user *frame;
int rsig;

set_fs(USER_DS);

frame = get_sigframe(ka, sizeof(*frame));

if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
Expand Down Expand Up @@ -293,22 +298,23 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
(unsigned long) (frame->retcode + 2));
}

/* set up registers for signal handler */
__frame->sp = (unsigned long) frame;
__frame->lr = (unsigned long) &frame->retcode;
__frame->gr8 = sig;

/* Set up registers for the signal handler */
if (current->personality & FDPIC_FUNCPTRS) {
struct fdpic_func_descriptor __user *funcptr =
(struct fdpic_func_descriptor __user *) ka->sa.sa_handler;
__get_user(__frame->pc, &funcptr->text);
__get_user(__frame->gr15, &funcptr->GOT);
struct fdpic_func_descriptor desc;
if (copy_from_user(&desc, funcptr, sizeof(desc)))
goto give_sigsegv;
__frame->pc = desc.text;
__frame->gr15 = desc.GOT;
} else {
__frame->pc = (unsigned long) ka->sa.sa_handler;
__frame->gr15 = 0;
}

set_fs(USER_DS);
__frame->sp = (unsigned long) frame;
__frame->lr = (unsigned long) &frame->retcode;
__frame->gr8 = sig;

/* the tracer may want to single-step inside the handler */
if (test_thread_flag(TIF_SINGLESTEP))
Expand All @@ -323,7 +329,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
return 0;

give_sigsegv:
force_sig(SIGSEGV, current);
force_sigsegv(sig, current);
return -EFAULT;

} /* end setup_frame() */
Expand All @@ -338,6 +344,8 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
struct rt_sigframe __user *frame;
int rsig;

set_fs(USER_DS);

frame = get_sigframe(ka, sizeof(*frame));

if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
Expand Down Expand Up @@ -392,22 +400,23 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
}

/* Set up registers for signal handler */
__frame->sp = (unsigned long) frame;
__frame->lr = (unsigned long) &frame->retcode;
__frame->gr8 = sig;
__frame->gr9 = (unsigned long) &frame->info;

if (current->personality & FDPIC_FUNCPTRS) {
struct fdpic_func_descriptor __user *funcptr =
(struct fdpic_func_descriptor __user *) ka->sa.sa_handler;
__get_user(__frame->pc, &funcptr->text);
__get_user(__frame->gr15, &funcptr->GOT);
struct fdpic_func_descriptor desc;
if (copy_from_user(&desc, funcptr, sizeof(desc)))
goto give_sigsegv;
__frame->pc = desc.text;
__frame->gr15 = desc.GOT;
} else {
__frame->pc = (unsigned long) ka->sa.sa_handler;
__frame->gr15 = 0;
}

set_fs(USER_DS);
__frame->sp = (unsigned long) frame;
__frame->lr = (unsigned long) &frame->retcode;
__frame->gr8 = sig;
__frame->gr9 = (unsigned long) &frame->info;

/* the tracer may want to single-step inside the handler */
if (test_thread_flag(TIF_SINGLESTEP))
Expand All @@ -422,7 +431,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
return 0;

give_sigsegv:
force_sig(SIGSEGV, current);
force_sigsegv(sig, current);
return -EFAULT;

} /* end setup_rt_frame() */
Expand All @@ -437,7 +446,7 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
int ret;

/* Are we from a system call? */
if (in_syscall(__frame)) {
if (__frame->syscallno != -1) {
/* If so, check system call restarting.. */
switch (__frame->gr8) {
case -ERESTART_RESTARTBLOCK:
Expand All @@ -456,6 +465,7 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
__frame->gr8 = __frame->orig_gr8;
__frame->pc -= 4;
}
__frame->syscallno = -1;
}

/* Set up the stack frame */
Expand Down Expand Up @@ -538,10 +548,11 @@ static void do_signal(void)
break;

case -ERESTART_RESTARTBLOCK:
__frame->gr8 = __NR_restart_syscall;
__frame->gr7 = __NR_restart_syscall;
__frame->pc -= 4;
break;
}
__frame->syscallno = -1;
}

/* if there's no signal to deliver, we just put the saved sigmask
Expand Down
8 changes: 5 additions & 3 deletions trunk/mm/memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -2680,10 +2680,12 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma,
delayacct_clear_flag(DELAYACCT_PF_SWAPIN);

/*
* Make sure try_to_free_swap didn't release the swapcache
* from under us. The page pin isn't enough to prevent that.
* Make sure try_to_free_swap or reuse_swap_page or swapoff did not
* release the swapcache from under us. The page pin, and pte_same
* test below, are not enough to exclude that. Even if it is still
* swapcache, we need to check that the page's swap has not changed.
*/
if (unlikely(!PageSwapCache(page)))
if (unlikely(!PageSwapCache(page) || page_private(page) != entry.val))
goto out_page;

if (ksm_might_need_to_copy(page, vma, address)) {
Expand Down

0 comments on commit 764a074

Please sign in to comment.