1*82da0f94SDaniel Pereira.. SPDX-License-Identifier: GPL-2.0 2*82da0f94SDaniel Pereira 3*82da0f94SDaniel Pereira======================================= 4*82da0f94SDaniel PereiraAdicionando uma Nova Chamada de Sistema 5*82da0f94SDaniel Pereira======================================= 6*82da0f94SDaniel Pereira 7*82da0f94SDaniel PereiraEste documento descreve o que está envolvido na adição de uma nova chamada de 8*82da0f94SDaniel Pereirasistema (system call) ao kernel Linux, indo além dos conselhos normais de 9*82da0f94SDaniel Pereirasubmissão em 10*82da0f94SDaniel Pereira:ref:`Documentation/process/submitting-patches.rst <submittingpatches>`. 11*82da0f94SDaniel Pereira 12*82da0f94SDaniel Pereira 13*82da0f94SDaniel PereiraAlternativas às Chamadas de Sistema 14*82da0f94SDaniel Pereira----------------------------------- 15*82da0f94SDaniel Pereira 16*82da0f94SDaniel PereiraA primeira coisa a se considerar ao adicionar uma nova chamada de sistema é se 17*82da0f94SDaniel Pereirauma das alternativas poderia ser mais adequada. Embora as chamadas de sistema 18*82da0f94SDaniel Pereirasejam os pontos de interação mais tradicionais e óbvios entre o espaço do 19*82da0f94SDaniel Pereirausuário (userspace) e o kernel, existem outras possibilidades -- escolha o que 20*82da0f94SDaniel Pereiramelhor se adapta à sua interface. 21*82da0f94SDaniel Pereira 22*82da0f94SDaniel Pereira - Se as operações envolvidas puderem ser moldadas para se parecerem com um 23*82da0f94SDaniel Pereira objeto do tipo arquivo, pode fazer mais sentido criar um novo sistema de 24*82da0f94SDaniel Pereira arquivos ou dispositivo. Isso também torna mais fácil encapsular a nova 25*82da0f94SDaniel Pereira funcionalidade em um módulo de kernel, em vez de exigir que ela seja 26*82da0f94SDaniel Pereira incorporada ao kernel principal. 27*82da0f94SDaniel Pereira 28*82da0f94SDaniel Pereira - Se a nova funcionalidade envolver operações em que o kernel notifica o 29*82da0f94SDaniel Pereira espaço do usuário de que algo aconteceu, retornar um novo descritor de 30*82da0f94SDaniel Pereira arquivo (file descriptor) para o objeto relevante permite que o espaço 31*82da0f94SDaniel Pereira do usuário use ``poll``/``select``/``epoll`` para receber essa 32*82da0f94SDaniel Pereira notificação. 33*82da0f94SDaniel Pereira - No entanto, as operações que não se mapeiam para operações do tipo 34*82da0f94SDaniel Pereira :manpage:`read(2)`/:manpage:`write(2)` precisam ser implementadas como 35*82da0f94SDaniel Pereira requisições :manpage:`ioctl(2)`, o que pode levar a uma API um tanto 36*82da0f94SDaniel Pereira quanto opaca. 37*82da0f94SDaniel Pereira 38*82da0f94SDaniel Pereira - Se você estiver apenas expondo informações do sistema em tempo de execução, 39*82da0f94SDaniel Pereira um novo nó no sysfs (veja ``Documentation/filesystems/sysfs.rst``) ou no 40*82da0f94SDaniel Pereira sistema de arquivos ``/proc`` pode ser mais apropriado. No entanto, o acesso 41*82da0f94SDaniel Pereira a esses mecanismos exige que o sistema de arquivos relevante esteja montado, 42*82da0f94SDaniel Pereira o que pode não ser sempre o caso (por exemplo, em um ambiente com namespaces, 43*82da0f94SDaniel Pereira sandboxed ou chrooted). Evite adicionar qualquer API ao debugfs, pois este 44*82da0f94SDaniel Pereira não é considerado uma interface de "produção" para o espaço do usuário. 45*82da0f94SDaniel Pereira - Se a operação for específica para um arquivo ou descritor de arquivo de um 46*82da0f94SDaniel Pereira determinado objeto, então uma opção de comando adicional para :manpage:`fcntl(2)` 47*82da0f94SDaniel Pereira pode ser mais adequada. Contudo, o :manpage:`fcntl(2)` é uma chamada de sistema 48*82da0f94SDaniel Pereira de multiplexação que oculta muita complexidade, portanto, esta opção é melhor 49*82da0f94SDaniel Pereira para quando a nova função for intimamente análoga à funcionalidade existente 50*82da0f94SDaniel Pereira do :manpage:`fcntl(2)`, ou se a nova funcionalidade for muito simples (por 51*82da0f94SDaniel Pereira exemplo, obter/definir uma flag simples relacionada a um descritor de arquivo). 52*82da0f94SDaniel Pereira - Se a operação for específica para uma tarefa (task) ou processo específico, 53*82da0f94SDaniel Pereira então uma opção de comando adicional para :manpage:`prctl(2)` pode ser mais 54*82da0f94SDaniel Pereira apropriada. Assim como no caso do :manpage:`fcntl(2)`, esta chamada de sistema 55*82da0f94SDaniel Pereira é um multiplexador complicado, sendo melhor reservá-la para análogos próximos 56*82da0f94SDaniel Pereira de comandos ``prctl()`` existentes ou para obter/definir uma flag simples 57*82da0f94SDaniel Pereira relacionada a um processo. 58*82da0f94SDaniel Pereira 59*82da0f94SDaniel Pereira 60*82da0f94SDaniel PereiraProjetando a API: Planejando a Extensibilidade 61*82da0f94SDaniel Pereira---------------------------------------------- 62*82da0f94SDaniel Pereira 63*82da0f94SDaniel PereiraUma nova chamada de sistema faz parte da API do kernel e deve ser suportada 64*82da0f94SDaniel Pereiraindefinidamente. Sendo assim, é uma excelente ideia discutir explicitamente a 65*82da0f94SDaniel Pereirainterface na lista de discussão do kernel (LKML), e é crucial planejar extensões 66*82da0f94SDaniel Pereirafuturas para essa interface. 67*82da0f94SDaniel Pereira 68*82da0f94SDaniel Pereira(A tabela de chamadas de sistema está repleta de exemplos históricos onde isso 69*82da0f94SDaniel Pereiranão foi feito, juntamente com as respectivas chamadas de sistema de acompanhamento 70*82da0f94SDaniel Pereira-- ``eventfd``/``eventfd2``, ``dup2``/``dup3``, ``inotify_init``/``inotify_init1``, 71*82da0f94SDaniel Pereira``pipe``/``pipe2``, ``renameat``/``renameat2`` -- portanto, aprenda com a história 72*82da0f94SDaniel Pereirado kernel e planeje as extensões desde o início.) 73*82da0f94SDaniel Pereira 74*82da0f94SDaniel PereiraPara chamadas de sistema mais simples que recebem apenas alguns argumentos, a 75*82da0f94SDaniel Pereiramaneira preferencial de permitir extensibilidade futura é incluir um argumento de 76*82da0f94SDaniel Pereiraflags na chamada de sistema. Para garantir que os programas do espaço do usuário 77*82da0f94SDaniel Pereirapossam usar flags de forma segura entre diferentes versões do kernel, verifique 78*82da0f94SDaniel Pereirase o valor de flags contém qualquer flag desconhecida e rejeite a chamada de 79*82da0f94SDaniel Pereirasistema (com ``EINVAL``) se contiver:: 80*82da0f94SDaniel Pereira 81*82da0f94SDaniel Pereira if (flags & ~(THING_FLAG1 | THING_FLAG2 | THING_FLAG3)) 82*82da0f94SDaniel Pereira return -EINVAL; 83*82da0f94SDaniel Pereira 84*82da0f94SDaniel Pereira(Se nenhum valor de flag for utilizado ainda, verifique se o argumento de flags 85*82da0f94SDaniel Pereiraé zero.) 86*82da0f94SDaniel Pereira 87*82da0f94SDaniel PereiraPara chamadas de sistema mais sofisticadas que envolvem um número maior de 88*82da0f94SDaniel Pereiraargumentos, prefere-se encapsular a maioria dos argumentos em uma estrutura 89*82da0f94SDaniel Pereira(struct) que é passada por meio de um ponteiro. Esse tipo de estrutura pode 90*82da0f94SDaniel Pereiralidar com extensões futuras incluindo um argumento de tamanho (size) na própria 91*82da0f94SDaniel Pereiraestrutura:: 92*82da0f94SDaniel Pereira 93*82da0f94SDaniel Pereira struct xyzzy_params { 94*82da0f94SDaniel Pereira u32 size; /* o espaço do usuário define p->size = sizeof(struct xyzzy_params) */ 95*82da0f94SDaniel Pereira u32 param_1; 96*82da0f94SDaniel Pereira u64 param_2; 97*82da0f94SDaniel Pereira u64 param_3; 98*82da0f94SDaniel Pereira }; 99*82da0f94SDaniel Pereira 100*82da0f94SDaniel PereiraDesde que qualquer campo adicionado subsequentemente, digamos ``param_4``, seja 101*82da0f94SDaniel Pereiraprojetado de forma que um valor zero mantenha o comportamento anterior, isso 102*82da0f94SDaniel Pereirapermitirá lidar com a divergência de versões em ambas as direções: 103*82da0f94SDaniel Pereira 104*82da0f94SDaniel Pereira - Para lidar com um programa de espaço do usuário mais novo chamando um kernel 105*82da0f94SDaniel Pereira mais antigo, o código do kernel deve verificar se qualquer memória além do 106*82da0f94SDaniel Pereira tamanho da estrutura que ele espera está zerada (efetivamente verificando 107*82da0f94SDaniel Pereira se ``param_4 == 0``). 108*82da0f94SDaniel Pereira - Para lidar com um programa de espaço do usuário mais antigo chamando um kernel 109*82da0f94SDaniel Pereira mais novo, o código do kernel pode preencher com zero (zero-extend) a 110*82da0f94SDaniel Pereira instância menor da estrutura (efetivamente definindo ``param_4 = 0``). 111*82da0f94SDaniel Pereira 112*82da0f94SDaniel PereiraVeja :manpage:`perf_event_open(2)` e a função ``perf_copy_attr()`` (em 113*82da0f94SDaniel Pereira``kernel/events/core.c``) para um exemplo desta abordagem. 114*82da0f94SDaniel Pereira 115*82da0f94SDaniel Pereira 116*82da0f94SDaniel PereiraProjetando a API: Outras Considerações 117*82da0f94SDaniel Pereira-------------------------------------- 118*82da0f94SDaniel Pereira 119*82da0f94SDaniel PereiraSe a sua nova chamada de sistema permitir que o espaço do usuário se refira a 120*82da0f94SDaniel Pereiraum objeto do kernel, ela deve usar um descritor de arquivo (file descriptor) 121*82da0f94SDaniel Pereiracomo o handle (identificador) para esse objeto -- não invente um novo tipo de 122*82da0f94SDaniel Pereirahandle de objeto para o espaço do usuário quando o kernel já possui mecanismos 123*82da0f94SDaniel Pereirae semânticas bem definidas para o uso de descritores de arquivo. 124*82da0f94SDaniel Pereira 125*82da0f94SDaniel PereiraSe a sua nova chamada de sistema (2) de fato retornar un novo descritor de 126*82da0f94SDaniel Pereiraarquivo, então o argumento de flags deve incluir um valor que seja equivalente 127*82da0f94SDaniel Pereiraa definir ``O_CLOEXEC`` no novo FD. Isso torna possível para o espaço do usuário 128*82da0f94SDaniel Pereirafechar a janela de tempo entre a chamada ``()`` e a execução de 129*82da0f94SDaniel Pereira``fcntl(fd, F_SETFD, FD_CLOEXEC)``, onde um ``fork()`` e ``execve()`` inesperados 130*82da0f94SDaniel Pereiraem outra thread poderiam vazar um descritor para o programa executado. (Contudo, 131*82da0f94SDaniel Pereiraresista à tentação de reutilizar o valor real da constante ``O_CLOEXEC``, pois 132*82da0f94SDaniel Pereiraela é específica de cada arquitetura e faz parte de um espaço de numeração de 133*82da0f94SDaniel Pereiraflags ``O_*`` que está bastante cheio.) 134*82da0f94SDaniel Pereira 135*82da0f94SDaniel PereiraSe a sua chamada de sistema retornar um novo descritor de arquivo, você também 136*82da0f94SDaniel Pereiradeve considerar o que significa usar a família de chamadas de sistema 137*82da0f94SDaniel Pereira:manpage:`poll(2)` nesse descritor de arquivo. Tornar um descritor de arquivo 138*82da0f94SDaniel Pereirapronto para leitura ou escrita é a maneira normal de o kernel indicar ao espaço 139*82da0f94SDaniel Pereirado usuário que um evento ocorreu no objeto correspondente do kernel. 140*82da0f94SDaniel Pereira 141*82da0f94SDaniel PereiraSe a sua nova chamada de sistema (2) envolver um argumento de nome de arquivo 142*82da0f94SDaniel Pereira(filename):: 143*82da0f94SDaniel Pereira 144*82da0f94SDaniel Pereira int sys_xyzzy(const char __user *path, ..., unsigned int flags); 145*82da0f94SDaniel Pereira 146*82da0f94SDaniel Pereiravocê também deve considerar se uma versão xyzzyat(2) seria mais apropriada:: 147*82da0f94SDaniel Pereira 148*82da0f94SDaniel Pereira int sys_xyzzyat(int dfd, const char __user *path, ..., unsigned int flags); 149*82da0f94SDaniel Pereira 150*82da0f94SDaniel PereiraIsso permite maior flexibilidade para a forma como o espaço do usuário especifica 151*82da0f94SDaniel Pereirao arquivo em questão; em particular, permite que o espaço do usuário solicite a 152*82da0f94SDaniel Pereirafuncionalidade para um descritor de arquivo já aberto usando a flag 153*82da0f94SDaniel Pereira``AT_EMPTY_PATH``, fornecendo efetivamente uma operação fxyzzy(3) de graça:: 154*82da0f94SDaniel Pereira 155*82da0f94SDaniel Pereira - xyzzyat(AT_FDCWD, path, ..., 0) é equivalente a (path,...) 156*82da0f94SDaniel Pereira - xyzzyat(fd, "", ..., AT_EMPTY_PATH) é equivalente a fxyzzy(fd, ...) 157*82da0f94SDaniel Pereira 158*82da0f94SDaniel Pereira(Para mais detalhes sobre a justificativa das chamadas \*at(), veja a página de 159*82da0f94SDaniel Pereiramanual :manpage:`openat(2)`; para um exemplo de AT_EMPTY_PATH, veja a página de 160*82da0f94SDaniel Pereiramanual :manpage:`fstatat(2)`.) 161*82da0f94SDaniel Pereira 162*82da0f94SDaniel PereiraSe a sua nova chamada de sistema (2) envolver um parâmetro que descreve um 163*82da0f94SDaniel Pereiradeslocamento (offset) dentro de um arquivo, mude o seu tipo para ``loff_t`` para 164*82da0f94SDaniel Pereiraque offsets de 64 bits possam ser suportados mesmo em arquiteturas de 32 bits. 165*82da0f94SDaniel Pereira 166*82da0f94SDaniel PereiraSe a sua nova chamada de sistema (2) envolver funcionalidades privilegiadas, 167*82da0f94SDaniel Pereiraela precisa ser governada pelo bit de capacidade (capability) do Linux apropriado 168*82da0f94SDaniel Pereira(verificado com uma chamada a ``capable()``), conforme descrito na página de 169*82da0f94SDaniel Pereiramanual :manpage:`capabilities(7)`. Escolha um bit de capacidade existente que governe 170*82da0f94SDaniel Pereirafuncionalidades relacionadas, mas tente evitar combinar muitas funções que tenham 171*82da0f94SDaniel Pereiraapenas uma vaga relação sob o mesmo bit, pois isso vai contra o propósito das 172*82da0f94SDaniel Pereiracapabilities de dividir o poder do root. Em particular, evite adicionar novos 173*82da0f94SDaniel Pereirausos para a capacidade ``CAP_SYS_ADMIN``, que já é excessivamente generalista. 174*82da0f94SDaniel Pereira 175*82da0f94SDaniel PereiraSe a sua nova chamada de sistema (2) manipular um processo diferente do 176*82da0f94SDaniel Pereiraprocesso que a chamou, ela deve ser restrita (usando uma chamada a 177*82da0f94SDaniel Pereira``ptrace_may_access()``) para que apenas um processo chamador com as mesmas 178*82da0f94SDaniel Pereirapermissões do processo alvo, ou com as capacidades necessárias, possa manipular 179*82da0f94SDaniel Pereirao processo alvo. 180*82da0f94SDaniel Pereira 181*82da0f94SDaniel PereiraFinalmente, esteja ciente de que algumas arquiteturas não-x86 lidam melhor se os 182*82da0f94SDaniel Pereiraparâmetros da chamada de sistema que são explicitamente de 64 bits caírem em 183*82da0f94SDaniel Pereiraargumentos de numeração ímpar (ou seja, parâmetro 1, 3, 5), para permitir o uso 184*82da0f94SDaniel Pereirade pares contíguos de registradores de 32 bits. (Esta preocupação não se aplica 185*82da0f94SDaniel Pereirase os argumentos fizerem parte de uma estrutura que é passada por meio de um 186*82da0f94SDaniel Pereiraponteiro.) 187*82da0f94SDaniel Pereira 188*82da0f94SDaniel Pereira 189*82da0f94SDaniel PereiraPropondo a API 190*82da0f94SDaniel Pereira-------------- 191*82da0f94SDaniel Pereira 192*82da0f94SDaniel PereiraPara tornar as novas chamadas de sistema fáceis de revisar, é melhor dividir o 193*82da0f94SDaniel Pereiraconjunto de patches (patchset) em blocos separados. Estes devem incluir, pelo 194*82da0f94SDaniel Pereiramenos, os seguintes itens como commits distintos (cada um dos quais é descrito 195*82da0f94SDaniel Pereiramais adiante): 196*82da0f94SDaniel Pereira 197*82da0f94SDaniel Pereira - A implementação central da chamada de sistema, juntamente com protótipos, 198*82da0f94SDaniel Pereira numeração genérica, alterações no Kconfig e a implementação de stub de realinhamento (fallback stub). 199*82da0f94SDaniel Pereira - A fiação (wiring up) da nova chamada de sistema para uma arquitetura em 200*82da0f94SDaniel Pereira particular, geralmente x86 (incluindo todas as variantes x86_64, x86_32 e x32). 201*82da0f94SDaniel Pereira - Uma demonstração do uso da nova chamada de sistema no espaço do usuário por 202*82da0f94SDaniel Pereira meio de um selftest em ``tools/testing/selftests/``. 203*82da0f94SDaniel Pereira - Um rascunho da página de manual (man-page) para a nova chamada de sistema, 204*82da0f94SDaniel Pereira seja como texto simples na carta de apresentação (cover letter) ou como um 205*82da0f94SDaniel Pereira patch para o repositório (separado) de man-pages. 206*82da0f94SDaniel Pereira 207*82da0f94SDaniel PereiraNovas propostas de chamadas de sistema, como qualquer alteração na API do 208*82da0f94SDaniel Pereirakernel, devem sempre ser enviadas com cópia (cc'ed) para linux-api@vger.kernel.org. 209*82da0f94SDaniel Pereira 210*82da0f94SDaniel Pereira 211*82da0f94SDaniel PereiraImplementação Genérica de Chamadas de Sistema 212*82da0f94SDaniel Pereira--------------------------------------------- 213*82da0f94SDaniel Pereira 214*82da0f94SDaniel PereiraO ponto de entrada principal para a sua nova chamada de sistema (2) será chamado 215*82da0f94SDaniel Pereirade ``sys_xyzzy()``, mas você deve adicionar esse ponto de entrada com a macro 216*82da0f94SDaniel Pereira``SYSCALL_DEFINEn()`` apropriada, em vez de fazer isso explicitamente. O 'n' 217*82da0f94SDaniel Pereiraindica o número de argumentos da chamada de sistema, e a macro recebe o nome da 218*82da0f94SDaniel Pereirachamada de sistema seguido pelos pares (tipo, nome) para os parâmetros como 219*82da0f94SDaniel Pereiraargumentos. O uso dessa macro permite que os metadados sobre a nova chamada de 220*82da0f94SDaniel Pereirasistema fiquem disponíveis para outras ferramentas. 221*82da0f94SDaniel Pereira 222*82da0f94SDaniel PereiraO novo ponto de entrada também precisa de um protótipo de função correspondente 223*82da0f94SDaniel Pereiraem ``include/linux/syscalls.h``, marcado como asmlinkage para corresponder à 224*82da0f94SDaniel Pereiramaneira como as chamadas de sistema são invocadas:: 225*82da0f94SDaniel Pereira 226*82da0f94SDaniel Pereira asmlinkage long sys_xyzzy(...); 227*82da0f94SDaniel Pereira 228*82da0f94SDaniel PereiraAlgumas arquiteturas (por exemplo, x86) possuem suas próprias tabelas de syscall 229*82da0f94SDaniel Pereiraespecíficas da arquitetura, mas várias outras arquiteturas compartilham uma tabela 230*82da0f94SDaniel Pereirade syscall genérica. Adicione a sua nova chamada de sistema à lista genérica 231*82da0f94SDaniel Pereiraadicionando uma entrada na lista em ``include/uapi/asm-generic/unistd.h``:: 232*82da0f94SDaniel Pereira 233*82da0f94SDaniel Pereira #define __NR_xyzzy 292 234*82da0f94SDaniel Pereira __SYSCALL(__NR_xyzzy, sys_xyzzy) 235*82da0f94SDaniel Pereira 236*82da0f94SDaniel PereiraAtualize também a contagem de __NR_syscalls para refletir a chamada de sistema 237*82da0f94SDaniel Pereiraadicional, e observe que se múltiplas novas chamadas de sistema forem adicionadas 238*82da0f94SDaniel Pereirana mesma janela de mesclagem (merge window), o número da sua nova syscall poderá 239*82da0f94SDaniel Pereiraser ajustado para resolver conflitos. 240*82da0f94SDaniel Pereira 241*82da0f94SDaniel PereiraO arquivo ``kernel/sys_ni.c`` fornece uma implementação de stub de fallback para 242*82da0f94SDaniel Pereiracada chamada de sistema, retornando ``-ENOSYS``. Adicione a sua nova chamada de 243*82da0f94SDaniel Pereirasistema aqui também:: 244*82da0f94SDaniel Pereira 245*82da0f94SDaniel Pereira COND_SYSCALL(sys_xyzzy); 246*82da0f94SDaniel Pereira 247*82da0f94SDaniel PereiraA sua nova funcionalidade de kernel, e a chamada de sistema que a controla, deve 248*82da0f94SDaniel Pereiranormalmente ser opcional, portanto adicione uma opção ``CONFIG`` (tipicamente em 249*82da0f94SDaniel Pereira``init/Kconfig``) para ela. Como de costume para novas opções ``CONFIG``: 250*82da0f94SDaniel Pereira 251*82da0f94SDaniel Pereira - Inclua uma descrição da nova funcionalidade e da chamada de sistema controlada 252*82da0f94SDaniel Pereira pela opção. 253*82da0f94SDaniel Pereira - Faça a opção depender de EXPERT se ela deve ser ocultada dos usuários normais. 254*82da0f94SDaniel Pereira - Faça com que quaisquer novos arquivos de código-fonte que implementem a função 255*82da0f94SDaniel Pereira sejam dependentes da opção CONFIG no Makefile (por exemplo, 256*82da0f94SDaniel Pereira ``obj-$(CONFIG_XYZZY_SYSCALL) += xyzzy.o``). 257*82da0f94SDaniel Pereira - Verifique duas vezes se o kernel ainda compila com a nova opção CONFIG desativada. 258*82da0f94SDaniel Pereira 259*82da0f94SDaniel PereiraPara resumir, você precisa de um commit que inclua: 260*82da0f94SDaniel Pereira 261*82da0f94SDaniel Pereira - Opção ``CONFIG`` para a nova função, normalmente em ``init/Kconfig`` 262*82da0f94SDaniel Pereira - ``SYSCALL_DEFINEn(, ...)`` para o ponto de entrada 263*82da0f94SDaniel Pereira - Protótipo correspondente em ``include/linux/syscalls.h`` 264*82da0f94SDaniel Pereira - Entrada na tabela genérica em ``include/uapi/asm-generic/unistd.h`` 265*82da0f94SDaniel Pereira - Stub de fallback em ``kernel/sys_ni.c`` 266*82da0f94SDaniel Pereira 267*82da0f94SDaniel Pereira 268*82da0f94SDaniel Pereira.. _pt_BR_syscall_generic_6_11: 269*82da0f94SDaniel Pereira 270*82da0f94SDaniel PereiraDesde a versão 6.11 271*82da0f94SDaniel Pereira~~~~~~~~~~~~~~~~~~~ 272*82da0f94SDaniel Pereira 273*82da0f94SDaniel PereiraA partir da versão 6.11 do kernel, a implementação de chamadas de sistema 274*82da0f94SDaniel Pereiragenéricas para as seguintes arquiteturas não requer mais modificações em 275*82da0f94SDaniel Pereira``include/uapi/asm-generic/unistd.h``: 276*82da0f94SDaniel Pereira 277*82da0f94SDaniel Pereira - arc 278*82da0f94SDaniel Pereira - arm64 279*82da0f94SDaniel Pereira - csky 280*82da0f94SDaniel Pereira - hexagon 281*82da0f94SDaniel Pereira - loongarch 282*82da0f94SDaniel Pereira - nios2 283*82da0f94SDaniel Pereira - openrisc 284*82da0f94SDaniel Pereira - riscv 285*82da0f94SDaniel Pereira 286*82da0f94SDaniel PereiraEm vez disso, você precisa atualizar ``scripts/syscall.tbl`` e, se aplicável, 287*82da0f94SDaniel Pereiraajustar ``arch/*/kernel/Makefile.syscalls``. 288*82da0f94SDaniel Pereira 289*82da0f94SDaniel PereiraComo o ``scripts/syscall.tbl`` serve como uma tabela de syscall comum para 290*82da0f94SDaniel Pereiramúltiplas arquiteturas, uma nova entrada é necessária nesta tabela:: 291*82da0f94SDaniel Pereira 292*82da0f94SDaniel Pereira 468 common sys_xyzzy 293*82da0f94SDaniel Pereira 294*82da0f94SDaniel PereiraNote que adicionar uma entrada ao ``scripts/syscall.tbl`` com a ABI "common" 295*82da0f94SDaniel Pereiratambém afeta todas as arquiteturas que compartilham essa tabela. Para alterações 296*82da0f94SDaniel Pereiramais limitadas ou específicas de uma arquitetura, considere usar uma ABI 297*82da0f94SDaniel Pereiraespecífica da arquitetura ou definir uma nova. 298*82da0f94SDaniel Pereira 299*82da0f94SDaniel PereiraSe uma nova ABI, digamos ``xyz``, for introduzida, as atualizações 300*82da0f94SDaniel Pereiracorrespondentes também devem ser feitas em ``arch/*/kernel/Makefile.syscalls``:: 301*82da0f94SDaniel Pereira 302*82da0f94SDaniel Pereira syscall_abis_{32,64} += xyz (...) 303*82da0f94SDaniel Pereira 304*82da0f94SDaniel PereiraPara resumir, você precisa de um commit que inclua: 305*82da0f94SDaniel Pereira 306*82da0f94SDaniel Pereira - Opção ``CONFIG`` para a nova função, normalmente em ``init/Kconfig`` 307*82da0f94SDaniel Pereira - ``SYSCALL_DEFINEn(, ...)`` para o ponto de entrada 308*82da0f94SDaniel Pereira - Protótipo correspondente em ``include/linux/syscalls.h`` 309*82da0f94SDaniel Pereira - Nova entrada em ``scripts/syscall.tbl`` 310*82da0f94SDaniel Pereira - (Se necessário) Atualizações de Makefile em ``arch/*/kernel/Makefile.syscalls`` 311*82da0f94SDaniel Pereira - Stub de fallback em ``kernel/sys_ni.c`` 312*82da0f94SDaniel Pereira 313*82da0f94SDaniel Pereira 314*82da0f94SDaniel PereiraImplementação de Chamadas de Sistema em x86 315*82da0f94SDaniel Pereira------------------------------------------- 316*82da0f94SDaniel Pereira 317*82da0f94SDaniel PereiraPara interligar (wire up) a sua nova chamada de sistema nas plataformas x86, você 318*82da0f94SDaniel Pereiraprecisa atualizar as tabelas mestras de syscall. Assumindo que a sua nova chamada 319*82da0f94SDaniel Pereirade sistema não seja especial de alguma forma (veja abaixo), isso envolve uma 320*82da0f94SDaniel Pereiraentrada "common" (para x86_64 e x32) em 321*82da0f94SDaniel Pereira``arch/x86/entry/syscalls/syscall_64.tbl``:: 322*82da0f94SDaniel Pereira 323*82da0f94SDaniel Pereira 333 common sys_xyzzy 324*82da0f94SDaniel Pereira 325*82da0f94SDaniel Pereirae uma entrada "i386" em ``arch/x86/entry/syscalls/syscall_32.tbl``:: 326*82da0f94SDaniel Pereira 327*82da0f94SDaniel Pereira 380 i386 sys_xyzzy 328*82da0f94SDaniel Pereira 329*82da0f94SDaniel PereiraNovamente, esses números estão sujeitos a alterações caso ocorram conflitos na 330*82da0f94SDaniel Pereirajanela de mesclagem (merge window) relevante. 331*82da0f94SDaniel Pereira 332*82da0f94SDaniel PereiraChamadas de Sistema de Compatibilidade (Genéricas) 333*82da0f94SDaniel Pereira-------------------------------------------------- 334*82da0f94SDaniel Pereira 335*82da0f94SDaniel PereiraPara a maioria das chamadas de sistema, a mesma implementação de 64 bits pode 336*82da0f94SDaniel Pereiraser invocada mesmo quando o programa do espaço do usuário é, ele próprio, de 32 337*82da0f94SDaniel Pereirabits; mesmo se os parâmetros da chamada de sistema incluírem um ponteiro 338*82da0f94SDaniel Pereiraexplícito, isso é tratado de forma transparente. 339*82da0f94SDaniel Pereira 340*82da0f94SDaniel PereiraNo entanto, existem algumas situações em que uma camada de compatibilidade 341*82da0f94SDaniel Pereira(compatibility layer) é necessária para lidar com as diferenças de tamanho entre 342*82da0f94SDaniel Pereira32 bits e 64 bits. 343*82da0f94SDaniel Pereira 344*82da0f94SDaniel PereiraA primeira é se o kernel de 64 bits também suportar programas de espaço do 345*82da0f94SDaniel Pereirausuário de 32 bits e, portanto, precisar analisar áreas de memória 346*82da0f94SDaniel Pereira(``__user``) que poderiam conter valores de 32 bits ou 64 bits. Em particular, 347*82da0f94SDaniel Pereiraisso é necessário sempre que um argumento de chamada de sistema for: 348*82da0f94SDaniel Pereira 349*82da0f94SDaniel Pereira - um ponteiro para um ponteiro 350*82da0f94SDaniel Pereira - um ponteiro para uma struct que contém um ponteiro (por exemplo, 351*82da0f94SDaniel Pereira ``struct iovec __user *``) 352*82da0f94SDaniel Pereira - um ponteiro para um tipo integral de tamanho variável (``time_t``, 353*82da0f94SDaniel Pereira ``off_t``, ``long``, ...) 354*82da0f94SDaniel Pereira - um ponteiro para uma struct que contém um tipo integral de tamanho variável. 355*82da0f94SDaniel Pereira 356*82da0f94SDaniel PereiraA segunda situação que requer uma camada de compatibilidade é se um dos 357*82da0f94SDaniel Pereiraargumentos da chamada de sistema tiver um tipo que é explicitamente de 64 bits, 358*82da0f94SDaniel Pereiramesmo em uma arquitetura de 32 bits, por exemplo, ``loff_t`` ou ``__u64``. Neste 359*82da0f94SDaniel Pereiracaso, um valor que chega ao kernel de 64 bits vindo de uma aplicação de 32 bits 360*82da0f94SDaniel Pereiraserá dividido em dois valores de 32 bits, que precisarão ser remontados na 361*82da0f94SDaniel Pereiracamada de compatibilidade. 362*82da0f94SDaniel Pereira 363*82da0f94SDaniel Pereira(Note que um argumento de chamada de sistema que seja um ponteiro para um tipo 364*82da0f94SDaniel Pereiraexplícito de 64 bits **não** precisa de uma camada de compatibilidade; por 365*82da0f94SDaniel Pereiraexemplo, os argumentos do :manpage:`splice(2)` do tipo ``loff_t __user *`` não 366*82da0f94SDaniel Pereiradisparam a necessidade de uma chamada de sistema ``compat_``.) 367*82da0f94SDaniel Pereira 368*82da0f94SDaniel PereiraA versão de compatibilidade da chamada de sistema é chamada de 369*82da0f94SDaniel Pereira``compat_sys_xyzzy()`` e é adicionada com a macro ``COMPAT_SYSCALL_DEFINEn()``, 370*82da0f94SDaniel Pereirade forma análoga à macro SYSCALL_DEFINEn. Esta versão da implementação roda como 371*82da0f94SDaniel Pereiraparte de um kernel de 64 bits, mas espera receber valores de parâmetros de 32 372*82da0f94SDaniel Pereirabits e faz o que for necessário para lidar com eles. (Tipicamente, a versão 373*82da0f94SDaniel Pereira``compat_sys_`` converte os valores para versões de 64 bits e chama a versão 374*82da0f94SDaniel Pereira``sys_``, ou ambas chamam uma função interna comum de implementação). 375*82da0f94SDaniel Pereira 376*82da0f94SDaniel PereiraO ponto de entrada compat também precisa de um protótipo de função 377*82da0f94SDaniel Pereiracorrespondente em ``include/linux/compat.h``, marcado como asmlinkage para 378*82da0f94SDaniel Pereiracorresponder à maneira como as chamadas de sistema são invocadas:: 379*82da0f94SDaniel Pereira 380*82da0f94SDaniel Pereira asmlinkage long compat_sys_xyzzy(...); 381*82da0f94SDaniel Pereira 382*82da0f94SDaniel PereiraSe a chamada de sistema envolver uma estrutura cujo layout seja diferente em 383*82da0f94SDaniel Pereirasistemas de 32 bits e 64 bits, digamos ``struct xyzzy_args``, então o arquivo de 384*82da0f94SDaniel Pereiracabeçalho ``include/linux/compat.h`` também deve incluir uma versão compat da 385*82da0f94SDaniel Pereiraestrutura (``struct compat_xyzzy_args``), onde cada campo de tamanho variável 386*82da0f94SDaniel Pereiratenha o tipo ``compat_`` correspondente ao tipo na ``struct xyzzy_args``. A 387*82da0f94SDaniel Pereirarotina ``compat_sys_xyzzy()`` pode então usar essa estrutura ``compat_`` para 388*82da0f94SDaniel Pereiraanalisar os argumentos vindos de uma invocação de 32 bits. 389*82da0f94SDaniel Pereira 390*82da0f94SDaniel PereiraPor exemplo, se existirem os campos:: 391*82da0f94SDaniel Pereira 392*82da0f94SDaniel Pereira struct xyzzy_args { 393*82da0f94SDaniel Pereira const char __user *ptr; 394*82da0f94SDaniel Pereira __kernel_long_t varying_val; 395*82da0f94SDaniel Pereira u64 fixed_val; 396*82da0f94SDaniel Pereira /* ... */ 397*82da0f94SDaniel Pereira }; 398*82da0f94SDaniel Pereira 399*82da0f94SDaniel Pereirana struct xyzzy_args, então a struct compat_xyzzy_args teria:: 400*82da0f94SDaniel Pereira 401*82da0f94SDaniel Pereira struct compat_xyzzy_args { 402*82da0f94SDaniel Pereira compat_uptr_t ptr; 403*82da0f94SDaniel Pereira compat_long_t varying_val; 404*82da0f94SDaniel Pereira u64 fixed_val; 405*82da0f94SDaniel Pereira /* ... */ 406*82da0f94SDaniel Pereira }; 407*82da0f94SDaniel Pereira 408*82da0f94SDaniel PereiraA lista genérica de chamadas de sistema também precisa de ajustes para permitir 409*82da0f94SDaniel Pereiraa versão compat; a entrada em ``include/uapi/asm-generic/unistd.h`` deve usar 410*82da0f94SDaniel Pereira``__SC_COMP`` em vez de ``__SYSCALL``:: 411*82da0f94SDaniel Pereira 412*82da0f94SDaniel Pereira #define __NR_xyzzy 292 413*82da0f94SDaniel Pereira __SC_COMP(__NR_xyzzy, sys_xyzzy, compat_sys_xyzzy) 414*82da0f94SDaniel Pereira 415*82da0f94SDaniel PereiraPara resumir, você precisa de: 416*82da0f94SDaniel Pereira 417*82da0f94SDaniel Pereira - uma macro ``COMPAT_SYSCALL_DEFINEn(, ...)`` para o ponto de entrada compat 418*82da0f94SDaniel Pereira - protótipo correspondente em ``include/linux/compat.h`` 419*82da0f94SDaniel Pereira - (se necessário) struct de mapeamento de 32 bits em ``include/linux/compat.h`` 420*82da0f94SDaniel Pereira - instância de ``__SC_COMP``, e não de ``__SYSCALL``, em 421*82da0f94SDaniel Pereira ``include/uapi/asm-generic/unistd.h`` 422*82da0f94SDaniel Pereira 423*82da0f94SDaniel PereiraDesde a versão 6.11 424*82da0f94SDaniel Pereira~~~~~~~~~~~~~~~~~~~ 425*82da0f94SDaniel Pereira 426*82da0f94SDaniel PereiraIsso se aplica a todas as arquiteturas listadas em 427*82da0f94SDaniel Pereira:ref:`Desde a versão 6.11<pt_BR_syscall_generic_6_11>` sob "Implementação Genérica de 428*82da0f94SDaniel PereiraChamadas de Sistema", exceto arm64. Veja 429*82da0f94SDaniel Pereira:ref:`Chamadas de Sistema de Compatibilidade (arm64)<pt_BR_compat_arm64>` para mais 430*82da0f94SDaniel Pereirainformações. 431*82da0f94SDaniel Pereira 432*82da0f94SDaniel PereiraVocê precisa estender a entrada em ``scripts/syscall.tbl`` com uma coluna extra 433*82da0f94SDaniel Pereirapara indicar que um programa de espaço do usuário de 32 bits rodando em um 434*82da0f94SDaniel Pereirakernel de 64 bits deve atingir o ponto de entrada compat:: 435*82da0f94SDaniel Pereira 436*82da0f94SDaniel Pereira 468 common sys_xyzzy compat_sys_xyzzy 437*82da0f94SDaniel Pereira 438*82da0f94SDaniel PereiraPara resumir, você precisa de: 439*82da0f94SDaniel Pereira 440*82da0f94SDaniel Pereira - ``COMPAT_SYSCALL_DEFINEn(, ...)`` para o ponto de entrada compat 441*82da0f94SDaniel Pereira - Protótipo correspondente em ``include/linux/compat.h`` 442*82da0f94SDaniel Pereira - Modificação da entrada em ``scripts/syscall.tbl`` para incluir uma coluna 443*82da0f94SDaniel Pereira "compat" extra 444*82da0f94SDaniel Pereira - (Se necessário) Struct de mapeamento de 32 bits em ``include/linux/compat.h`` 445*82da0f94SDaniel Pereira 446*82da0f94SDaniel Pereira 447*82da0f94SDaniel Pereira.. _pt_BR_compat_arm64: 448*82da0f94SDaniel Pereira 449*82da0f94SDaniel PereiraChamadas de Sistema de Compatibilidade (arm64) 450*82da0f94SDaniel Pereira^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 451*82da0f94SDaniel Pereira 452*82da0f94SDaniel PereiraNo arm64, existe uma tabela de syscall dedicada para chamadas de sistema de 453*82da0f94SDaniel Pereiracompatibilidade voltadas para o espaço do usuário de 32 bits (AArch32): 454*82da0f94SDaniel Pereira``arch/arm64/tools/syscall_32.tbl``. Você precisa adicionar uma linha adicional 455*82da0f94SDaniel Pereiraa esta tabela especificando o ponto de entrada compat:: 456*82da0f94SDaniel Pereira 457*82da0f94SDaniel Pereira 468 common sys_xyzzy compat_sys_xyzzy 458*82da0f94SDaniel Pereira 459*82da0f94SDaniel Pereira 460*82da0f94SDaniel PereiraChamadas de Sistema de Compatibilidade (x86) 461*82da0f94SDaniel Pereira-------------------------------------------- 462*82da0f94SDaniel Pereira 463*82da0f94SDaniel PereiraPara interligar a arquitetura x86 de uma chamada de sistema com uma versão de 464*82da0f94SDaniel Pereiracompatibilidade, as entradas nas tabelas de syscall precisam ser ajustadas. 465*82da0f94SDaniel Pereira 466*82da0f94SDaniel PereiraPrimeiro, a entrada em ``arch/x86/entry/syscalls/syscall_32.tbl`` ganha uma 467*82da0f94SDaniel Pereiracoluna extra para indicar que um programa de espaço do usuário de 32 bits rodando 468*82da0f94SDaniel Pereiraem um kernel de 64 bits deve atingir o ponto de entrada compat:: 469*82da0f94SDaniel Pereira 470*82da0f94SDaniel Pereira 380 i386 sys_xyzzy __ia32_compat_sys_xyzzy 471*82da0f94SDaniel Pereira 472*82da0f94SDaniel PereiraSegundo, você precisa definir o que deve acontecer para a versão da ABI x32 da 473*82da0f94SDaniel Pereiranova chamada de sistema. Há uma escolha aqui: o layout dos argumentos deve 474*82da0f94SDaniel Pereiracorresponder à versão de 64 bits ou à versão de 32 bits. 475*82da0f94SDaniel Pereira 476*82da0f94SDaniel PereiraSe houver um ponteiro para um ponteiro envolvido, a decisão é fácil: x32 é 477*82da0f94SDaniel PereiraILP32 (inteiro, long e ponteiro possuem 32 bits), portanto o layout deve 478*82da0f94SDaniel Pereiracorresponder à versão de 32 bits, e a entrada em 479*82da0f94SDaniel Pereira``arch/x86/entry/syscalls/syscall_64.tbl`` é dividida para que os programas x32 480*82da0f94SDaniel Pereiraatinjam o wrapper de compatibilidade:: 481*82da0f94SDaniel Pereira 482*82da0f94SDaniel Pereira 333 64 sys_xyzzy 483*82da0f94SDaniel Pereira ... 484*82da0f94SDaniel Pereira 555 x32 __x32_compat_sys_xyzzy 485*82da0f94SDaniel Pereira 486*82da0f94SDaniel PereiraSe não houver ponteiros envolvidos, então é preferível reutilizar a chamada de 487*82da0f94SDaniel Pereirasistema de 64 bits para a ABI x32 (e, consequentemente, a entrada em 488*82da0f94SDaniel Pereira``arch/x86/entry/syscalls/syscall_64.tbl`` permanece inalterada). 489*82da0f94SDaniel Pereira 490*82da0f94SDaniel PereiraEm qualquer um dos casos, você deve verificar se os tipos envolvidos no layout 491*82da0f94SDaniel Pereirados seus argumentos de fato se mapeiam exatamente do x32 (-mx32) para os seus 492*82da0f94SDaniel Pereiraequivalentes de 32 bits (-m32) ou 64 bits (-m64). 493*82da0f94SDaniel Pereira 494*82da0f94SDaniel Pereira 495*82da0f94SDaniel PereiraChamadas de Sistema com Retorno para Outro Local 496*82da0f94SDaniel Pereira------------------------------------------------ 497*82da0f94SDaniel Pereira 498*82da0f94SDaniel PereiraPara a maioria das chamadas de sistema (syscalls), assim que a execução é 499*82da0f94SDaniel Pereiraconcluída, o programa do usuário continua exatamente de onde parou -- na 500*82da0f94SDaniel Pereirapróxima instrução, com a pilha idêntica e a maior parte dos registradores no 501*82da0f94SDaniel Pereiramesmo estado de antes da chamada, além do mesmo espaço de memória virtual. 502*82da0f94SDaniel Pereira 503*82da0f94SDaniel PereiraNo entanto, algumas poucas chamadas de sistema agem de forma diferente. Elas 504*82da0f94SDaniel Pereirapodem retornar para um local distinto (``rt_sigreturn``), alterar o espaço de 505*82da0f94SDaniel Pereiramemória (``fork``/``vfork``/``clone``) ou até mesmo modificar a arquitetura 506*82da0f94SDaniel Pereira(``execve``/``execveat``) do programa. 507*82da0f94SDaniel Pereira 508*82da0f94SDaniel PereiraPara permitir isso, a implementação da chamada de sistema no kernel pode 509*82da0f94SDaniel Pereiraprecisar salvar e restaurar registradores adicionais na pilha do kernel, 510*82da0f94SDaniel Pereiragarantindo controle total de onde e como a execução continuará após a syscall. 511*82da0f94SDaniel Pereira 512*82da0f94SDaniel PereiraIsso é específico de cada arquitetura (arch-specific), mas tipicamente envolve 513*82da0f94SDaniel Pereiraa definição de pontos de entrada em assembly que salvam/restauram esses 514*82da0f94SDaniel Pereiraregistradores adicionais e invocam o ponto de entrada real da chamada de 515*82da0f94SDaniel Pereirasistema. 516*82da0f94SDaniel Pereira 517*82da0f94SDaniel PereiraPara x86_64, isso é implementado como um ponto de entrada ``stub_xyzzy`` em 518*82da0f94SDaniel Pereira``arch/x86/entry/entry_64.S``, e a entrada correspondente na tabela de syscalls 519*82da0f94SDaniel Pereira(``arch/x86/entry/syscalls/syscall_64.tbl``) é ajustada para refletir:: 520*82da0f94SDaniel Pereira 521*82da0f94SDaniel Pereira 333 common stub_xyzzy 522*82da0f94SDaniel Pereira 523*82da0f94SDaniel PereiraO equivalente para programas de 32 bits executados em um kernel de 64 bits é 524*82da0f94SDaniel Pereiranormalmente chamado de ``stub32_xyzzy`` e implementado em 525*82da0f94SDaniel Pereira``arch/x86/entry/entry_64_compat.S``, com o respectivo ajuste na tabela de 526*82da0f94SDaniel Pereirasyscalls em ``arch/x86/entry/syscalls/syscall_32.tbl``:: 527*82da0f94SDaniel Pereira 528*82da0f94SDaniel Pereira 380 i386 sys_xyzzy stub32_xyzzy 529*82da0f94SDaniel Pereira 530*82da0f94SDaniel PereiraSe a chamada de sistema precisar de uma camada de compatibilidade (como na 531*82da0f94SDaniel Pereiraseção anterior), a versão ``stub32_`` precisará chamar a versão 532*82da0f94SDaniel Pereira``compat_sys_`` da chamada de sistema em vez da versão nativa de 64 bits. Além 533*82da0f94SDaniel Pereiradisso, se a implementação da ABI x32 não for compartilhada com a versão 534*82da0f94SDaniel Pereirax86_64, sua tabela de syscalls também precisará invocar um stub que direcione 535*82da0f94SDaniel Pereirapara a versão ``compat_sys_``. 536*82da0f94SDaniel Pereira 537*82da0f94SDaniel PereiraPor questões de integridade, também é recomendado configurar um mapeamento para 538*82da0f94SDaniel Pereiraque o User-Mode Linux (UML) continue funcionando -- sua tabela de syscalls fará 539*82da0f94SDaniel Pereirareferência a ``stub_xyzzy``, mas o build do UML não inclui a implementação de 540*82da0f94SDaniel Pereira``arch/x86/entry/entry_64.S`` (já que o UML simula registradores, etc.). Corrigir 541*82da0f94SDaniel Pereiraisso é tão simples quanto adicionar um #define em 542*82da0f94SDaniel Pereira``arch/x86/um/sys_call_table_64.c``:: 543*82da0f94SDaniel Pereira 544*82da0f94SDaniel Pereira #define stub_xyzzy sys_xyzzy 545*82da0f94SDaniel Pereira 546*82da0f94SDaniel Pereira 547*82da0f94SDaniel PereiraOutros Detalhes 548*82da0f94SDaniel Pereira--------------- 549*82da0f94SDaniel Pereira 550*82da0f94SDaniel PereiraA maior parte do kernel trata as chamadas de sistema de maneira genérica, mas 551*82da0f94SDaniel Pereirahá exceções ocasionais que podem precisar de atualização para a sua chamada 552*82da0f94SDaniel Pereirade sistema específica. 553*82da0f94SDaniel Pereira 554*82da0f94SDaniel PereiraO subsistema de auditoria (audit) é um desses casos especiais; ele inclui 555*82da0f94SDaniel Pereirafunções (específicas de cada arquitetura) que classificam alguns tipos 556*82da0f94SDaniel Pereiraespeciais de chamada de sistema -- especificamente operações de abertura de 557*82da0f94SDaniel Pereiraarquivo (``open``/``openat``), execução de programa (``execve``/``exeveat``) ou 558*82da0f94SDaniel Pereiramultiplexador de socket (``socketcall``). Se a sua nova chamada de sistema for 559*82da0f94SDaniel Pereiraanáloga a uma dessas, o sistema de auditoria deverá ser atualizado. 560*82da0f94SDaniel Pereira 561*82da0f94SDaniel PereiraDe forma mais geral, se existir uma chamada de sistema atual que seja análoga 562*82da0f94SDaniel Pereiraà sua nova chamada de sistema, vale a pena fazer um grep em todo o kernel pela 563*82da0f94SDaniel Pereirachamada existente para verificar se não há outros casos especiais. 564*82da0f94SDaniel Pereira 565*82da0f94SDaniel Pereira 566*82da0f94SDaniel PereiraTestes 567*82da0f94SDaniel Pereira------ 568*82da0f94SDaniel Pereira 569*82da0f94SDaniel PereiraUma nova chamada de sistema deve, obviamente, ser testada; também é útil 570*82da0f94SDaniel Pereirafornecer aos revisores uma demonstração de como os programas do espaço do 571*82da0f94SDaniel Pereirausuário (user space) usarão a chamada de sistema. Uma boa maneira de combinar 572*82da0f94SDaniel Pereiraesses objetivos é incluir um programa simples de autoteste em um novo diretório 573*82da0f94SDaniel Pereirasob ``tools/testing/selftests/``. 574*82da0f94SDaniel Pereira 575*82da0f94SDaniel PereiraPara uma nova chamada de sistema, obviamente não haverá uma função de wrapper 576*82da0f94SDaniel Pereirana libc e, portanto, o teste precisará invocá-la usando ``syscall()``; além 577*82da0f94SDaniel Pereiradisso, se a chamada de sistema envolver uma nova estrutura visível para o 578*82da0f94SDaniel Pereiraespaço do usuário, o cabeçalho correspondente precisará ser instalado para 579*82da0f94SDaniel Pereiracompilar o teste. 580*82da0f94SDaniel Pereira 581*82da0f94SDaniel PereiraCertifique-se de que o autoteste seja executado com sucesso em todas as 582*82da0f94SDaniel Pereiraarquiteturas suportadas. Por exemplo, verifique se ele funciona quando compitado 583*82da0f94SDaniel Pereiracomo um programa ABI x86_64 (-m64), x86_32 (-m32) e x32 (-mx32). 584*82da0f94SDaniel Pereira 585*82da0f94SDaniel PereiraPara testes mais extensos e minuciosos de novas funcionalidades, você também 586*82da0f94SDaniel Pereiradeve considerar a adição de testes ao Linux Test Project ou ao projeto 587*82da0f94SDaniel Pereiraxfstests para alterações relacionadas 588*82da0f94SDaniel Pereira 589*82da0f94SDaniel PereiraPágina de Manual (Man Page) 590*82da0f94SDaniel Pereira--------------------------- 591*82da0f94SDaniel Pereira 592*82da0f94SDaniel PereiraTodas as novas chamadas de sistema devem vir acompanhadas de uma página de 593*82da0f94SDaniel Pereiramanual completa, idealmente usando a marcação groff, mas texto simples também 594*82da0f94SDaniel Pereiraé aceitável. Se o groff for utilizado, é útil incluir uma versão ASCII pré- 595*82da0f94SDaniel Pereirarenderizada da página de manual no e-mail de apresentação (cover letter) do 596*82da0f94SDaniel Pereiraconjunto de patches (patchset), para a conveniência dos revisores. 597*82da0f94SDaniel Pereira 598*82da0f94SDaniel PereiraA página de manual deve ser enviada com cópia (cc) para 599*82da0f94SDaniel Pereiralinux-man@vger.kernel.org. Para mais detalhes, consulte 600*82da0f94SDaniel Pereirahttps://www.kernel.org/doc/man-pages/patches.html 601*82da0f94SDaniel Pereira 602*82da0f94SDaniel Pereira 603*82da0f94SDaniel PereiraNão invoque Chamadas de Sistema dentro do Kernel 604*82da0f94SDaniel Pereira------------------------------------------------ 605*82da0f94SDaniel Pereira 606*82da0f94SDaniel PereiraAs chamadas de sistema são, como mencionado acima, pontos de interação entre o 607*82da0f94SDaniel Pereiraespaço do usuário (userspace) e o kernel. Portanto, funções de chamada de 608*82da0f94SDaniel Pereirasistema como ``sys_xyzzy()`` ou ``compat_sys_xyzzy()`` só devem ser chamadas a 609*82da0f94SDaniel Pereirapartir do espaço do usuário por meio da tabela de syscalls, e não de outros 610*82da0f94SDaniel Pereiralugares do kernel. Se a funcionalidade da syscall for útil para ser utilizada 611*82da0f94SDaniel Pereiradentro do kernel, precisar ser compartilhada entre uma syscall antiga e uma 612*82da0f94SDaniel Pereiranova, ou precisar ser compartilhada entre uma syscall e sua variante de 613*82da0f94SDaniel Pereiracompatibilidade, ela deve ser implementada por meio de uma função auxiliadora 614*82da0f94SDaniel Pereira("helper", como ``ksys_xyzzy()``). Essa função do kernel poderá então ser 615*82da0f94SDaniel Pereirachamada dentro do stub da syscall (``sys_xyzzy()``), do stub da syscall de 616*82da0f94SDaniel Pereiracompatibilidade (``compat_sys_xyzzy()``) e/ou de outro código do kernel. 617*82da0f94SDaniel Pereira 618*82da0f94SDaniel PereiraPelo menos em x86 de 64 bits, será um requisito rígido a partir da versão v4.17 619*82da0f94SDaniel Pereiraem diante não chamar funções de chamadas de sistema no kernel. Essa arquitetura 620*82da0f94SDaniel Pereirautiliza uma convenção de chamada diferente para chamadas de sistema na qual a 621*82da0f94SDaniel Pereira``struct pt_regs`` é decodificada dinamicamente em um wrapper de syscall, que 622*82da0f94SDaniel Pereiraentão repassa o processamento para a função real da syscall. Isso significa que 623*82da0f94SDaniel Pereiraapenas os parâmetros realmente necessários para uma syscall específica são 624*82da0f94SDaniel Pereirapassados durante a entrada da syscall, em vez de preencher seis registradores da 625*82da0f94SDaniel PereiraCPU com conteúdos aleatórios do espaço do usuário o tempo todo (o que poderia 626*82da0f94SDaniel Pereiracausar problemas sérios no decorrer da cadeia de chamadas). 627*82da0f94SDaniel Pereira 628*82da0f94SDaniel PereiraAlém disso, as regras sobre como os dados podem ser acessados diferem entre os 629*82da0f94SDaniel Pereiradados do kernel e os dados do usuário. Essa é outra razão pela qual chamar 630*82da0f94SDaniel Pereira``sys_xyzzy()`` geralmente é uma má ideia. 631*82da0f94SDaniel Pereira 632*82da0f94SDaniel PereiraExceções a essa regra são permitidas apenas em substituições (overrides) 633*82da0f94SDaniel Pereiraespecíficas de cada arquitetura, wrappers de compatibilidade específicos de cada 634*82da0f94SDaniel Pereiraarquitetura ou outros códigos dentro do diretório arch/. 635*82da0f94SDaniel Pereira 636*82da0f94SDaniel PereiraReferências e Fontes 637*82da0f94SDaniel Pereira-------------------- 638*82da0f94SDaniel Pereira 639*82da0f94SDaniel Pereira - Artigo da LWN por Michael Kerrisk sobre o uso do argumento flags em chamadas 640*82da0f94SDaniel Pereira de sistema: 641*82da0f94SDaniel Pereira https://lwn.net/Articles/585415/ 642*82da0f94SDaniel Pereira - Artigo da LWN por Michael Kerrisk sobre como lidar com flags desconhecidas 643*82da0f94SDaniel Pereira em uma chamada de sistema: https://lwn.net/Articles/588444/ 644*82da0f94SDaniel Pereira - Artigo da LWN por Jake Edge descrevendo restrições em argumentos de chamadas 645*82da0f94SDaniel Pereira de sistema de 64 bits: https://lwn.net/Articles/311630/ 646*82da0f94SDaniel Pereira - Par de artigos da LWN por David Drysdale que descrevem detalhadamente os 647*82da0f94SDaniel Pereira caminhos de implementação de chamadas de sistema para a v3.14: 648*82da0f94SDaniel Pereira 649*82da0f94SDaniel Pereira - https://lwn.net/Articles/604287/ 650*82da0f94SDaniel Pereira - https://lwn.net/Articles/604515/ 651*82da0f94SDaniel Pereira 652*82da0f94SDaniel Pereira - Os requisitos específicos de arquitetura para chamadas de sistema são 653*82da0f94SDaniel Pereira discutidos na página de manual :manpage:`syscall(2)`: 654*82da0f94SDaniel Pereira http://man7.org/linux/man-pages/man2/syscall.2.html#NOTES 655*82da0f94SDaniel Pereira - E-mails compilados de Linus Torvalds discutindo os problemas com ``ioctl()``: 656*82da0f94SDaniel Pereira https://yarchive.net/comp/linux/ioctl.html 657*82da0f94SDaniel Pereira - "How to not invent kernel interfaces", Arnd Bergmann, 658*82da0f94SDaniel Pereira https://www.ukuug.org/events/linux2007/2007/papers/Bergmann.pdf 659*82da0f94SDaniel Pereira - Artigo da LWN por Michael Kerrisk sobre evitar novos usos de CAP_SYS_ADMIN: 660*82da0f94SDaniel Pereira https://lwn.net/Articles/486306/ 661*82da0f94SDaniel Pereira - Recomendação de Andrew Morton para que todas as informações relacionadas a 662*82da0f94SDaniel Pereira uma nova chamada de sistema venham na mesma thread de e-mail: 663*82da0f94SDaniel Pereira https://lore.kernel.org/r/20140724144747.3041b208832bbdf9fbce5d96@linux-foundation.org 664*82da0f94SDaniel Pereira - Recomendação de Michael Kerrisk para que uma nova chamada de sistema venha 665*82da0f94SDaniel Pereira acompanhada de uma página de manual: 666*82da0f94SDaniel Pereira https://lore.kernel.org/r/CAKgNAkgMA39AfoSoA5Pe1r9N+ZzfYQNvNPvcRN7tOvRb8+v06Q@mail.gmail.com 667*82da0f94SDaniel Pereira - Sugestão de Thomas Gleixner para que a vinculação (wire-up) do x86 esteja em 668*82da0f94SDaniel Pereira um commit separado: 669*82da0f94SDaniel Pereira https://lore.kernel.org/r/alpine.DEB.2.11.1411191249560.3909@nanos 670*82da0f94SDaniel Pereira - Sugestão de Greg Kroah-Hartman de que é bom que novas chamadas de sistema 671*82da0f94SDaniel Pereira venham acompanhadas de uma página de manual e um autoteste: 672*82da0f94SDaniel Pereira https://lore.kernel.org/r/20140320025530.GA25469@kroah.com 673*82da0f94SDaniel Pereira - Discussão de Michael Kerrisk sobre uma nova chamada de sistema versus a 674*82da0f94SDaniel Pereira extensão de :manpage:`prctl(2)`: 675*82da0f94SDaniel Pereira https://lore.kernel.org/r/CAHO5Pa3F2MjfTtfNxa8LbnkeeU8=YJ+9tDqxZpw7Gz59E-4AUg@mail.gmail.com 676*82da0f94SDaniel Pereira - Sugestão de Ingo Molnar de que as chamadas de sistema que envolvem múltiplos 677*82da0f94SDaniel Pereira argumentos devem encapsular esses argumentos em uma struct, a qual inclua um 678*82da0f94SDaniel Pereira campo de tamanho (size) para fins de extensibilidade futura: 679*82da0f94SDaniel Pereira https://lore.kernel.org/r/20150730083831.GA22182@gmail.com 680*82da0f94SDaniel Pereira - Excentricidades de numeração decorrentes do uso (e reuso) de flags do espaço 681*82da0f94SDaniel Pereira de numeração O_*: 682*82da0f94SDaniel Pereira 683*82da0f94SDaniel Pereira - commit 75069f2b5bfb ("vfs: renumber FMODE_NONOTIFY and add to uniqueness 684*82da0f94SDaniel Pereira check") 685*82da0f94SDaniel Pereira - commit 12ed2e36c98a ("fanotify: FMODE_NONOTIFY and __O_SYNC in sparc 686*82da0f94SDaniel Pereira conflict") 687*82da0f94SDaniel Pereira - commit bb458c644a59 ("Safer ABI for O_TMPFILE") 688*82da0f94SDaniel Pereira 689*82da0f94SDaniel Pereira - Discussão de Matthew Wilcox sobre restrições em argumentos de 64 bits: 690*82da0f94SDaniel Pereira https://lore.kernel.org/r/20081212152929.GM26095@parisc-linux.org 691*82da0f94SDaniel Pereira - Recomendação de Greg Kroah-Hartman de que flags desconhecidas devem ser 692*82da0f94SDaniel Pereira fiscalizadas/policiadas: 693*82da0f94SDaniel Pereira https://lore.kernel.org/r/20140717193330.GB4703@kroah.com 694*82da0f94SDaniel Pereira - Recomendação de Linus Torvalds de que as chamadas de sistema x32 devem 695*82da0f94SDaniel Pereira preferir a compatibilidade com as versões de 64 bits em vez das versões de 696*82da0f94SDaniel Pereira 32 bits: 697*82da0f94SDaniel Pereira https://lore.kernel.org/r/CA+55aFxfmwfB7jbbrXxa=K7VBYPfAvmu3XOkGrLbB1UFjX1+Ew@mail.gmail.com 698*82da0f94SDaniel Pereira - Série de patches revisando a infraestrutura da tabela de chamadas de sistema 699*82da0f94SDaniel Pereira para utilizar scripts/syscall.tbl em múltiplas arquiteturas: 700*82da0f94SDaniel Pereira https://lore.kernel.org/lkml/20240704143611.2979589-1-arnd@kernel.org 701