Os VMAs contêm os endereços virtuais dos primeiros e (um após o) último bytes:
struct vm_area_struct {
/* The first cache line has the info for VMA tree walking. */
unsigned long vm_start; /* Our start address within vm_mm. */
unsigned long vm_end; /* The first byte after our end address
within vm_mm. */
...
Isso significa que, para obter os dados da página, você precisa primeiro descobrir em qual contexto seu código está sendo executado?
Se estiver dentro do contexto do processo, uma simples abordagem copy_from_user
pode ser suficiente para obter os dados reais e uma página (através da totalidade do seu PGD / PUD / PMD / PTE) para obter o PFN e, em seguida, para um struct page
. (Cuidado não para usar o sedutor virt_to_page(addr)
, pois isso só funcionará nos endereços do kernel).
Em termos de iteração, você precisa apenas iterar em PAGE_SIZEs, sobre os endereços virtuais obtidos dos VMAs.
Note que isto assume que as páginas são realmente mapeadas. Se não ( !pte_present(pte_t a)
) você pode precisar remapear você mesmo para acessar os dados.
Se a sua verificação estiver sendo executada em algum outro contexto (como um kthread / interrupt), você deve remapear a página do swap antes de acessá-la, o que é um caso totalmente diferente. Se você quiser o caminho mais fácil, eu procuraria aqui: link para entender como para lidar com pesquisa / recuperação de trocas.