es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Escribir a CR2 durante la ISR de PageFault.

Estoy escribiendo un controlador de falta de página y me pregunto qué sucede si el ISR cambia el valor de cr2 justo antes de que el ISR regrese.

Por ejemplo, si algún código hace esto:

mov rax, QWORD PTR [rip+0x23]
mov rbx, QWORD PTR [rax+0x28432]
movabs rax, 0xdeadbeefdeadbeef
mov rcx, QWORD PTR [rax]

Digamos que [rax+0x28432] tiene el bit Present en PTE establecido en 0. También asumamos que 0xdeadbeefdeadbeef apunta a una memoria válida pero paginada.

Suponiendo que el código es el ISR (esto es pseudocódigo):

PPTE pte = GetPteFromVA(__readcr2() & ~0xFFF);

/* Traer la página a memoria */

pte->Present = 1;

_writecr2(nuevoValor);
_asm
{
    add rsp, 8
    iretq
}

¿Qué sucederá de vuelta en el código? ¿La instrucción que carga rbx con un valor usará el valor actualizado de cr2 en su cálculo? ¿Qué sucederá al intentar cargar rcx con el valor al que rax está apuntando? ¿cr2 solo se usa para notificar al kernel de una dirección con falla? ¿O algo se romperá?

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    El cambio al registro cr2 realizado por el ISR será únicamente para el contexto del manejador de fallos de página. Una vez que el manejador devuelve el control al código, se restaurará el valor original de cr2. Por lo tanto, la instrucción que carga rbx con un valor seguirá utilizando el valor original de cr2 en su cálculo.

    Sin embargo, al intentar cargar rcx con el valor al que apunta rax, se producirá una excepción, ya que la dirección virtual 0xdeadbeefdeadbeef no está presente en la memoria y está paginada. Esto provocará otro fallo de página y dará lugar a que se llame nuevamente al manejador de fallos de página.

    En resumen, el registro cr2 solo se utiliza para notificar al kernel una dirección con errores y cambiar su valor en el ISR no afectará la ejecución del código después de que el manejador devuelva el control. Sin embargo, intentar acceder a una memoria paginada provocará un nuevo fallo de página y volverá a llamar al manejador de fallos de página.

Comments are closed.