簡體   English   中英

為什么在ARM Linux內核上不為vmalloc填寫頁面錯誤中的PTE條目?

[英]Why doesn't fill the PTE entry in page fault for vmalloc on ARM Linux Kernel?

當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 }

此范圍是為使用vmalloc分配的內核內存保留的。

禁用IRQ(軟或硬)並且無法處理頁面錯誤時,通常可以訪問內核內存。
vmalloc函數需要事先創建映射,因此訪問不會有任何錯誤。
如果存在錯誤,那是因為訪問是對未分配(或已釋放)的內存的訪問,因此無法處理。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM