2016-12-09 16 views
0

即使頁表項已存在,我也希望故意生成頁面錯誤。如何引發頁面錯誤

所以我清除了一個_PAGE_PRESENT位來產生頁面錯誤。

這裏的內核代碼我寫道:

pte = get_locked_pte(mm, addr, &ptl); 
entry = *pte; 
entry = pte_clear_flags(entry, _PAGE_PRESENT); 
set_pte_at(mm, addr, pte, entry); 
pte_unmap_unlock(pte, ptl); 
flush_tlb_range(vma, vma->vm_start, vma->vm_end); 

但是,此代碼不能正常工作。我打算的頁面錯誤不會發生。我想知道如何觸發頁面錯誤。

謝謝。

+0

你想編寫內核代碼,或用戶的土地代碼? –

+1

你正在編寫內核代碼來跳轉用戶代碼中的頁面錯誤嗎? – jxh

+0

上面的代碼是內核代碼。在上面的代碼中,「addr」是用戶空間的地址。 –

回答

0

@Jungsik財,當你設置頁面存在損壞你的頁表項不存在旗,其實改變一個標誌,不存在顯示什麼都不做,只是改變了標誌。所以你的網頁實際上仍然存在。通過以這種方式設置NOT PRESENT標誌,您將損壞PTE,而不會導致頁面錯誤。

如果你想觀察頁面錯誤,你需要強制讀取磁盤。下面的代碼映射命令行給出的文件,告訴內核它不需要它;如果該文件是足夠大,(接在/ usr/bin中一個大的文件),您總能獲得主要頁面錯誤:

#include <fcntl.h> 
#include <stdio.h> 
#include <sys/mman.h> 
#include <sys/stat.h> 

int main(int argc, char ** argv) { 
    int fd = open(argv[1], O_RDONLY); 
    struct stat stats; 
    fstat(fd, &stats); 
    posix_fadvise(fd, 0, stats.st_size, POSIX_FADV_DONTNEED); 
    char * map = (char *) mmap(NULL, stats.st_size, PROT_READ, MAP_SHARED, fd, 0); 
    if (map == MAP_FAILED) { 
    perror("Failed to mmap"); 
    return 1; 
    } 
    int result = 0; 
    int i; 
    for (i = 0; i < stats.st_size; i++) { 
    result += map[i]; 
    } 
    munmap(map, stats.st_size); 
    return result; 
} 

沒有在錯誤處理的方式很多,這只是展示這個想法。在我的系統上,

gcc majorfault.c -o majorfault && /usr/bin/time -v ./majorfault /usr/bin/git-annex 

總是產生154個主要頁面錯誤。