簡體   English   中英

Linux內核中的頁面錯誤

[英]Page Fault in Linux Kernel

閱讀Mel Gorman的書《 Understanding the Linux Virtual Memory Manager 》后,我有幾個問題。 4.3 Process Address Space Descriptor4.3 Process Address Space Descriptorkernel threads never page fault or access the user space portion. The only exception is page faulting within the vmalloc space kernel threads never page fault or access the user space portion. The only exception is page faulting within the vmalloc space 以下是我的問題。

  1. kenrel 線程從不缺頁:這是否意味着只有用戶空間代碼會觸發缺頁錯誤? 如果調用了kmalloc()vmalloc() ,它不會出現頁面錯誤嗎? 我相信內核必須將這些映射到匿名頁面。 當對該頁執行寫操作時,會發生頁錯誤。 我的理解正確嗎?

  2. 為什么內核線程不能訪問用戶空間? copy_to_user()copy_from_user()不是這樣做的嗎?

  3. Exception is page faulting within vmalloc space :這是否意味着vmalloc()會觸發頁面錯誤而kmalloc()不會? 為什么kmalloc()不會出現頁面錯誤? 內核虛擬地址的物理幀不需要作為頁表條目保留嗎?

  1. 內核線程永遠不會出現頁面錯誤:所討論的頁面錯誤是在使虛擬頁面駐留或從交換中恢復時。 內核頁面不僅在 kmalloc() 上被分頁,而且在它們的一生中都保持常駐。 對於用戶空間頁面而言,情況並非如此,A) 可能是延遲分配的(即僅保留為 malloc() 上的頁表條目,但在 memset() 或其他取消引用之前實際上不會出現故障)和 B) 可能會被交換在內存不足的情況下。

  2. 為什么內核線程不能訪問用戶空間? copy_to_user() 或 copy_from_user() 不是這樣做的嗎?

這是一個很好的問題,有特定於硬件的答復。 過去的情況是不鼓勵內核線程訪問用戶空間,正是因為可能發生頁面錯誤命中,如果訪問用戶空間中的未分頁/分頁內存(回想一下,這不會發生在內核空間中,如上所述確保)。 所以 copy_to/from 將是正常的 memcpy,但包裝在頁面錯誤處理程序中。 這樣,任何潛在的頁面錯誤都將被透明處理(即內存將被調入)並且一切都會好起來。 但是在某些情況下,memcpy 到/從用戶內存的糟糕方法會起作用 - 更糟糕的是,它會經常起作用,因為頁面錯誤與 RAM 駐留和可用性非常相關 - 因此未處理的錯誤會導致隨機恐慌。 因此,始終使用 copy_from/to_user 的法令。

然而,最近,從安全的角度來看,內核/用戶內存隔離變得很重要。 這是由於許多利用技術(空指針解引用是一種非常常見且功能強大的技術),其中可以在用戶空間(因此易於控制)內存中構造偽造的內核對象(或代碼),並可能導致代碼在核心。

因此,大多數體系結構都有一個頁表位,它在物理上防止內核訪問屬於用戶模式的頁面。 以ARM64為例,這個特性叫做PAN/PXN(Privileged Access/Execute Never)。

因此,copy_from/to 現在不僅處理頁面錯誤,還在操作前禁用 PAN/PXN,並在操作后恢復它。

  1. 例外是 vmalloc 空間內的頁面錯誤:vmalloc() 分配可交換的內存,而 kmalloc 則不是。 不同之處在於實現(kmalloc 使用 GFP_KERNEL)。 這也意味着 kmalloc 更有可能失敗(如果沒有可用的 RAM),但不會出現頁面錯誤(它會返回 NULL,這本身就是一個問題..)

我認為您會感到困惑,因為您對內核、進程和虛擬內存的啟動還沒有清楚地了解。

  1. kenrel 線程從不缺頁:這是因為內核空間和用戶空間的頁面使用不同的分配方法。 對於內核空間,我們在初始化時分配頁面,而對於用戶空間,我們在運行進程和調用malloc()等函數時分配它們,映射后,當真正使用該虛擬內存時,我們會觸發頁面錯誤。

  2. 為什么內核線程不能訪問用戶空間? kenrel啟動時,進程0會創建進程1和進程2。進程1用於形成用戶空間進程樹,進程2用於管理內核線程。 你提到的函數總是被那些用戶線程用來將數據傳入/傳出內核來實現一些功能,比如打開文件或套接字等。

  3. 異常是 vmalloc 空間內的頁面錯誤: vmalloc 空間不是函數vmalloc() ,它是內核內存空間中的一個區域,用於某些用作異常的動態內存分配。

暫無
暫無

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

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