1

当VMALLOC_START~VMALLOC_END发生page fault时,为什么do_translation_fault不填Page table entry,只填PG、PUD和PMD?

arch/arm/mm/fault.c中对应的源代码@do_translation_fault:

414 static int __kprobes
415 do_translation_fault(unsigned long addr, unsigned int fsr,
416                      struct pt_regs *regs)
417 {
418         unsigned int index;
419         pgd_t *pgd, *pgd_k;
420         pud_t *pud, *pud_k;
421         pmd_t *pmd, *pmd_k;
422
423         if (addr < TASK_SIZE)
424                 return do_page_fault(addr, fsr, regs);
425
426         if (user_mode(regs))
427                 goto bad_area;
428
429         index = pgd_index(addr);
430
431         /*
432          * FIXME: CP15 C1 is write only on ARMv3 architectures.
433          */
434         pgd = cpu_get_pgd() + index;
435         pgd_k = init_mm.pgd + index;
436
437         if (pgd_none(*pgd_k))
438                 goto bad_area;
439         if (!pgd_present(*pgd))
440                 set_pgd(pgd, *pgd_k);
441
442         pud = pud_offset(pgd, addr);
443         pud_k = pud_offset(pgd_k, addr);
444
445         if (pud_none(*pud_k))
446                 goto bad_area;
447         if (!pud_present(*pud)) 
448                 set_pud(pud, *pud_k);
449
450         pmd = pmd_offset(pud, addr);
451         pmd_k = pmd_offset(pud_k, addr);
452
453 #ifdef CONFIG_ARM_LPAE
454         /*
455          * Only one hardware entry per PMD with LPAE.
456          */
457         index = 0;
458 #else
459         /*
460          * On ARM one Linux PGD entry contains two hardware entries (see page
461          * tables layout in pgtable.h). We normally guarantee that we always
462          * fill both L1 entries. But create_mapping() doesn't follow the rule.
463          * It can create inidividual L1 entries, so here we have to call
464          * pmd_none() check for the entry really corresponded to address, not
465          * for the first of pair.
466          */
467         index = (addr >> SECTION_SHIFT) & 1;
468 #endif
469         if (pmd_none(pmd_k[index]))
470                 goto bad_area;
471
472         copy_pmd(pmd, pmd_k);
473         return 0;
474
475 bad_area:
476         do_bad_area(addr, fsr, regs);
477         return 0;
478 }
4

1 回答 1

0

这个范围是为内核内存保留的,使用vmalloc.

通常在禁用 IRQ(软或硬)时访问内核内存,并且无法处理页面错误。
vmalloc函数负责提前创建映射,因此访问不会出错。
如果出现故障,那是因为访问的是未分配(或已释放)的内存,因此无法处理。

于 2012-06-18T13:04:47.667 回答