Segmento de estado de tarefa - Task state segment

O segmento de estado de tarefa ( TSS ) é uma estrutura em computadores baseados em x86 que contém informações sobre uma tarefa . É usado pelo kernel do sistema operacional para gerenciamento de tarefas. Especificamente, as seguintes informações são armazenadas no TSS:

  • Estado de registro do processador
  • Permissões de porta de E / S
  • Ponteiros de pilha de nível interno
  • Link TSS anterior

Todas essas informações devem ser armazenadas em locais específicos dentro do TSS, conforme especificado nos manuais IA-32 .

Localização do TSS

O TSS pode residir em qualquer lugar da memória . Um registro de segmento denominado registro de tarefa (TR) contém um seletor de segmento que aponta para um descritor de segmento TSS válido que reside no GDT (um descritor TSS pode não residir no LDT ). Portanto, para usar um TSS, o seguinte deve ser feito pelo kernel do sistema operacional:

  1. Crie uma entrada de descritor TSS no GDT
  2. Carregue o TR com o seletor de segmento para esse segmento
  3. Adicione informações ao TSS na memória conforme necessário

Por motivos de segurança, o TSS deve ser colocado em uma memória acessível apenas para o kernel .

Registro de tarefas

O registro TR é um registro de 16 bits que contém um seletor de segmento para o TSS. Ele pode ser carregado por meio da instrução LTR . LTR é uma instrução privilegiada e atua de maneira semelhante a outras cargas de registro de segmento. O registro da tarefa tem duas partes: uma parte visível e acessível ao programador e uma invisível que é carregada automaticamente do descritor TSS.

Registrar estados

O TSS pode conter valores salvos de todos os registros x86 . Isso é usado para alternar tarefas . O sistema operacional pode carregar o TSS com os valores dos registros que a nova tarefa precisa e depois de executar uma troca de tarefa de hardware (como com uma instrução IRET ) a CPU x86 carregará os valores salvos do TSS nos registros apropriados. Observe que alguns sistemas operacionais modernos, como Windows e Linux , não usam esses campos no TSS, pois implementam a alternância de tarefas de software.

Observe que durante uma troca de tarefa de hardware, certos campos do antigo TSS são atualizados com o conteúdo do registro atual da CPU antes que os valores do novo TSS sejam lidos. Assim, alguns campos do TSS são de leitura / gravação, enquanto outros são somente leitura:

  • Campos de leitura / gravação : lidos e escritos durante uma troca de tarefa de hardware.
    • Todos os registradores de uso geral ( EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP);
    • Todos os registradores de segmento ( CS, DS, ES, FS, GS, SS);
    • Estado de execução atual ( EIP, EFlags);
    • O Linkcampo no novo TSS, se a troca de tarefa foi devido a CALLou em INTvez de a JMP.
  • Campos somente leitura: somente leitura quando necessário, conforme indicado.
    • Control Register 3 ( CR3), também conhecido como Page Directory Base Register ( PDBR).
      Leia durante uma troca de tarefa de hardware.
    • O registro da Tabela do descritor local ( LDTR);
      Leia durante uma troca de tarefa de hardware.
    • Os pares pilha de três nível de privilégio ( SS0:ESP0, SS1:ESP1, SS2:ESP2);
      Leia durante um inter-nível CALLou INTpara estabelecer uma nova pilha.
    • O ponteiro IO Port Bitmap ( IOPB) e o próprio I / O Port Bitmap;
      Leia durante uma IN, OUT, INSou OUTSinstrução se CPL > IOPLpara confirmar a instrução é legal (ver permissões Porta I / O abaixo).

O PDBRcampo é de fato o primeiro a ser lido do novo TSS: como uma chave de tarefa de hardware também pode mudar para um mapeamento de tabela de página completamente diferente, todos os outros campos (especialmente o LDTR) são relativos ao novo mapeamento.

Permissões de porta de E / S

O TSS contém um ponteiro de 16 bits para o bitmap de permissões da porta de E / S para a tarefa atual . Esse bitmap, geralmente configurado pelo sistema operacional quando uma tarefa é iniciada, especifica portas individuais às quais o programa deve ter acesso. O bitmap de E / S é uma matriz de bits de permissões de acesso à porta; se o programa tiver permissão para acessar uma porta, um "0" será armazenado no índice de bits correspondente e, se o programa não tiver permissão, um "1" será armazenado lá. Se o limite do segmento TSS for menor do que o bitmap completo, todos os bits ausentes serão considerados "1".

