xref: /linux/Documentation/translations/pt_BR/process/adding-syscalls.rst (revision 72fdff1416e280e2baaa3cca69574defb998437e)
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