~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/Documentation/translations/sp_SP/process/adding-syscalls.rst

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 .. include:: ../disclaimer-sp.rst
  2 
  3 :Original: :ref:`Documentation/process/adding-syscalls.rst <addsyscalls>`
  4 :Translator: Mauricio Fuentes <mauriciofb@gmail.com>
  5 
  6 .. _sp_addsyscalls:
  7 
  8 Agregando una Nueva Llamada del Sistema
  9 =======================================
 10 
 11 Este documento describe qué involucra agregar una nueva llamada del sistema
 12 al kernel Linux, más allá de la presentación y consejos normales en
 13 :ref:`Documentation/process/submitting-patches.rst <submittingpatches>` que
 14 también puede encontrar traducido a este idioma.
 15 
 16 Alternativas a Llamadas del Sistema
 17 -----------------------------------
 18 
 19 La primera cosa a considerar cuando se agrega una llamada al sistema es si
 20 alguna alternativa es adecuada en su lugar. Aunque las llamadas al sistema
 21 son los puntos de interacción entre el userspace y el kernel más obvios y
 22 tradicionales, existen otras posibilidades -- elija la que mejor se adecúe
 23 a su interfaz.
 24 
 25  - Si se puede hacer que la operación se parezca a un objeto filesystem,
 26    podría tener más sentido crear un nuevo sistema de ficheros o
 27    dispositivo. Esto también hará más fácil encapsular la nueva
 28    funcionalidad en un módulo del kernel en vez de requerir que sea
 29    construido junto al kernel principal.
 30 
 31      - Si la nueva funcionalidad involucra operaciones donde el kernel
 32        notifica al userspace que algo ha pasado, entonces retornar un nuevo
 33        descriptor de archivo para el objeto relevante permite al userspace
 34        usar ``poll``/``select``/``epoll`` para recibir esta notificación.
 35 
 36      - Sin embargo, operaciones que no mapean a operaciones similares a
 37        :manpage:`read(2)`/:manpage:`write(2)` tienen que ser implementadas
 38        como solicitudes :manpage:`ioctl(2)`, las cuales pueden llevar a un
 39        API algo opaca.
 40 
 41  - Si sólo está exponiendo información del runtime, un nuevo nodo en sysfs
 42    (mire ``Documentation/filesystems/sysfs.rst``) o el filesystem ``/proc``
 43    podría ser más adecuado. Sin embargo, acceder a estos mecanismos
 44    requiere que el filesystem relevante esté montado, lo que podría no ser
 45    siempre el caso (e.g. en un ambiente namespaced/sandboxed/chrooted).
 46    Evite agregar cualquier API a debugfs, ya que no se considera una
 47    interfaz (interface) de 'producción' para el userspace.
 48 
 49  - Si la operación es específica a un archivo o descriptor de archivo
 50    específico, entonces la opción de comando adicional :manpage:`fcntl(2)`
 51    podría ser más apropiada. Sin embargo, :manpage:`fcntl(2)` es una
 52    llamada al sistema multiplexada que esconde mucha complejidad, así que
 53    esta opción es mejor cuando la nueva funcion es analogamente cercana a
 54    la funcionalidad existente :manpage:`fcntl(2)`, o la nueva funcionalidad
 55    es muy simple (por ejemplo, definir/obtener un flag simple relacionado a
 56    un descriptor de archivo).
 57 
 58  - Si la operación es específica a un proceso o tarea particular, entonces
 59    un comando adicional :manpage:`prctl(2)` podría ser más apropiado. Tal
 60    como con :manpage:`fcntl(2)`, esta llamada al sistema es un multiplexor
 61    complicado así que está reservado para comandos análogamente cercanos
 62    del existente ``prctl()`` u obtener/definir un flag simple relacionado a
 63    un proceso.
 64 
 65 Diseñando el API: Planeando para extensiones
 66 --------------------------------------------
 67 
 68 Una nueva llamada del sistema forma parte del API del kernel, y tiene que
 69 ser soportada indefinidamente. Como tal, es una muy buena idea discutir
 70 explícitamente el interface en las listas de correo del kernel, y es
 71 importante planear para futuras extensiones del interface.
 72 
 73 (La tabla syscall está poblada con ejemplos históricos donde esto no se
 74 hizo, junto con los correspondientes seguimientos de los system calls --
 75 ``eventfd``/``eventfd2``, ``dup2``/``dup3``, ``inotify_init``/``inotify_init1``,
 76 ``pipe``/``pipe2``, ``renameat``/``renameat2`` -- así que aprenda de la
 77 historia del kernel y planee extensiones desde el inicio.)
 78 
 79 Para llamadas al sistema más simples que sólo toman un par de argumentos,
 80 la forma preferida de permitir futuras extensiones es incluir un argumento
 81 flag a la llamada al sistema. Para asegurarse que el userspace pueda usar
 82 de forma segura estos flags entre versiones del kernel, revise si los flags
 83 contienen cualquier flag desconocido, y rechace la llamada al sistema (con
 84 ``EINVAL``) si ocurre::
 85 
 86     if (flags & ~(THING_FLAG1 | THINGFLAG2 | THING_FLAG3))
 87         return -EINVAL;
 88 
 89 (Si no hay valores de flags usados aún, revise que los argumentos del flag
 90 sean cero.)
 91 
 92 Para llamadas al sistema más sofisticadas que involucran un gran número de
 93 argumentos, es preferible encapsular la mayoría de los argumentos en una
 94 estructura que sea pasada a través de un puntero. Tal estructura puede
 95 hacer frente a futuras extensiones mediante la inclusión de un argumento de
 96 tamaño en la estructura::
 97 
 98     struct xyzzy_params {
 99         u32 size; /* userspace define p->size = sizeof(struct xyzzy_params) */
100         u32 param_1;
101         u64 param_2;
102         u64 param_3;
103     };
104 
105 Siempre que cualquier campo añadido subsecuente, digamos ``param_4``, sea
106 diseñado de forma tal que un valor cero, devuelva el comportamiento previo,
107 entonces permite versiones no coincidentes en ambos sentidos:
108 
109  - Para hacer frente a programas del userspace más modernos, haciendo
110    llamadas a un kernel más antiguo, el código del kernel debe revisar que
111    cualquier memoria más allá del tamaño de la estructura sea cero (revisar
112    de manera efectiva que ``param_4 == 0``).
113  - Para hacer frente a programas antiguos del userspace haciendo llamadas a
114    un kernel más nuevo, el código del kernel puede extender con ceros, una
115    instancia más pequeña de la estructura (definiendo efectivamente
116    ``param_4 == 0``).
117 
118 Revise :manpage:`perf_event_open(2)` y la función ``perf_copy_attr()`` (en
119 ``kernel/events/code.c``) para un ejemplo de esta aproximación.
120 
121 
122 Diseñando el API: Otras consideraciones
123 ---------------------------------------
124 
125 Si su nueva llamada al sistema permite al userspace hacer referencia a un
126 objeto del kernel, esta debería usar un descriptor de archivo como el
127 manipulador de ese objeto -- no invente un nuevo tipo de objeto manipulador
128 userspace cuando el kernel ya tiene mecanismos y semánticas bien definidas
129 para usar los descriptores de archivos.
130 
131 Si su nueva llamada a sistema :manpage:`xyzzy(2)` retorna un nuevo
132 descriptor de archivo, entonces el argumento flag debe incluir un valor que
133 sea equivalente a definir ``O_CLOEXEC`` en el nuevo FD. Esto hace posible
134 al userspace acortar la brecha de tiempo entre ``xyzzy()`` y la llamada a
135 ``fcntl(fd, F_SETFD, FD_CLOEXEC)``, donde un ``fork()`` inesperado y
136 ``execve()`` en otro hilo podrían filtrar un descriptor al programa
137 ejecutado. (Sin embargo, resista la tentación de reusar el valor actual de
138 la constante ``O_CLOEXEC``, ya que es específica de la arquitectura y es
139 parte de un espacio numerado de flags ``O_*`` que está bastante lleno.)
140 
141 Si su llamada de sistema retorna un nuevo descriptor de archivo, debería
142 considerar también que significa usar la familia de llamadas de sistema
143 :manpage:`poll(2)` en ese descriptor de archivo. Hacer un descriptor de
144 archivo listo para leer o escribir es la forma normal para que el kernel
145 indique al espacio de usuario que un evento ha ocurrido en el
146 correspondiente objeto del kernel.
147 
148 Si su nueva llamada de sistema :manpage:`xyzzy(2)` involucra algún nombre
149 de archivo como argumento::
150 
151     int sys_xyzzy(const char __user *path, ..., unsigned int flags);
152 
153 debería considerar también si una versión :manpage:`xyzzyat(2)` es mas
154 apropiada::
155 
156     int sys_xyzzyat(int dfd, const char __user *path, ..., unsigned int flags);
157 
158 Esto permite más flexibilidad en como el userspace especifica el archivo en
159 cuestión; en particular esto permite al userspace pedir la funcionalidad a
160 un descriptor de archivo ya abierto usando el flag ``AT_EMPTY_PATH``,
161 efectivamente dando una operación :manpage:`fxyzzy(3)` gratis::
162 
163  - xyzzyat(AT_FDCWD, path, ..., 0) es equivalente a xyzzy(path, ...)
164  - xyzzyat(fd, "", ..., AT_EMPTY_PATH) es equivalente a fxyzzy(fd, ...)
165 
166 (Para más detalles sobre la explicación racional de las llamadas \*at(),
167 revise el man page :manpage:`openat(2)`; para un ejemplo de AT_EMPTY_PATH,
168 mire el man page :manpage:`fstatat(2)` manpage.)
169 
170 Si su nueva llamada de sistema :manpage:`xyzzy(2)` involucra un parámetro
171 describiendo un describiendo un movimiento dentro de un archivo, ponga de
172 tipo ``loff_t`` para que movimientos de 64-bit puedan ser soportados
173 incluso en arquitecturas de 32-bit.
174 
175 Si su nueva llamada de sistema  :manpage:`xyzzy` involucra una
176 funcionalidad privilegiada, esta necesita ser gobernada por la capability
177 bit linux apropiada (revisado con una llamada a ``capable()``), como se
178 describe en el man page :manpage:`capabilities(7)`. Elija una parte de
179 capability linux que govierne las funcionalidades relacionadas, pero trate
180 de evitar combinar muchas funciones sólo relacionadas vagamente bajo la
181 misma sección, ya que va en contra de los propósitos de las capabilities de
182 dividir el poder del usuario root. En particular, evite agregar nuevos usos
183 de la capacidad ya demasiado general de la capabilities ``CAP_SYS_ADMIN``.
184 
185 Si su nueva llamada de sistema :manpage:`xyzzy(2)` manipula un proceso que
186 no es el proceso invocado, este debería ser restringido (usando una llamada
187 a ``ptrace_may_access()``) de forma que el único proceso con los mismos
188 permisos del proceso objetivo, o con las capacidades (capabilities)
189 necesarias, pueda manipulador el proceso objetivo.
190 
191 Finalmente, debe ser conciente de que algunas arquitecturas no-x86 tienen
192 un manejo más sencillo si los parámetros que son explícitamente 64-bit
193 caigan en argumentos enumerados impares (i.e. parámetros 1,3,5), para
194 permitir el uso de pares contiguos de registros 32-bits. (Este cuidado no
195 aplica si el argumento es parte de una estructura que se pasa a través de
196 un puntero.)
197 
198 Proponiendo el API
199 ------------------
200 
201 Para hacer una nueva llamada al sistema fácil de revisar, es mejor dividir
202 el patchset (conjunto de parches) en trozos separados. Estos deberían
203 incluir al menos los siguientes items como commits distintos (cada uno de
204 los cuales se describirá más abajo):
205 
206  - La implementación central de la llamada al sistema, junto con
207    prototipos, numeración genérica, cambios Kconfig e implementaciones de
208    rutinas de respaldo (fallback stub)
209  - Conectar la nueva llamada a sistema a una arquitectura particular,
210    usualmente x86 (incluyendo todas las x86_64, x86_32 y x32).
211  - Una demostración del use de la nueva llamada a sistema en el userspace
212    vía un selftest en ``tools/testing/selftest/``.
213  - Un borrador de man-page para la nueva llamada a sistema, ya sea como
214    texto plano en la carta de presentación, o como un parche (separado)
215    para el repositorio man-pages.
216 
217 Nuevas propuestas de llamadas de sistema, como cualquier cambio al API del
218 kernel, debería siempre ser copiado a linux-api@vger.kernel.org.
219 
220 
221 Implementation de Llamada de Sistema Generica
222 ---------------------------------------------
223 
224 La entrada principal a su nueva llamada de sistema :manpage:`xyzzy(2)` será
225 llamada ``sys_xyzzy()``, pero incluya este punto de entrada con la macro
226 ``SYSCALL_DEFINEn()`` apropiada en vez de explicitamente. El 'n' indica el
227 numero de argumentos de la llamada de sistema, y la macro toma el nombre de
228 la llamada de sistema seguida por el par (tipo, nombre) para los parámetros
229 como argumentos. Usar esta macro permite a la metadata de la nueva llamada
230 de sistema estar disponible para otras herramientas.
231 
232 El nuevo punto de entrada también necesita un prototipo de función
233 correspondiente en ``include/linux/syscalls.h``,  marcado como asmlinkage
234 para calzar en la manera en que las llamadas de sistema son invocadas::
235 
236     asmlinkage long sys_xyzzy(...);
237 
238 Algunas arquitecturas (e.g. x86) tienen sus propias tablas de syscall
239 específicas para la arquitectura, pero muchas otras arquitecturas comparten
240 una tabla de syscall genéricas. Agrega su nueva llamada de sistema a la
241 lista genérica agregando una entrada a la lista en
242 ``include/uapi/asm-generic/unistd.h``::
243 
244     #define __NR_xyzzy 292
245     __SYSCALL(__NR_xyzzy, sys_xyzzy )
246 
247 También actualice el conteo de __NR_syscalls para reflejar la llamada de
248 sistema adicional, y note que si multiples llamadas de sistema nuevas son
249 añadidas en la misma ventana unida, su nueva llamada de sistema podría
250 tener que ser ajustada para resolver conflictos.
251 
252 El archivo ``kernel/sys_ni.c`` provee una implementación fallback stub
253 (rutina de respaldo) para cada llamada de sistema, retornando ``-ENOSYS``.
254 Incluya su nueva llamada a sistema aquí también::
255 
256     COND_SYSCALL(xyzzy);
257 
258 Su nueva funcionalidad del kernel, y la llamada de sistema que la controla,
259 debería normalmente ser opcional, así que incluya una opción ``CONFIG``
260 (tipicamente en ``init/Kconfig``) para ella. Como es usual para opciones
261 ``CONFIG`` nuevas:
262 
263  - Incluya una descripción para la nueva funcionalidad y llamada al sistema
264    controlada por la opción.
265  - Haga la opción dependiendo de EXPERT si esta debe estar escondida de los
266    usuarios normales.
267  - Haga que cualquier nuevo archivo fuente que implemente la función
268    dependa de la opción CONFIG en el Makefile (e.g.
269    ``obj-$(CONFIG_XYZZY_SYSCALL) += xyzzy.o``).
270  - Revise dos veces que el kernel se siga compilando con la nueva opción
271    CONFIG apagada.
272 
273 Para resumir, necesita un commit que incluya:
274 
275  - una opción ``CONFIG`` para la nueva función, normalmente en ``init/Kconfig``
276  - ``SYSCALL_DEFINEn(xyzzy, ...)`` para el punto de entrada
277  - El correspondiente prototipo en ``include/linux/syscalls.h``
278  - Una entrada genérica en ``include/uapi/asm-generic/unistd.h``
279  - fallback stub en ``kernel/sys_ni.c``
280 
281 
282 Implementación de Llamada de Sistema x86
283 ----------------------------------------
284 
285 Para conectar su nueva llamada de sistema a plataformas x86, necesita
286 actualizar las tablas maestras syscall. Asumiendo que su nueva llamada de
287 sistema ni es especial de alguna manera (revise abajo), esto involucra una
288 entrada "común" (para x86_64 y x86_32) en
289 arch/x86/entry/syscalls/syscall_64.tbl::
290 
291     333   common   xyzz     sys_xyzzy
292 
293 y una entrada "i386" en ``arch/x86/entry/syscalls/syscall_32.tbl``::
294 
295     380   i386     xyzz     sys_xyzzy
296 
297 De nuevo, estos número son propensos de ser cambiados si hay conflictos en
298 la ventana de integración relevante.
299 
300 
301 Compatibilidad de Llamadas de Sistema (Genérica)
302 ------------------------------------------------
303 
304 Para la mayoría de llamadas al sistema la misma implementación 64-bit puede
305 ser invocada incluso cuando el programa de userspace es en si mismo 32-bit;
306 incluso si los parámetros de la llamada de sistema incluyen un puntero
307 explícito, esto es manipulado de forma transparente.
308 
309 Sin embargo, existe un par de situaciones donde se necesita una capa de
310 compatibilidad para lidiar con las diferencias de tamaño entre 32-bit y
311 64-bit.
312 
313 La primera es si el kernel 64-bit también soporta programas del userspace
314 32-bit, y por lo tanto necesita analizar areas de memoria del (``__user``)
315 que podrían tener valores tanto 32-bit como 64-bit. En particular esto se
316 necesita siempre que un argumento de la llamada a sistema es:
317 
318  - un puntero a un puntero
319  - un puntero a un struc conteniendo un puntero (por ejemplo
320    ``struct iovec __user *``)
321  - un puntero a un type entero de tamaño entero variable (``time_t``,
322    ``off_t``, ``long``, ...)
323  - un puntero a un struct conteniendo un type entero de tamaño variable.
324 
325 La segunda situación que requiere una capa de compatibilidad es cuando uno
326 de los argumentos de la llamada a sistema tiene un argumento que es
327 explícitamente 64-bit incluso sobre arquitectura 32-bit, por ejemplo
328 ``loff_t`` o ``__u64``. En este caso, el valor que llega a un kernel 64-bit
329 desde una aplicación de 32-bit se separará en dos valores de 32-bit, los
330 que luego necesitan ser reensamblados en la capa de compatibilidad.
331 
332 (Note que un argumento de una llamada a sistema que sea un puntero a un
333 type explicitamente de 64-bit **no** necesita una capa de compatibilidad;
334 por ejemplo, los argumentos de :manpage:`splice(2)`) del tipo
335 ``loff_t __user *`` no significan la necesidad de una llamada a sistema
336 ``compat_``.)
337 
338 La versión compatible de la llamada de sistema se llama
339 ``compat_sys_xyzzy()``, y se agrega con la macro
340 ``COMPAT_SYSCALL_DEFINEn``, de manera análoga a SYSCALL_DEFINEn. Esta
341 versión de la implementación se ejecuta como parte de un kernel de 64-bit,
342 pero espera recibir parametros con valores 32-bit y hace lo que tenga que
343 hacer para tratar con ellos. (Típicamente, la versión ``compat_sys_``
344 convierte los valores a versiones de 64 bits y llama a la versión ``sys_``
345 o ambas llaman a una función de implementación interna común.)
346 
347 El punto de entrada compat también necesita un prototipo de función
348 correspondiente, en ``include/linux/compat.h``, marcado como asmlinkage
349 para igualar la forma en que las llamadas al sistema son invocadas::
350 
351     asmlinkage long compat_sys_xyzzy(...);
352 
353 Si la nueva llamada al sistema involucra una estructura que que se dispone
354 de forma distinta en sistema de 32-bit y 64-bit, digamos
355 ``struct xyzzy_args``, entonces el archivo de cabecera
356 include/linux/compat.h también debería incluir una versión compatible de la
357 estructura (``struct compat_xyzzy_args``) donde cada campo de tamaño
358 variable tiene el tipo ``compat_`` apropiado que corresponde al tipo en
359 ``struct xyzzy_args``. La rutina ``compat_sys_xyzzy()`` puede entonces usar
360 esta estructura ``compat_`` para analizar los argumentos de una invocación
361 de 32-bit.
362 
363 Por ejemplo, si hay campos::
364 
365     struct xyzzy_args {
366       const char __user *ptr;
367       __kernel_long_t varying_val;
368       u64 fixed_val;
369       /* ... */
370     };
371 
372 en struct xyzzy_args, entonces struct compat_xyzzy_args debe tener::
373 
374     struct compat_xyzzy_args {
375       compat_uptr_t ptr;
376       compat_long_t varying_val;
377       u64 fixed_val;
378       /* ... */
379     };
380 
381 la lista genérica de llamadas al sistema también necesita ajustes para
382 permitir la versión compat; la entrada en
383 ``include/uapi/asm-generic/unistd.h`` debería usar ``__SC_COMP`` en vez de
384 ``__SYSCALL``::
385 
386     #define __NR_xyzzy 292
387     __SC_COMP(__NR_xyzzy, sys_xyzzy, compat_sys_xyzzy)
388 
389 Para resumir, necesita:
390 
391   - una ``COMPAT_SYSCALL_DEFINEn(xyzzy, ...)`` para el punto de entrada de compat.
392   - el prototipo correspondiente en ``include/linux/compat.h``
393   - (en caso de ser necesario) un struct de mapeo de 32-bit en ``include/linux/compat.h``
394   - una instancia de ``__SC_COMP`` no ``__SYSCALL`` en ``include/uapi/asm-generic/unistd.h``
395 
396 Compatibilidad de Llamadas de Sistema (x86)
397 -------------------------------------------
398 
399 Para conectar la arquitectura x86 de una llamada al sistema con una versión
400 de compatibilidad, las entradas en las tablas de syscall deben ser
401 ajustadas.
402 
403 Primero, la entrada en ``arch/x86/entry/syscalls/syscall_32.tbl`` recibe
404 una columna extra para indicar que un programa del userspace de 32-bit
405 corriendo en un kernel de 64-bit debe llegar al punto de entrada compat::
406 
407     380  i386     xyzzy      sys_xyzzy    __ia32_compat_sys_xyzzy
408 
409 Segundo, tienes que averiguar qué debería pasar para la versión x32 ABI de
410 la nueva llamada al sistema. Aquí hay una elección: el diseño de los
411 argumentos debería coincidir con la versión de 64-bit o la versión de
412 32-bit.
413 
414 Si hay involucrado un puntero-a-puntero, la decisión es fácil: x32 es
415 ILP32, por lo que el diseño debe coincidir con la versión 32-bit, y la
416 entrada en ``arch/x86/entry/syscalls/syscall_64.tbl`` se divide para que
417 progamas 32-bit lleguen al envoltorio de compatibilidad::
418 
419     333   64        xyzzy       sys_xyzzy
420     ...
421     555   x32       xyzzy       __x32_compat_sys_xyzzy
422 
423 Si no hay punteros involucrados, entonces es preferible reutilizar el system
424 call 64-bit para el x32 ABI  (y consecuentemente la entrada en
425 arch/x86/entry/syscalls/syscall_64.tbl no se cambia).
426 
427 En cualquier caso, debes revisar que lo tipos involucrados en su diseño de
428 argumentos de hecho asigne exactamente de x32 (-mx32) a 32-bit(-m32) o
429 equivalentes 64-bit (-m64).
430 
431 
432 Llamadas de Sistema Retornando a Otros Lugares
433 ----------------------------------------------
434 
435 Para la mayoría de las llamadas al sistema, una vez que se la llamada al
436 sistema se ha completado el programa de usuario continúa exactamente donde
437 quedó -- en la siguiente instrucción, con el stack igual y la mayoría de
438 los registros igual que antes de la llamada al sistema, y con el mismo
439 espacio en la memoria virtual.
440 
441 Sin embargo, unas pocas llamadas al sistema hacen las cosas diferente.
442 Estas podrían retornar a una ubicación distinta (``rt_sigreturn``) o
443 cambiar el espacio de memoria (``fork``/``vfork``/``clone``) o incluso de
444 arquitectura (``execve``/``execveat``) del programa.
445 
446 Para permitir esto, la implementación del kernel de la llamada al sistema
447 podría necesitar guardar y restaurar registros adicionales al stak del
448 kernel, brindandole control completo de donde y cómo la ejecución continúa
449 después de la llamada a sistema.
450 
451 Esto es arch-specific, pero típicamente involucra definir puntos de entrada
452 assembly que guardan/restauran registros adicionales e invocan el punto de
453 entrada real de la llamada a sistema.
454 
455 Para x86_64, esto es implementado como un punto de entrada ``stub_xyzzy``
456 en ``arch/x86/entry/entry_64.S``, y la entrada en la tabla syscall
457 (``arch/x86/entry/syscalls/syscall_32.tbl``) es ajustada para calzar::
458 
459     333   common  xyzzy     stub_xyzzy
460 
461 El equivalente para programas 32-bit corriendo en un kernel 64-bit es
462 normalmente llamado ``stub32_xyzzy`` e implementado en
463 ``arch/x86/entry/entry_64_compat.S``, con el correspondiente ajuste en la
464 tabla syscall en ``arch/x86/syscalls/syscall_32.tbl``::
465 
466     380    i386       xyzzy     sys_xyzzy     stub32_xyzzy
467 
468 Si la llamada a sistema necesita una capa de compatibilidad (como en la
469 sección anterior) entonces la versión ``stub32_`` necesita llamar a la
470 versión ``compat_sys_`` de la llamada a sistema, en vez de la versión
471 nativa de 64-bit. También, si la implementación de la versión x32 ABI no es
472 comun con la versión x86_64, entonces su tabla syscall también necesitará
473 invocar un stub que llame a la versión ``compat_sys_``
474 
475 Para completar, también es agradable configurar un mapeo de modo que el
476 user-mode linux todavía funcione -- su tabla syscall referenciará
477 stub_xyzzy, pero el UML construido no incluye una implementación
478 ``arch/x86/entry/entry_64.S``. Arreglar esto es tan simple como agregar un
479 #define a ``arch/x86/um/sys_call_table_64.c``::
480 
481     #define stub_xyzzy sys_xyzzy
482 
483 
484 Otros detalles
485 --------------
486 
487 La mayoría del kernel trata las llamadas a sistema de manera genérica, pero
488 está la excepción ocasional que pueda requerir actualización para su
489 llamada a sistema particular.
490 
491 El subsistema de auditoría es un caso especial; este incluye funciones
492 (arch-specific) que clasifican algunos tipos especiales de llamadas al
493 sistema -- específicamente file open (``open``/``openat``), program
494 execution (``execve`` /``execveat``) o operaciones multiplexores de socket
495 (``socketcall``). Si su nueva llamada de sistema es análoga a alguna de
496 estas, entonces el sistema auditor debe ser actualizado.
497 
498 Más generalmente, si existe una llamada al sistema que sea análoga a su
499 nueva llamada al sistema, entonces vale la pena hacer un grep a todo el
500 kernel de la llamada a sistema existente, para revisar que no exista otro
501 caso especial.
502 
503 
504 Testing
505 -------
506 
507 Una nueva llamada al sistema debe obviamente ser probada; también es útil
508 proveer a los revisores con una demostración de cómo los programas del
509 userspace usarán la llamada al sistema. Una buena forma de combinar estos
510 objetivos es incluir un simple programa self-test en un nuevo directorio
511 bajo ``tools/testing/selftests/``.
512 
513 Para una nueva llamada al sistema, obviamente no habrá una función
514 envoltorio libc por lo que el test necesitará ser invocado usando
515 ``syscall()``; también, si la llamada al sistema involucra una nueva
516 estructura userspace-visible, el encabezado correspondiente necesitará ser
517 instalado para compilar el test.
518 
519 Asegure que selftest corra satisfactoriamente en todas las arquitecturas
520 soportadas. Por ejemplo, revise si funciona cuando es compilado como un
521 x86_64 (-m64), x86_32 (-m32) y x32 (-mx32) programa ABI.
522 
523 Para pruebas más amplias y exhautivas de la nueva funcionalidad, también
524 debería considerar agregar tests al Linus Test Project, o al proyecto
525 xfstests para cambios filesystem-related
526 
527   - https://linux-test-project.github.io/
528   - git://git.kernel.org/pub/scm/fs/xfs/xfstests-dev.git
529 
530 
531 Man Page
532 --------
533 
534 Todas las llamada al sistema nueva deben venir con un man page completo,
535 idealmente usando groff markup, pero texto plano también funciona. Si se
536 usa groff, es útil incluir una versión ASCII pre-renderizada del man-page
537 en el cover del email para el patchset, para la conveniencia de los
538 revisores.
539 
540 El man page debe ser cc'do a linux-man@vger.kernel.org
541 Para más detalles, revise https://www.kernel.org/doc/man-pages/patches.html
542 
543 
544 No invoque las llamadas de sistemas en el kernel
545 ------------------------------------------------
546 
547 Las llamadas al sistema son, cómo se declaró más arriba, puntos de
548 interacción entre el userspace y el kernel. Por lo tanto, las funciones de
549 llamada al sistema como ``sys_xyzzy()`` o ``compat_sys_xyzzy()`` deberían
550 ser llamadas sólo desde el userspace vía la tabla de syscall, pero no de
551 otro lugar en el kernel. Si la funcionalidad syscall es útil para ser usada
552 dentro del kernel, necesita ser compartida entre syscalls nuevas o
553 antiguas, o necesita ser compartida entre una syscall y su variante de
554 compatibilidad, esta debería ser implementada mediante una función "helper"
555 (como ``ksys_xyzzy()``). Esta función del kernel puede ahora ser llamada
556 dentro del syscall stub (``sys_xyzzy()``), la syscall stub de
557 compatibilidad (``compat_sys_xyzzy()``), y/o otro código del kernel.
558 
559 Al menos en 64-bit x86, será un requerimiento duro desde la v4.17 en
560 adelante no invocar funciones de llamada al sistema (system call) en el
561 kernel. Este usa una convención de llamada diferente para llamadas al
562 sistema donde ``struct pt_regs`` es decodificado on-the-fly en un
563 envoltorio syscall que luego entrega el procesamiento al syscall real. Esto
564 significa que sólo aquellos parámetros que son realmente necesarios para
565 una syscall específica son pasados durante la entrada del syscall, en vez
566 de llenar en seis registros de CPU con contenido random del userspace todo
567 el tiempo (los cuales podrían causar serios problemas bajando la cadena de
568 llamadas).
569 
570 Más aún, reglas sobre cómo se debería acceder a la data pueden diferir
571 entre la data del kernel y la data de usuario. Esta es otra razón por la
572 cual llamar a ``sys_xyzzy()`` es generalmente una mala idea.
573 
574 Excepciones a esta regla están permitidas solamente en overrides
575 específicos de arquitectura, envoltorios de compatibilidad específicos de
576 arquitectura, u otro código en arch/.
577 
578 
579 Referencias y fuentes
580 ---------------------
581 
582  - Artículo LWN de Michael Kerrisk sobre el uso de argumentos flags en llamadas al
583    sistema:
584    https://lwn.net/Articles/585415/
585  - Artículo LWN de Michael Kerrisk sobre cómo manejar flags desconocidos en una
586    llamada al sistema: https://lwn.net/Articles/588444/
587  - Artículo LWN de Jake Edge describiendo restricciones en argumentos en
588    64-bit system call: https://lwn.net/Articles/311630/
589  - Par de artículos LWN de David Drysdale que describen la ruta de implementación
590    de llamadas al sistema en detalle para v3.14:
591 
592     - https://lwn.net/Articles/604287/
593     - https://lwn.net/Articles/604515/
594 
595  - Requerimientos arquitectura-específicos para llamadas al sistema son discutidos en el
596    :manpage:`syscall(2)` man-page:
597    http://man7.org/linux/man-pages/man2/syscall.2.html#NOTES
598  - Recopilación de emails de Linus Torvalds discutiendo problemas con ``ioctl()``:
599    https://yarchive.net/comp/linux/ioctl.html
600  - "How to not invent kernel interfaces", Arnd Bergmann,
601    https://www.ukuug.org/events/linux2007/2007/papers/Bergmann.pdf
602  - Artículo LWN de Michael Kerrisk sobre evitar nuevos usos de CAP_SYS_ADMIN:
603    https://lwn.net/Articles/486306/
604  - Recomendaciones de Andrew Morton que toda la información relacionada a una nueva
605    llamada al sistema debe venir en el mismo hilo de correos:
606    https://lore.kernel.org/r/20140724144747.3041b208832bbdf9fbce5d96@linux-foundation.org
607  - Recomendaciones de Michael Kerrisk que una nueva llamada al sistema debe venir
608    con un man-page: https://lore.kernel.org/r/CAKgNAkgMA39AfoSoA5Pe1r9N+ZzfYQNvNPvcRN7tOvRb8+v06Q@mail.gmail.com
609  - Sugerencias de Thomas Gleixner que conexiones x86 deben ir en commits
610    separados: https://lore.kernel.org/r/alpine.DEB.2.11.1411191249560.3909@nanos
611  - Sugerencias de Greg Kroah-Hartman que es bueno para las nueva llamadas al sistema
612    que vengan con man-page y selftest: https://lore.kernel.org/r/20140320025530.GA25469@kroah.com
613  - Discusión de Michael Kerrisk de nuevas system call vs. extensiones :manpage:`prctl(2)`:
614    https://lore.kernel.org/r/CAHO5Pa3F2MjfTtfNxa8LbnkeeU8=YJ+9tDqxZpw7Gz59E-4AUg@mail.gmail.com
615  - Sugerencias de Ingo Molnar que llamadas al sistema que involucran múltiples
616    argumentos deben encapsular estos argumentos en una estructura, la cual incluye
617    un campo de tamaño para futura extensibilidad: https://lore.kernel.org/r/20150730083831.GA22182@gmail.com
618  - Enumerando rarezas por la (re-)utilización de O_* numbering space flags:
619 
620     - commit 75069f2b5bfb ("vfs: renumber FMODE_NONOTIFY and add to uniqueness
621       check")
622     - commit 12ed2e36c98a ("fanotify: FMODE_NONOTIFY and __O_SYNC in sparc
623       conflict")
624     - commit bb458c644a59 ("Safer ABI for O_TMPFILE")
625 
626  - Discusión de Matthew Wilcox sobre las restricciones en argumentos 64-bit:
627    https://lore.kernel.org/r/20081212152929.GM26095@parisc-linux.org
628  - Recomendaciones de Greg Kroah-Hartman sobre flags desconocidos deben ser
629    vigilados: https://lore.kernel.org/r/20140717193330.GB4703@kroah.com
630  - Recomendaciones de Linus Torvalds que las llamadas al sistema x32 deben favorecer
631    compatibilidad con versiones 64-bit sobre versiones 32-bit:
632    https://lore.kernel.org/r/CA+55aFxfmwfB7jbbrXxa=K7VBYPfAvmu3XOkGrLbB1UFjX1+Ew@mail.gmail.com

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php