~ubuntu-branches/ubuntu/trusty/qemu/trusty-proposed

« back to all changes in this revision

Viewing changes to linux-user/signal.c

  • Committer: Package Import Robot
  • Author(s): Serge Hallyn, dann frazier, Serge Hallyn
  • Date: 2014-03-06 16:15:50 UTC
  • Revision ID: package-import@ubuntu.com-20140306161550-83y1d9kr1t4t19tz
Tags: 1.7.0+dfsg-3ubuntu5
[ dann frazier ]
* Add patches from the susematz tree to avoid intermittent segfaults:
   - ubuntu/signal-added-a-wrapper-for-sigprocmask-function.patch
   - ubuntu/signal-sigsegv-protection-on-do_sigprocmask.patch
   - ubuntu/Don-t-block-SIGSEGV-at-more-places.patch

[ Serge Hallyn ]
* Modify do_sigprocmask to only change behavior for aarch64.
  (LP: #1285363)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1213
1213
    uint64_t pstate;
1214
1214
 
1215
1215
    target_to_host_sigset(&set, &sf->uc.tuc_sigmask);
1216
 
    sigprocmask(SIG_SETMASK, &set, NULL);
 
1216
    do_sigprocmask(SIG_SETMASK, &set, NULL);
1217
1217
 
1218
1218
    for (i = 0; i < 31; i++) {
1219
1219
        __get_user(env->xregs[i], &sf->uc.tuc_mcontext.regs[i]);
5654
5654
 
5655
5655
#endif
5656
5656
 
 
5657
/* Wrapper for sigprocmask function
 
5658
 * Emulates a sigprocmask in a safe way for the guest. Note that set and oldset
 
5659
 * are host signal set, not guest ones. This wraps the sigprocmask host calls
 
5660
 * that should be protected (calls originated from guest)
 
5661
 */
 
5662
int do_sigprocmask(int how, const sigset_t *set, sigset_t *oldset)
 
5663
{
 
5664
#ifdef TARGET_AARCH64
 
5665
    int ret;
 
5666
    sigset_t val;
 
5667
    sigset_t *temp;
 
5668
    if (set) {
 
5669
        val = *set;
 
5670
        temp = &val;
 
5671
        sigdelset(temp, SIGSEGV);
 
5672
    } else {
 
5673
        temp = NULL;
 
5674
    }
 
5675
    ret = sigprocmask(how, temp, oldset);
 
5676
 
 
5677
    /* Force set state of SIGSEGV, may be best for some apps, maybe not so good
 
5678
     * This is not required for qemu to work */
 
5679
    if (oldset) {
 
5680
        sigaddset(oldset, SIGSEGV);
 
5681
    }
 
5682
    return ret;
 
5683
#else
 
5684
    return sigprocmask(how, set, oldset);
 
5685
#endif
 
5686
}
 
5687
 
5657
5688
void process_pending_signals(CPUArchState *cpu_env)
5658
5689
{
5659
5690
    CPUState *cpu = ENV_GET_CPU(cpu_env);
5722
5753
            sigaddset(&set, target_to_host_signal(sig));
5723
5754
 
5724
5755
        /* block signals in the handler using Linux */
 
5756
        sigdelset(&set, SIGSEGV);
5725
5757
        sigprocmask(SIG_BLOCK, &set, &old_set);
5726
5758
        /* save the previous blocked signal state to restore it at the
5727
5759
           end of the signal execution (see do_sigreturn) */