- 论坛徽章:
- 0
|
这是KERNEL 6.2.13的do_page_fault. 我实验的就是这版本:
- ........
- do_sigbus:
- up_read(&mm->mmap_sem);
- /* Kernel mode? Handle exceptions or die */
- if (!(error_code & 4))
- goto no_context;
- /* User space => ok to do another page fault */
- if (is_prefetch(regs, address, error_code))
- return;
- tsk->thread.cr2 = address;
- tsk->thread.error_code = error_code;
- tsk->thread.trap_no = 14;
- info.si_signo = SIGBUS;
- info.si_errno = 0;
- info.si_code = BUS_ADRERR;
- info.si_addr = (void __user *)address;
- force_sig_info(SIGBUS, &info, tsk);
- return;
- vmalloc_fault:
- {
- /*
- * Synchronize this task's top level page-table
- * with the 'reference' page table.
- *
- * Do _not_ use "tsk" here. We might be inside
- * an interrupt in the middle of a task switch..
- */
- int index = pgd_index(address);
- unsigned long pgd_paddr;
- pgd_t *pgd, *pgd_k;
- pud_t *pud, *pud_k;
- pmd_t *pmd, *pmd_k;
- pte_t *pte_k;
- //printk("vmalloc_fault %p ii %d\n", address, in_interrupt());
- vmalloc_fault_count++;
- asm("movl %%cr3,%0":"=r" (pgd_paddr));
- pgd = index + (pgd_t *)__va(pgd_paddr);
- pgd_k = init_mm.pgd + index;
- if (!pgd_present(*pgd_k))
- goto no_context;
- /*
- * set_pgd(pgd, *pgd_k); here would be useless on PAE
- * and redundant with the set_pmd() on non-PAE. As would
- * set_pud.
- */
- pud = pud_offset(pgd, address);
- pud_k = pud_offset(pgd_k, address);
- if (!pud_present(*pud_k))
- ..................
复制代码
明显告诉了, vmalloc是通过page_fault的。 |
|