Uma falha de página ocorre quando um acesso à memória falha porque a consulta da MMU para o endereço virtual terminou em um descritor inválido ou em um descritor indicando uma falta de permissões (por exemplo, tentativa de gravação para uma página somente leitura). Quando ocorre uma falha de página, o processador executa algumas ações; os detalhes são específicos para cada arquitetura de processador, mas a essência é a mesma:
- Mude para um modo privilegiado (por exemplo, modo kernel).
- Defina alguns registros para indicar, pelo menos, a natureza da falha e o modo de contador de programa e processador no ponto da falha.
- Ir para um endereço específico na memória, indicado por um registrador ou ele mesmo olhou para um local específico na memória: o endereço do manipulador de falhas da página.
Para dar um exemplo, em um processador ARM (32 bits):
- O registro
dfsr
é definido para um valor que descreve a falha (seja devido a uma leitura ou gravação, a uma instrução do processador ou a um DMA, etc.). - O registro
dfar
é definido para o endereço virtual que foi o destino do acesso que causou a falha. - O processador alterna para o modo de aborto (um dos modos privilegiados no nível do kernel
- O
lr
register está configurado para o contador de programa no momento da falha, e ospsr
register está configurado para o registrador de status do programa (cpsr
, o que contém os bits de modo, entre outras coisas ) no momento da falha. - Os registros
sp
ecpsr
são armazenados: eles são restaurados do último valor definido no modo de aborto. - A execução vai para o vetor de interrupção, um dos vetores de exceção .
O código do manipulador de falhas de página faz parte do kernel do sistema operacional. Sua tarefa é analisar a causa da falha e fazer algo a respeito. Pode consultar os registros de finalidade especial que fornecem informações sobre a natureza da falha e, se necessário, também pode inspecionar a instrução de que o programa estava sendo executado. Ele também pode procurar o descritor na tabela MMU; os descritores inválidos podem, às vezes, codificar informações, como a localização de uma página no espaço de troca. O kernel sabe qual tarefa está executando no momento, observando o valor de uma variável global ou registrando que ela é atualizada em cada switch de contexto. Aqui estão alguns comportamentos comuns em uma falha de página:
- Os dados sobre os mapeamentos de memória do processo indicam que a página está em troca. O kernel encontra uma página física extra, ou obtém uma removendo uma página que continha cache de disco, ou obtém uma salvando seu conteúdo para swap. Em seguida, ele carrega os dados do swap para essa página física e altera a tabela MMU para que o endereço virtual que causou a falha agora esteja conectado a essa página física no mapa da MMU do processo. Finalmente, o kernel organiza para voltar ao processo no ponto da instrução que causou a falha; desta vez a instrução será executada com sucesso.
- Os dados sobre os mapeamentos de memória do processo indicam que a página é uma página de cópia na gravação e que um acesso de gravação foi tentado. De maneira semelhante ao caso anterior, o kernel obtém uma página física de reserva, copia dados para ela (aqui, da página que era somente leitura), altera o descritor de MMU e organiza o processo para executar a instrução novamente.
- Os dados sobre os mapeamentos de memória do processo indicam que a página não está mapeada ou que não possui as permissões necessárias. Nesse caso, o kernel entrega um sinal SIGSEGV (falha de segmentação) ao processo: a execução do processo é retomada no manipulador de sinal, e não no local original, mas o local original é salvo na pilha. Se o processo não tiver manipulador para o SIGSEGV, ele será finalizado.
Não é possível determinar que uma exceção está prestes a acontecer, exceto conhecendo a configuração da memória virtual e fazendo verificações antes dos acessos à memória. O fluxo normal de operação é que o motivo da falha da página é registrado pelo processador quando a falha da página acontece.