Cuándo hacer o no hacer INVLPG, MOV a CR3 para minimizar el enjuague TLB

Prólogo

Soy un aficionado a los sistemas operativos, y mi kernel se ejecuta en 80486+, y ya es compatible con la memoria virtual.

A partir de 80386, la familia de procesadores x86 de Intel y varios clones de los mismos han admitido la memoria virtual con paginación. Es bien sabido que cuando elPG mordióCR0 está configurado, el procesador utiliza la traducción de direcciones virtuales. Entonces laCR3 el registro apunta al directorio de la página de nivel superior, que es la raíz de 2-4 niveles de estructuras de tablas de páginas que asignan las direcciones virtuales a direcciones físicas.

El procesador no consulta estas tablas para cada dirección virtual generada, sino que las almacena en caché en una estructura llamadaTraducción Lookaside Buffero TLB. Sin embargo, cuando se realizan cambios en las tablas de páginas, es necesario vaciar el TLB. En los procesadores 80386, esta descarga se realizaría recargando (MOV) CR3 con la dirección del directorio de la página de nivel superior o un cambio de tarea. Esto supuestamente elimina todas las entradas TLB incondicionalmente. Según tengo entendido, sería perfectamente válido para un sistema de memoria virtualsiempre recarga CR3 despuésalguna cambio.

Esto es un desperdicio, ya que el TLB ahora arrojaría entradas completamente buenas, por lo tanto, en los procesadores 80486 elINVLPG Se introdujo la instrucción.INVLPG invalidará la entrada TLB que coincida con la dirección del operando de origen.

Sin embargo, comenzando con Pentium Pro, también tenemos páginas globales que no se enjuagan con los movimientos aCR3 o cambio de tarea; y AMD x86-64 ISA dice que algunas estructuras de tablas de páginas de nivel superior pueden almacenarse en caché y no ser invalidadas porINVLPG. Para obtener una imagen coherente de lo que se necesita y lo que no se necesita en cada ISA, uno realmente necesitaría descargar una hoja de datos de 1000 páginas para una multitud de ISA lanzadas desde los años 80 para leer un par de páginas, e incluso entonces los documentos parecen sea particularmente vago en cuanto a la invalidación de TLB y lo que sucede si el TLB no se invalida correctamente.

Pregunta

Por simplicidad, se puede suponer queestamos hablando de un sistema uniprocesador. Además, se puede suponer queno se requiere un cambio de tarea después de cambiar las estructuras de la página. (asíINVLPG supuestamente siempre es al menos tan buena opción como recargar elCR3 registro).

La suposición básica es que sería necesario volver a cargarCR3 después de cada cambio en las tablas de páginas y directorios de páginas, y dicho sistema sería correcto. Sin embargo, si uno quiere evitar vaciar innecesariamente el TLB, necesita respuestas a las 2 preguntas:

Siempre queINVLPG es compatible con ISA, después de qué tipo de cambios se puede usar de forma segura en lugar de volver a cargar elCR3? P.ej. "Si uno desasigna un marco de página (establece la entrada de la tabla correspondiente como no presente), siempre se puede usarINVLPG"?

¿Qué tipo de cambios se pueden hacer a las tablas y directorios sin tocar ninguno?CR3 o ejecutandoINVLPG? P.ej. "Si una página no está asignada (no está presente), se puede escribir un PTE conPresent=1 para ello sin enjuagar el TLB en absoluto "?

Incluso después de leer una gran cantidad de documentos ISA y todo lo relacionado conINVLPG aquí en Stack Overflow no estoy personalmente seguro de ninguno de los ejemplos que presenté allí. De hecho, unopublicación notable Lo afirmó de inmediato: "No sé exactamente cuándo debe usarlo y cuándo no". Por lo tanto, cualquier ejemplo correcto y correcto, preferiblemente documentado, y para IA32 o x86-64, que pueda dar, es apreciado.

Respuestas a la pregunta(0)

Su respuesta a la pregunta