コード例 #1
0
void bus_handler(int sig, struct siginfo *si, struct uml_pt_regs *regs)
{
	if (current->thread.fault_catcher != NULL)
		UML_LONGJMP(current->thread.fault_catcher, 1);
	else
		relay_signal(sig, si, regs);
}
コード例 #2
0
ファイル: trap.c プロジェクト: liuyang201666/linux-akae
/*
 * We give a *copy* of the faultinfo in the regs to segv.
 * This must be done, since nesting SEGVs could overwrite
 * the info in the regs. A pointer to the info then would
 * give us bad data!
 */
unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user,
                   struct uml_pt_regs *regs)
{
    struct siginfo si;
    jmp_buf *catcher;
    int err;
    int is_write = FAULT_WRITE(fi);
    unsigned long address = FAULT_ADDRESS(fi);

    if (!is_user && (address >= start_vm) && (address < end_vm)) {
        flush_tlb_kernel_vm();
        return 0;
    }
    else if (current->mm == NULL) {
        show_regs(container_of(regs, struct pt_regs, regs));
        panic("Segfault with no mm");
    }

    if (SEGV_IS_FIXABLE(&fi) || SEGV_MAYBE_FIXABLE(&fi))
        err = handle_page_fault(address, ip, is_write, is_user,
                                &si.si_code);
    else {
        err = -EFAULT;
        /*
         * A thread accessed NULL, we get a fault, but CR2 is invalid.
         * This code is used in __do_copy_from_user() of TT mode.
         * XXX tt mode is gone, so maybe this isn't needed any more
         */
        address = 0;
    }

    catcher = current->thread.fault_catcher;
    if (!err)
        return 0;
    else if (catcher != NULL) {
        current->thread.fault_addr = (void *) address;
        UML_LONGJMP(catcher, 1);
    }
    else if (current->thread.fault_addr != NULL)
        panic("fault_addr set but no fault catcher");
    else if (!is_user && arch_fixup(ip, regs))
        return 0;

    if (!is_user) {
        show_regs(container_of(regs, struct pt_regs, regs));
        panic("Kernel mode fault at addr 0x%lx, ip 0x%lx",
              address, ip);
    }

    if (err == -EACCES) {
        si.si_signo = SIGBUS;
        si.si_errno = 0;
        si.si_code = BUS_ADRERR;
        si.si_addr = (void __user *)address;
        current->thread.arch.faultinfo = fi;
        force_sig_info(SIGBUS, &si, current);
    } else if (err == -ENOMEM) {
        printk(KERN_INFO "VM: killing process %s\n", current->comm);
        do_exit(SIGKILL);
    } else {
        BUG_ON(err != -EFAULT);
        si.si_signo = SIGSEGV;
        si.si_addr = (void __user *) address;
        current->thread.arch.faultinfo = fi;
        force_sig_info(SIGSEGV, &si, current);
    }
    return 0;
}
コード例 #3
0
ファイル: trap.c プロジェクト: ivucica/linux
void do_longjmp(void *b, int val)
{
	jmp_buf *buf = b;

	UML_LONGJMP(buf, val);
}