linux-kernel arm mmu

linux kernel - ¿Cómo emula ARM Linux los bits sucios, accedidos y de archivo de un PTE?



linux-kernel mmu (1)

Según pgtable-2-level.h , ARM Linux tiene dos versiones de PTE; El PTE de Linux y H / W PTE. Los PTE de Linux se almacenan debajo de un desplazamiento de 1024 bytes.

Cuando maneje la falla de la página en handle_pte_fault varias funciones como pte_file , pte_mkdirty , pte_mkyoung , invoque con la versión H / W PTE.

Pero en realidad ARM H / W no admite el bit sucio, al que se accede y el archivo en su PTE.

Mi pregunta es ¿cómo verifica el bit de archivo sucio y al que se accede de una página en PTE H / W? ¿Idealmente debería verificar esos bits en PTE de Linux que están almacenados debajo de un desplazamiento de 1024 bytes?


Mi pregunta es ¿cómo verifica el bit de archivo sucio y al que se accede de una página en PTE H / W?

TL; DR: se emulan al tomar un error de página en los accesos iniciales.

Las respuestas se dan en pgtable-2-level.h ,

El bit "sucio" se emula otorgando solo permiso de escritura de hardware si la página está marcada como "grabable" y "sucia" en el PTE de Linux. Esto significa que una escritura en una página limpia provocará un error de permiso, y la capa MM de Linux marcará la página como sucia a través de handle_pte_fault (). Para que el hardware note el cambio de permiso, la entrada TLB debe ser vaciada, y ptep_set_access_flags () lo hace por nosotros.

Para tomar el caso sucio , las asignaciones iniciales de MMU para la página están marcadas como de solo lectura. Cuando un proceso escribe en él, se genera un error de página. Este es el handle_pte_fault referenciado y el código principal está en fault.c como do_page_fault y llamará al handle_mm_fault genérico que finalmente termina en handle_pte_fault . Puedes ver el código,

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. **/ }

Por lo tanto, el código genérico de Linux examinará el permiso de la página, verá que se supone que se puede escribir y llame al pte_mkdirty para marcar la página como sucia; todo el proceso se inicia o se emula a través del controlador de fallas. Después de que la página se marca sucia en el PTE de Linux, el PTE de ARM se marca como grabable para que las escrituras posteriores no causen un error.

el acceso es idéntico, solo tanto la lectura como la escritura fallarán inicialmente. Un bit de archivo también está completamente sin asignar y cuando ocurre una falla, se consulta al PTE de Linux para ver si está respaldado por un archivo o si es una falla de página completamente sin asignar .

Una vez que la tabla de hardware se actualiza con nuevos permisos y se lleva a cabo la contabilidad, el programa de modo de usuario se reinicia en la instrucción de falla y no notará la diferencia, además del intervalo de tiempo para manejar la falla.

ARM Linux utiliza páginas de 4k y las tablas de páginas de segundo nivel de ARM tienen un tamaño de 1k (256 entradas * 4bytes). De los comentarios de pgtable-2-level.h ,

Por lo tanto, modificamos ligeramente la implementación: le decimos a Linux que tenemos 2048 entradas en el primer nivel, cada una de las cuales tiene 8 bytes (iow, dos punteros de hardware al segundo nivel). El segundo nivel contiene dos tablas PTE de hardware dispuestas contiguamente, precedido por versiones de Linux que contienen la información de estado que Linux necesita. Por lo tanto, terminamos con 512 entradas en el nivel "PTE".

Para usar la página 4K completa, las entradas PTE están estructuradas de la siguiente manera:

  1. PTE de Linux [n]
  2. PTE de Linux [n + 1]
  3. BRAZO PTE [n]
  4. BRAZO PTE [n + 1]

Cuatro artículos de 1k para una página completa de 4k. Estas colecciones de páginas deben administrarse por proceso para dar a cada una una vista única de la memoria y cierta información se comparte para conservar la RAM real. La función cpu_set_pte_ext se usa para cambiar las entradas ARM físicas. Como cada revisión de CPU ARM utiliza estructuras y características de tablas ligeramente diferentes, hay una entrada en la tabla de funciones del procesador que apunta a una rutina de ensamblador. Por ejemplo, cpu_v7_set_pte_ext es el ARMv7 o la implementación original típica de la CPU Cortex. Esta rutina es responsable de examinar los indicadores de Linux y actualizar los bits de hardware en consecuencia. Como se puede ver, el r3 se escribe en pte+2048 (desplazamiento de PTE de Linux a PTE de hardware) al final de esta rutina. La macro ensambladora armv3_set_pte_ext en proc-marcos.S es utilizada por muchas de las variantes de CPU más antiguas.

Ver: notas de Tim sobre ARM MM
Descriptor de entrada de tabla de página (PTE) en el kernel de Linux para ARM