O recurso opera da seguinte forma: quando um programa emite uma instrução de porta de E / S x86, como IN ou OUT (consulte as listagens de instruções x86 - e observe que existem versões de comprimento de byte, palavra e dword), o hardware fará um Verifique o nível de privilégio de E / S (IOPL) para ver se o programa tem acesso a todas as portas de E / S. Se o nível de privilégio atual (CPL) do programa for numericamente maior do que o nível de privilégio I / O (IOPL) (o programa é menos privilegiado do que o que o IOPL especifica), o programa não tem acesso à porta I / O para todos portas. O hardware irá então verificar o bitmap de permissões de E / S no TSS para ver se aquele programa pode acessar a (s) porta (s) específica (s) na instrução IN ou OUT. Se (todos os) bit (s) relevantes (s) no bitmap de permissões da porta de E / S estiver / estão limpos, o programa tem permissão para acessar a (s) porta (s) e a instrução pode ser executada. Se (qualquer um) o (s) bit (s) relevante (s) está (m) definido (s) - ou se (qualquer um) o (s) bit (s) ultrapassou o limite do segmento TSS - o programa não tem acesso e o processador gera uma proteção geral culpa . Este recurso permite que os sistemas operacionais concedam acesso seletivo à porta para programas do usuário.

Ponteiros de pilha de nível interno

O TSS contém 6 campos para especificar o novo ponteiro da pilha quando ocorre uma mudança no nível de privilégio. O campo SS0 contém o seletor de segmento de pilha para CPL = 0 e o campo ESP0 / RSP0 contém o novo valor ESP / RSP para CPL = 0. Quando uma interrupção acontece no modo protegido (32 bits), a CPU x86 procura no TSS por SS0 e ESP0 e carrega seus valores em SS e ESP respectivamente. Isso permite que o kernel use uma pilha diferente do programa do usuário e também que essa pilha seja exclusiva para cada programa do usuário.

Um novo recurso introduzido nas extensões AMD64 é chamado de Interrupt Stack Table (IST), que também reside no TSS e contém ponteiros de pilha lógicos (segmento + deslocamento). Se uma tabela de descritor de interrupção especifica uma entrada IST a ser usada (são 8), o processador carregará a nova pilha do IST. Isso permite que pilhas em boas condições sejam usadas em caso de erros graves ( NMI ou falha dupla, por exemplo). Anteriormente, a entrada para a exceção ou interrupção no IDT apontava para uma porta de tarefa, fazendo com que o processador mudasse para a tarefa apontada pela porta de tarefa. Os valores de registro originais foram salvos na corrente TSS no momento em que a interrupção ou exceção ocorreu. O processador então define os registros, incluindo SS: ESP, com um valor conhecido especificado no TSS e salva o seletor no TSS anterior. O problema aqui é que a troca de tarefas de hardware não é suportada no AMD64.

Link TSS anterior

Este é um seletor de 16 bits que permite vincular este TSS ao anterior. Isso é usado apenas para alternar tarefas de hardware. Consulte os manuais IA-32 para obter detalhes.

Uso de TSS no Linux

Embora um TSS possa ser criado para cada tarefa em execução no computador, o kernel do Linux cria apenas um TSS para cada CPU e o usa para todas as tarefas. Essa abordagem foi selecionada porque fornece portabilidade mais fácil para outras arquiteturas (por exemplo, a arquitetura AMD64 não oferece suporte a switches de tarefa de hardware) e melhor desempenho e flexibilidade. O Linux usa apenas o bitmap de permissão de porta de E / S e recursos de pilha interna do TSS; os outros recursos são necessários apenas para alternância de tarefas de hardware, que o kernel do Linux não usa.

Exceções relacionadas ao TSS

O vetor de exceção x86 10 é chamado de exceção TSS inválida (#TS). Ele é emitido pelo processador sempre que algo dá errado com o acesso ao TSS. Por exemplo, se uma interrupção ocorre em CPL = 3 e está transferindo o controle para CPL = 0, o TSS é usado para extrair SS0 e ESP0 / RSP0 para o switch de pilha. Se o registro de tarefa contém um seletor TSS incorreto, uma falha #TS será gerada. A exceção de TSS inválida nunca deve ocorrer durante a operação normal do sistema operacional e está sempre relacionada a bugs do kernel ou falha de hardware.

Para obter mais detalhes sobre as exceções do TSS, consulte o Volume 3a, Capítulo 6 do manual IA-32 .

TSS no modo x86-64

A arquitetura x86-64 não oferece suporte a switches de tarefa de hardware. No entanto, o TSS ainda pode ser usado em uma máquina em execução nos modos estendidos de 64 bits. Nestes modos, o TSS ainda é útil, pois armazena:

  1. Os endereços do ponteiro da pilha para cada nível de privilégio.
  2. Endereços de ponteiro para a tabela de pilha de interrupção (a seção de ponteiro de pilha de nível interno acima discute a necessidade disso).
  3. Endereço de deslocamento do bitmap de permissão IO.

Além disso, o registro de tarefa é expandido nesses modos para poder conter um endereço de base de 64 bits.

Referências

links externos