当VMALLOC_START~VMALLOC_END发生页面错误时,为什么do_translation_fault不会填充Page表项并只填充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 }
答案 0 :(得分:0)
此范围保留给内核内存,使用vmalloc
分配。
当禁用IRQ(软或硬)时,通常会访问内核内存,并且无法处理页面错误。
vmalloc
函数需要提前创建映射,因此访问时不会出现错误
如果出现故障,那是因为访问是未分配(或被释放)的内存,因此无法处理。