In che modo ARM Linux emula i bit sporchi, accessibili e file di una PTE?

Come per pgtable-2-level.h , ARM Linux ha due versioni di PTE; PTE Linux e PTE H / W. Le PTE Linux sono memorizzate sotto un offset di 1024 byte.

Quando si gestisce l’errore di pagina in handle_pte_fault varie funzioni come pte_file , pte_mkdirty , pte_mkyoung , vengono richiamate con la versione H / W PTE.

Ma in realtà ARM H / W non supporta il bit sporco, accessibile e file nella sua PTE.

La mia domanda è: come controlla lo sporco, accesso, bit di una pagina su PTE H / W? Idealmente dovrebbe controllare quei bit su Linux PTE che sono memorizzati sotto un offset di 1024 byte?

    La mia domanda è: come controlla lo sporco, accesso, bit di una pagina su PTE H / W?

    TL; DR: vengono emulati rilevando un errore di pagina agli accessi iniziali.

    Le risposte sono date in pgtable-2-level.h ,

    Il bit “dirty” viene emulato solo concedendo il permesso di scrittura hardware se la pagina è contrassegnata come “scrivibile” e “dirty” nella PTE Linux. Ciò significa che scrivere su una pagina pulita causerà un errore di authorization e il livello MM Linux contrassegnerà la pagina sporca tramite handle_pte_fault (). Perché l’hardware noti la modifica del permesso, la voce TLB deve essere svuotata e ptep_set_access_flags () lo fa per noi.

    Per prendere il caso sporco , i mapping MMU iniziali per pagina sono contrassegnati come di sola lettura. Quando un processo scrive su di esso, viene generato un errore di pagina. Questo è il riferimento handle_pte_fault e il codice principale è in fault.c come do_page_fault e chiamerà il generico handle_mm_fault che alla fine termina con handle_pte_fault . Puoi vedere il codice,

     if (flags & FAULT_FLAG_WRITE) { if (!pte_write(entry)) return do_wp_page(mm, vma, address, pte, pmd, ptl, entry); entry = pte_mkdirty(entry); /** Here is the dirty emulation. **/ } 

    Quindi il codice generico di Linux esaminerà il permesso della pagina, si supponga che sia scrivibile e chiama pte_mkdirty per contrassegnare la pagina come sporca; l’intero processo viene avviato o emulato tramite il gestore degli errori. Dopo che la pagina è stata contrassegnata come dirty in PTE Linux, ARM PTE è contrassegnata come scrivibile in modo che le scritture successive non causino un errore.

    l’accesso è identico solo sia la lettura che la scrittura inizialmente si guastano. Un bit di file è anche completamente non mappato e quando si verifica un errore, viene consultata la PTE di Linux per verificare se è supportata da un file o si tratta di un errore di pagina completamente non mappato .

    Dopo che la tabella hardware è stata aggiornata con nuove autorizzazioni e il mantenimento della contabilità è stato eseguito, il programma in modalità utente viene riavviato nell’istruzione di errore e non si noterà la differenza, oltre all’intervallo di tempo per gestire l’errore.


    ARM Linux utilizza pagine 4k e le tabelle di pagina ARM di secondo livello hanno dimensioni di 1k (256 voci * 4 byte). Dai commenti pgtable-2-level.h ,

    Pertanto, modifichiamo leggermente l’implementazione – diciamo a Linux che abbiamo 2048 voci nel primo livello, ognuna delle quali è 8 byte (iow, due puntatori hardware al secondo livello.) Il secondo livello contiene due tabelle PTE hardware disposte in modo contiguo, preceduto da versioni di Linux che contengono le informazioni di stato di cui ha bisogno Linux. Pertanto, ci ritroviamo con 512 voci nel livello “PTE”.

    Per utilizzare la pagina 4K completa, le voci PTE sono strutturate come,

    1. Linux PTE [n]
    2. Linux PTE [n + 1]
    3. ARM PTE [n]
    4. ARM PTE [n + 1]

    Quattro articoli da 1k per una pagina completa di 4k. Queste raccolte di pagine devono essere gestite per processo per dare a ciascuna una visione unica della memoria e alcune informazioni sono condivise al fine di conservare la RAM reale. La funzione cpu_set_pte_ext viene utilizzata per modificare le voci fisiche di ARM. Poiché ogni revisione della CPU ARM utilizza strutture e caratteristiche di tabelle leggermente diverse, c’è una voce nella tabella delle funzioni del processore che punta a una routine assembler. Ad esempio, cpu_v7_set_pte_ext è l’ARMv7 o l’implementazione tipica della CPU Cortex originale. Questa routine è responsabile dell’esame dei flag di Linux e dell’aggiornamento dei bit hardware di conseguenza. Come si può vedere, la r3 è scritta su pte+2048 (offset da PTE Linux a PTE hardware) alla fine di questa routine. La macro assembler armv3_set_pte_ext in proc-marcos.S viene utilizzata da molte delle varianti CPU precedenti.

    Vedi: note di Tim su ARM MM
    Descrittore PTE (Page Table Entry) nel kernel Linux per ARM