Chinaunix

标题: arm do_page_fault问题 [打印本页]

作者: blake326    时间: 2013-03-29 10:01
标题: arm do_page_fault问题
看了两行就搞不定了。

do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
{
。。。
        /*
         * If we're in an interrupt or have no user
         * context, we must not take the fault..
         */
        if (in_atomic() || !mm)
                goto no_context;
。。。
no_context:
        __do_kernel_fault(mm, addr, fsr, regs);
        return 0;
}

static void
__do_kernel_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr,
                  struct pt_regs *regs)
{
        /*
         * Are we prepared to handle this kernel fault?
         */
        if (fixup_exception(regs))
                return;

        /*
         * No handler, we'll have to terminate things with extreme prejudice.
         */
        bust_spinlocks(1);
        printk(KERN_ALERT
                "Unable to handle kernel %s at virtual address %08lx\n",
                (addr < PAGE_SIZE) ? "NULL pointer dereference" :
                "paging request", addr);

        show_pte(mm, addr);
        die("Oops", regs, fsr);
        bust_spinlocks(0);
        do_exit(SIGKILL);
}


缺页异常,如果内核处于内核线程,中断,软中断,或者禁止抢占的话。直接进no_context。


no_context首先fixup_exeception(), 应该是修复 由于把某个用户线性地址作为系统调用的参数传进内核的 问题。
如果修复不了的话,则panic



我的问题是:
1. 相对于x86上的vmalloc_fault分支肿么没有了,vmalloc调用只会在主内核页表建立映射(c0004000)。那么内核在in_atomic或者内核线程中如果访问到了vmalloc的地址(arm好像都是用的另外一个ttbr来的,反正不是c0004000),产生了异常怎样修复。
2. 在no_context环境下进行fixup_exeception(), 如果说fixup_exeception(),是修复系统调用参数问题的话。那么,在中断状态下,就可能会要去分配page什么的引起调度。这个不合理吧。我看ulk3上说的,x86在非no_context情况下才会尝试fixup_exeception的,中断状态是不允许访问用户空间的。

作者: blake326    时间: 2013-03-29 16:49
没有人气啊。
作者: blake326    时间: 2013-04-01 14:59
顶一下死一个贪官。
作者: blake326    时间: 2013-04-02 10:20
cu没有高手。
作者: qtdszws    时间: 2013-07-16 17:40
你这个要贴版本是多少,否则没办法查
作者: longddr    时间: 2013-07-28 10:17
arm架构的vmalloc错误时另外一个handler:do_translation_fault:

/*
* First Level Translation Fault Handler
*
* We enter here because the first level page table doesn't contain
* a valid entry for the address.
*
* If the address is in kernel space (>= TASK_SIZE), then we are
* probably faulting in the vmalloc() area.
*
* If the init_task's first level page tables contains the relevant
* entry, we copy the it to this task.  If not, we send the process
* a signal, fixup the exception, or oops the kernel.
*
* NOTE! We MUST NOT take any locks for this case. We may be in an
* interrupt or a critical region, and should only copy the information
* from the master page table, nothing more.
*/
static int __kprobes
do_translation_fault(unsigned long addr, unsigned int fsr,
                     struct pt_regs *regs)
{
        unsigned int index;
        pgd_t *pgd, *pgd_k;
        pmd_t *pmd, *pmd_k;

        if (addr < TASK_SIZE)
                return do_page_fault(addr, fsr, regs);

        index = pgd_index(addr);

        /*
         * FIXME: CP15 C1 is write only on ARMv3 architectures.
         */
        pgd = cpu_get_pgd() + index;
        pgd_k = init_mm.pgd + index;

        if (pgd_none(*pgd_k))
                goto bad_area;

        if (!pgd_present(*pgd))
                set_pgd(pgd, *pgd_k);

        pmd_k = pmd_offset(pgd_k, addr);
        pmd   = pmd_offset(pgd, addr);

        if (pmd_none(*pmd_k))
                goto bad_area;

        copy_pmd(pmd, pmd_k);
        return 0;

bad_area:
        do_bad_area(addr, fsr, regs);
        return 0;
}
只是copy一下init mm中的内容,即使处于中断也不会引起切换。
x86也会在no_context是调用fixup_exception,应该fixup_exception不是你理解的那样吧,不会去alloc page,alloc  page只是在address合法的情况下,像这种都已经确定不合法了,还会去alloc page吗?fixup的作用只是确定不是内核代码写错了,是用户系统调用传错参数!
no_context:
        /* Are we prepared to handle this kernel fault?  */
        if (fixup_exception(regs))





欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2