brintos

brintos / linux-shallow public Read only

0
0
Text · 29.8 KiB · f21504c Raw
633 lines · plain
1.. include:: ../disclaimer-sp.rst2 3:Original: :ref:`Documentation/process/adding-syscalls.rst <addsyscalls>`4:Translator: Mauricio Fuentes <mauriciofb@gmail.com>5 6.. _sp_addsyscalls:7 8Agregando una Nueva Llamada del Sistema9=======================================10 11Este documento describe qué involucra agregar una nueva llamada del sistema12al kernel Linux, más allá de la presentación y consejos normales en13:ref:`Documentation/process/submitting-patches.rst <submittingpatches>` que14también puede encontrar traducido a este idioma.15 16Alternativas a Llamadas del Sistema17-----------------------------------18 19La primera cosa a considerar cuando se agrega una llamada al sistema es si20alguna alternativa es adecuada en su lugar. Aunque las llamadas al sistema21son los puntos de interacción entre el userspace y el kernel más obvios y22tradicionales, existen otras posibilidades -- elija la que mejor se adecúe23a 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 o27   dispositivo. Esto también hará más fácil encapsular la nueva28   funcionalidad en un módulo del kernel en vez de requerir que sea29   construido junto al kernel principal.30 31     - Si la nueva funcionalidad involucra operaciones donde el kernel32       notifica al userspace que algo ha pasado, entonces retornar un nuevo33       descriptor de archivo para el objeto relevante permite al userspace34       usar ``poll``/``select``/``epoll`` para recibir esta notificación.35 36     - Sin embargo, operaciones que no mapean a operaciones similares a37       :manpage:`read(2)`/:manpage:`write(2)` tienen que ser implementadas38       como solicitudes :manpage:`ioctl(2)`, las cuales pueden llevar a un39       API algo opaca.40 41 - Si sólo está exponiendo información del runtime, un nuevo nodo en sysfs42   (mire ``Documentation/filesystems/sysfs.rst``) o el filesystem ``/proc``43   podría ser más adecuado. Sin embargo, acceder a estos mecanismos44   requiere que el filesystem relevante esté montado, lo que podría no ser45   siempre el caso (e.g. en un ambiente namespaced/sandboxed/chrooted).46   Evite agregar cualquier API a debugfs, ya que no se considera una47   interfaz (interface) de 'producción' para el userspace.48 49 - Si la operación es específica a un archivo o descriptor de archivo50   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 una52   llamada al sistema multiplexada que esconde mucha complejidad, así que53   esta opción es mejor cuando la nueva funcion es analogamente cercana a54   la funcionalidad existente :manpage:`fcntl(2)`, o la nueva funcionalidad55   es muy simple (por ejemplo, definir/obtener un flag simple relacionado a56   un descriptor de archivo).57 58 - Si la operación es específica a un proceso o tarea particular, entonces59   un comando adicional :manpage:`prctl(2)` podría ser más apropiado. Tal60   como con :manpage:`fcntl(2)`, esta llamada al sistema es un multiplexor61   complicado así que está reservado para comandos análogamente cercanos62   del existente ``prctl()`` u obtener/definir un flag simple relacionado a63   un proceso.64 65Diseñando el API: Planeando para extensiones66--------------------------------------------67 68Una nueva llamada del sistema forma parte del API del kernel, y tiene que69ser soportada indefinidamente. Como tal, es una muy buena idea discutir70explícitamente el interface en las listas de correo del kernel, y es71importante planear para futuras extensiones del interface.72 73(La tabla syscall está poblada con ejemplos históricos donde esto no se74hizo, 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 la77historia del kernel y planee extensiones desde el inicio.)78 79Para llamadas al sistema más simples que sólo toman un par de argumentos,80la forma preferida de permitir futuras extensiones es incluir un argumento81flag a la llamada al sistema. Para asegurarse que el userspace pueda usar82de forma segura estos flags entre versiones del kernel, revise si los flags83contienen cualquier flag desconocido, y rechace la llamada al sistema (con84``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 flag90sean cero.)91 92Para llamadas al sistema más sofisticadas que involucran un gran número de93argumentos, es preferible encapsular la mayoría de los argumentos en una94estructura que sea pasada a través de un puntero. Tal estructura puede95hacer frente a futuras extensiones mediante la inclusión de un argumento de96tamañ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 105Siempre que cualquier campo añadido subsecuente, digamos ``param_4``, sea106diseñado de forma tal que un valor cero, devuelva el comportamiento previo,107entonces permite versiones no coincidentes en ambos sentidos:108 109 - Para hacer frente a programas del userspace más modernos, haciendo110   llamadas a un kernel más antiguo, el código del kernel debe revisar que111   cualquier memoria más allá del tamaño de la estructura sea cero (revisar112   de manera efectiva que ``param_4 == 0``).113 - Para hacer frente a programas antiguos del userspace haciendo llamadas a114   un kernel más nuevo, el código del kernel puede extender con ceros, una115   instancia más pequeña de la estructura (definiendo efectivamente116   ``param_4 == 0``).117 118Revise :manpage:`perf_event_open(2)` y la función ``perf_copy_attr()`` (en119``kernel/events/code.c``) para un ejemplo de esta aproximación.120 121 122Diseñando el API: Otras consideraciones123---------------------------------------124 125Si su nueva llamada al sistema permite al userspace hacer referencia a un126objeto del kernel, esta debería usar un descriptor de archivo como el127manipulador de ese objeto -- no invente un nuevo tipo de objeto manipulador128userspace cuando el kernel ya tiene mecanismos y semánticas bien definidas129para usar los descriptores de archivos.130 131Si su nueva llamada a sistema :manpage:`xyzzy(2)` retorna un nuevo132descriptor de archivo, entonces el argumento flag debe incluir un valor que133sea equivalente a definir ``O_CLOEXEC`` en el nuevo FD. Esto hace posible134al userspace acortar la brecha de tiempo entre ``xyzzy()`` y la llamada a135``fcntl(fd, F_SETFD, FD_CLOEXEC)``, donde un ``fork()`` inesperado y136``execve()`` en otro hilo podrían filtrar un descriptor al programa137ejecutado. (Sin embargo, resista la tentación de reusar el valor actual de138la constante ``O_CLOEXEC``, ya que es específica de la arquitectura y es139parte de un espacio numerado de flags ``O_*`` que está bastante lleno.)140 141Si su llamada de sistema retorna un nuevo descriptor de archivo, debería142considerar también que significa usar la familia de llamadas de sistema143:manpage:`poll(2)` en ese descriptor de archivo. Hacer un descriptor de144archivo listo para leer o escribir es la forma normal para que el kernel145indique al espacio de usuario que un evento ha ocurrido en el146correspondiente objeto del kernel.147 148Si su nueva llamada de sistema :manpage:`xyzzy(2)` involucra algún nombre149de archivo como argumento::150 151    int sys_xyzzy(const char __user *path, ..., unsigned int flags);152 153debería considerar también si una versión :manpage:`xyzzyat(2)` es mas154apropiada::155 156    int sys_xyzzyat(int dfd, const char __user *path, ..., unsigned int flags);157 158Esto permite más flexibilidad en como el userspace especifica el archivo en159cuestión; en particular esto permite al userspace pedir la funcionalidad a160un descriptor de archivo ya abierto usando el flag ``AT_EMPTY_PATH``,161efectivamente 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(),167revise el man page :manpage:`openat(2)`; para un ejemplo de AT_EMPTY_PATH,168mire el man page :manpage:`fstatat(2)` manpage.)169 170Si su nueva llamada de sistema :manpage:`xyzzy(2)` involucra un parámetro171describiendo un describiendo un movimiento dentro de un archivo, ponga de172tipo ``loff_t`` para que movimientos de 64-bit puedan ser soportados173incluso en arquitecturas de 32-bit.174 175Si su nueva llamada de sistema  :manpage:`xyzzy` involucra una176funcionalidad privilegiada, esta necesita ser gobernada por la capability177bit linux apropiada (revisado con una llamada a ``capable()``), como se178describe en el man page :manpage:`capabilities(7)`. Elija una parte de179capability linux que govierne las funcionalidades relacionadas, pero trate180de evitar combinar muchas funciones sólo relacionadas vagamente bajo la181misma sección, ya que va en contra de los propósitos de las capabilities de182dividir el poder del usuario root. En particular, evite agregar nuevos usos183de la capacidad ya demasiado general de la capabilities ``CAP_SYS_ADMIN``.184 185Si su nueva llamada de sistema :manpage:`xyzzy(2)` manipula un proceso que186no es el proceso invocado, este debería ser restringido (usando una llamada187a ``ptrace_may_access()``) de forma que el único proceso con los mismos188permisos del proceso objetivo, o con las capacidades (capabilities)189necesarias, pueda manipulador el proceso objetivo.190 191Finalmente, debe ser conciente de que algunas arquitecturas no-x86 tienen192un manejo más sencillo si los parámetros que son explícitamente 64-bit193caigan en argumentos enumerados impares (i.e. parámetros 1,3,5), para194permitir el uso de pares contiguos de registros 32-bits. (Este cuidado no195aplica si el argumento es parte de una estructura que se pasa a través de196un puntero.)197 198Proponiendo el API199------------------200 201Para hacer una nueva llamada al sistema fácil de revisar, es mejor dividir202el patchset (conjunto de parches) en trozos separados. Estos deberían203incluir al menos los siguientes items como commits distintos (cada uno de204los cuales se describirá más abajo):205 206 - La implementación central de la llamada al sistema, junto con207   prototipos, numeración genérica, cambios Kconfig e implementaciones de208   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 userspace212   vía un selftest en ``tools/testing/selftest/``.213 - Un borrador de man-page para la nueva llamada a sistema, ya sea como214   texto plano en la carta de presentación, o como un parche (separado)215   para el repositorio man-pages.216 217Nuevas propuestas de llamadas de sistema, como cualquier cambio al API del218kernel, debería siempre ser copiado a linux-api@vger.kernel.org.219 220 221Implementation de Llamada de Sistema Generica222---------------------------------------------223 224La entrada principal a su nueva llamada de sistema :manpage:`xyzzy(2)` será225llamada ``sys_xyzzy()``, pero incluya este punto de entrada con la macro226``SYSCALL_DEFINEn()`` apropiada en vez de explicitamente. El 'n' indica el227numero de argumentos de la llamada de sistema, y la macro toma el nombre de228la llamada de sistema seguida por el par (tipo, nombre) para los parámetros229como argumentos. Usar esta macro permite a la metadata de la nueva llamada230de sistema estar disponible para otras herramientas.231 232El nuevo punto de entrada también necesita un prototipo de función233correspondiente en ``include/linux/syscalls.h``,  marcado como asmlinkage234para calzar en la manera en que las llamadas de sistema son invocadas::235 236    asmlinkage long sys_xyzzy(...);237 238Algunas arquitecturas (e.g. x86) tienen sus propias tablas de syscall239específicas para la arquitectura, pero muchas otras arquitecturas comparten240una tabla de syscall genéricas. Agrega su nueva llamada de sistema a la241lista genérica agregando una entrada a la lista en242``include/uapi/asm-generic/unistd.h``::243 244    #define __NR_xyzzy 292245    __SYSCALL(__NR_xyzzy, sys_xyzzy )246 247También actualice el conteo de __NR_syscalls para reflejar la llamada de248sistema adicional, y note que si multiples llamadas de sistema nuevas son249añadidas en la misma ventana unida, su nueva llamada de sistema podría250tener que ser ajustada para resolver conflictos.251 252El archivo ``kernel/sys_ni.c`` provee una implementación fallback stub253(rutina de respaldo) para cada llamada de sistema, retornando ``-ENOSYS``.254Incluya su nueva llamada a sistema aquí también::255 256    COND_SYSCALL(xyzzy);257 258Su nueva funcionalidad del kernel, y la llamada de sistema que la controla,259debería normalmente ser opcional, así que incluya una opción ``CONFIG``260(tipicamente en ``init/Kconfig``) para ella. Como es usual para opciones261``CONFIG`` nuevas:262 263 - Incluya una descripción para la nueva funcionalidad y llamada al sistema264   controlada por la opción.265 - Haga la opción dependiendo de EXPERT si esta debe estar escondida de los266   usuarios normales.267 - Haga que cualquier nuevo archivo fuente que implemente la función268   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ón271   CONFIG apagada.272 273Para 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 entrada277 - 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 282Implementación de Llamada de Sistema x86283----------------------------------------284 285Para conectar su nueva llamada de sistema a plataformas x86, necesita286actualizar las tablas maestras syscall. Asumiendo que su nueva llamada de287sistema ni es especial de alguna manera (revise abajo), esto involucra una288entrada "común" (para x86_64 y x86_32) en289arch/x86/entry/syscalls/syscall_64.tbl::290 291    333   common   xyzz     sys_xyzzy292 293y una entrada "i386" en ``arch/x86/entry/syscalls/syscall_32.tbl``::294 295    380   i386     xyzz     sys_xyzzy296 297De nuevo, estos número son propensos de ser cambiados si hay conflictos en298la ventana de integración relevante.299 300 301Compatibilidad de Llamadas de Sistema (Genérica)302------------------------------------------------303 304Para la mayoría de llamadas al sistema la misma implementación 64-bit puede305ser invocada incluso cuando el programa de userspace es en si mismo 32-bit;306incluso si los parámetros de la llamada de sistema incluyen un puntero307explícito, esto es manipulado de forma transparente.308 309Sin embargo, existe un par de situaciones donde se necesita una capa de310compatibilidad para lidiar con las diferencias de tamaño entre 32-bit y31164-bit.312 313La primera es si el kernel 64-bit también soporta programas del userspace31432-bit, y por lo tanto necesita analizar areas de memoria del (``__user``)315que podrían tener valores tanto 32-bit como 64-bit. En particular esto se316necesita siempre que un argumento de la llamada a sistema es:317 318 - un puntero a un puntero319 - un puntero a un struc conteniendo un puntero (por ejemplo320   ``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 325La segunda situación que requiere una capa de compatibilidad es cuando uno326de los argumentos de la llamada a sistema tiene un argumento que es327explícitamente 64-bit incluso sobre arquitectura 32-bit, por ejemplo328``loff_t`` o ``__u64``. En este caso, el valor que llega a un kernel 64-bit329desde una aplicación de 32-bit se separará en dos valores de 32-bit, los330que 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 un333type explicitamente de 64-bit **no** necesita una capa de compatibilidad;334por ejemplo, los argumentos de :manpage:`splice(2)`) del tipo335``loff_t __user *`` no significan la necesidad de una llamada a sistema336``compat_``.)337 338La versión compatible de la llamada de sistema se llama339``compat_sys_xyzzy()``, y se agrega con la macro340``COMPAT_SYSCALL_DEFINEn``, de manera análoga a SYSCALL_DEFINEn. Esta341versión de la implementación se ejecuta como parte de un kernel de 64-bit,342pero espera recibir parametros con valores 32-bit y hace lo que tenga que343hacer para tratar con ellos. (Típicamente, la versión ``compat_sys_``344convierte los valores a versiones de 64 bits y llama a la versión ``sys_``345o ambas llaman a una función de implementación interna común.)346 347El punto de entrada compat también necesita un prototipo de función348correspondiente, en ``include/linux/compat.h``, marcado como asmlinkage349para igualar la forma en que las llamadas al sistema son invocadas::350 351    asmlinkage long compat_sys_xyzzy(...);352 353Si la nueva llamada al sistema involucra una estructura que que se dispone354de forma distinta en sistema de 32-bit y 64-bit, digamos355``struct xyzzy_args``, entonces el archivo de cabecera356include/linux/compat.h también debería incluir una versión compatible de la357estructura (``struct compat_xyzzy_args``) donde cada campo de tamaño358variable tiene el tipo ``compat_`` apropiado que corresponde al tipo en359``struct xyzzy_args``. La rutina ``compat_sys_xyzzy()`` puede entonces usar360esta estructura ``compat_`` para analizar los argumentos de una invocación361de 32-bit.362 363Por 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 372en 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 381la lista genérica de llamadas al sistema también necesita ajustes para382permitir la versión compat; la entrada en383``include/uapi/asm-generic/unistd.h`` debería usar ``__SC_COMP`` en vez de384``__SYSCALL``::385 386    #define __NR_xyzzy 292387    __SC_COMP(__NR_xyzzy, sys_xyzzy, compat_sys_xyzzy)388 389Para 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 396Compatibilidad de Llamadas de Sistema (x86)397-------------------------------------------398 399Para conectar la arquitectura x86 de una llamada al sistema con una versión400de compatibilidad, las entradas en las tablas de syscall deben ser401ajustadas.402 403Primero, la entrada en ``arch/x86/entry/syscalls/syscall_32.tbl`` recibe404una columna extra para indicar que un programa del userspace de 32-bit405corriendo en un kernel de 64-bit debe llegar al punto de entrada compat::406 407    380  i386     xyzzy      sys_xyzzy    __ia32_compat_sys_xyzzy408 409Segundo, tienes que averiguar qué debería pasar para la versión x32 ABI de410la nueva llamada al sistema. Aquí hay una elección: el diseño de los411argumentos debería coincidir con la versión de 64-bit o la versión de41232-bit.413 414Si hay involucrado un puntero-a-puntero, la decisión es fácil: x32 es415ILP32, por lo que el diseño debe coincidir con la versión 32-bit, y la416entrada en ``arch/x86/entry/syscalls/syscall_64.tbl`` se divide para que417progamas 32-bit lleguen al envoltorio de compatibilidad::418 419    333   64        xyzzy       sys_xyzzy420    ...421    555   x32       xyzzy       __x32_compat_sys_xyzzy422 423Si no hay punteros involucrados, entonces es preferible reutilizar el system424call 64-bit para el x32 ABI  (y consecuentemente la entrada en425arch/x86/entry/syscalls/syscall_64.tbl no se cambia).426 427En cualquier caso, debes revisar que lo tipos involucrados en su diseño de428argumentos de hecho asigne exactamente de x32 (-mx32) a 32-bit(-m32) o429equivalentes 64-bit (-m64).430 431 432Llamadas de Sistema Retornando a Otros Lugares433----------------------------------------------434 435Para la mayoría de las llamadas al sistema, una vez que se la llamada al436sistema se ha completado el programa de usuario continúa exactamente donde437quedó -- en la siguiente instrucción, con el stack igual y la mayoría de438los registros igual que antes de la llamada al sistema, y con el mismo439espacio en la memoria virtual.440 441Sin embargo, unas pocas llamadas al sistema hacen las cosas diferente.442Estas podrían retornar a una ubicación distinta (``rt_sigreturn``) o443cambiar el espacio de memoria (``fork``/``vfork``/``clone``) o incluso de444arquitectura (``execve``/``execveat``) del programa.445 446Para permitir esto, la implementación del kernel de la llamada al sistema447podría necesitar guardar y restaurar registros adicionales al stak del448kernel, brindandole control completo de donde y cómo la ejecución continúa449después de la llamada a sistema.450 451Esto es arch-specific, pero típicamente involucra definir puntos de entrada452assembly que guardan/restauran registros adicionales e invocan el punto de453entrada real de la llamada a sistema.454 455Para x86_64, esto es implementado como un punto de entrada ``stub_xyzzy``456en ``arch/x86/entry/entry_64.S``, y la entrada en la tabla syscall457(``arch/x86/entry/syscalls/syscall_32.tbl``) es ajustada para calzar::458 459    333   common  xyzzy     stub_xyzzy460 461El equivalente para programas 32-bit corriendo en un kernel 64-bit es462normalmente llamado ``stub32_xyzzy`` e implementado en463``arch/x86/entry/entry_64_compat.S``, con el correspondiente ajuste en la464tabla syscall en ``arch/x86/syscalls/syscall_32.tbl``::465 466    380    i386       xyzzy     sys_xyzzy     stub32_xyzzy467 468Si la llamada a sistema necesita una capa de compatibilidad (como en la469sección anterior) entonces la versión ``stub32_`` necesita llamar a la470versión ``compat_sys_`` de la llamada a sistema, en vez de la versión471nativa de 64-bit. También, si la implementación de la versión x32 ABI no es472comun con la versión x86_64, entonces su tabla syscall también necesitará473invocar un stub que llame a la versión ``compat_sys_``474 475Para completar, también es agradable configurar un mapeo de modo que el476user-mode linux todavía funcione -- su tabla syscall referenciará477stub_xyzzy, pero el UML construido no incluye una implementación478``arch/x86/entry/entry_64.S``. Arreglar esto es tan simple como agregar un479#define a ``arch/x86/um/sys_call_table_64.c``::480 481    #define stub_xyzzy sys_xyzzy482 483 484Otros detalles485--------------486 487La mayoría del kernel trata las llamadas a sistema de manera genérica, pero488está la excepción ocasional que pueda requerir actualización para su489llamada a sistema particular.490 491El subsistema de auditoría es un caso especial; este incluye funciones492(arch-specific) que clasifican algunos tipos especiales de llamadas al493sistema -- específicamente file open (``open``/``openat``), program494execution (``execve`` /``execveat``) o operaciones multiplexores de socket495(``socketcall``). Si su nueva llamada de sistema es análoga a alguna de496estas, entonces el sistema auditor debe ser actualizado.497 498Más generalmente, si existe una llamada al sistema que sea análoga a su499nueva llamada al sistema, entonces vale la pena hacer un grep a todo el500kernel de la llamada a sistema existente, para revisar que no exista otro501caso especial.502 503 504Testing505-------506 507Una nueva llamada al sistema debe obviamente ser probada; también es útil508proveer a los revisores con una demostración de cómo los programas del509userspace usarán la llamada al sistema. Una buena forma de combinar estos510objetivos es incluir un simple programa self-test en un nuevo directorio511bajo ``tools/testing/selftests/``.512 513Para una nueva llamada al sistema, obviamente no habrá una función514envoltorio libc por lo que el test necesitará ser invocado usando515``syscall()``; también, si la llamada al sistema involucra una nueva516estructura userspace-visible, el encabezado correspondiente necesitará ser517instalado para compilar el test.518 519Asegure que selftest corra satisfactoriamente en todas las arquitecturas520soportadas. Por ejemplo, revise si funciona cuando es compilado como un521x86_64 (-m64), x86_32 (-m32) y x32 (-mx32) programa ABI.522 523Para pruebas más amplias y exhautivas de la nueva funcionalidad, también524debería considerar agregar tests al Linus Test Project, o al proyecto525xfstests para cambios filesystem-related526 527  - https://linux-test-project.github.io/528  - git://git.kernel.org/pub/scm/fs/xfs/xfstests-dev.git529 530 531Man Page532--------533 534Todas las llamada al sistema nueva deben venir con un man page completo,535idealmente usando groff markup, pero texto plano también funciona. Si se536usa groff, es útil incluir una versión ASCII pre-renderizada del man-page537en el cover del email para el patchset, para la conveniencia de los538revisores.539 540El man page debe ser cc'do a linux-man@vger.kernel.org541Para más detalles, revise https://www.kernel.org/doc/man-pages/patches.html542 543 544No invoque las llamadas de sistemas en el kernel545------------------------------------------------546 547Las llamadas al sistema son, cómo se declaró más arriba, puntos de548interacción entre el userspace y el kernel. Por lo tanto, las funciones de549llamada al sistema como ``sys_xyzzy()`` o ``compat_sys_xyzzy()`` deberían550ser llamadas sólo desde el userspace vía la tabla de syscall, pero no de551otro lugar en el kernel. Si la funcionalidad syscall es útil para ser usada552dentro del kernel, necesita ser compartida entre syscalls nuevas o553antiguas, o necesita ser compartida entre una syscall y su variante de554compatibilidad, esta debería ser implementada mediante una función "helper"555(como ``ksys_xyzzy()``). Esta función del kernel puede ahora ser llamada556dentro del syscall stub (``sys_xyzzy()``), la syscall stub de557compatibilidad (``compat_sys_xyzzy()``), y/o otro código del kernel.558 559Al menos en 64-bit x86, será un requerimiento duro desde la v4.17 en560adelante no invocar funciones de llamada al sistema (system call) en el561kernel. Este usa una convención de llamada diferente para llamadas al562sistema donde ``struct pt_regs`` es decodificado on-the-fly en un563envoltorio syscall que luego entrega el procesamiento al syscall real. Esto564significa que sólo aquellos parámetros que son realmente necesarios para565una syscall específica son pasados durante la entrada del syscall, en vez566de llenar en seis registros de CPU con contenido random del userspace todo567el tiempo (los cuales podrían causar serios problemas bajando la cadena de568llamadas).569 570Más aún, reglas sobre cómo se debería acceder a la data pueden diferir571entre la data del kernel y la data de usuario. Esta es otra razón por la572cual llamar a ``sys_xyzzy()`` es generalmente una mala idea.573 574Excepciones a esta regla están permitidas solamente en overrides575específicos de arquitectura, envoltorios de compatibilidad específicos de576arquitectura, u otro código en arch/.577 578 579Referencias y fuentes580---------------------581 582 - Artículo LWN de Michael Kerrisk sobre el uso de argumentos flags en llamadas al583   sistema:584   https://lwn.net/Articles/585415/585 - Artículo LWN de Michael Kerrisk sobre cómo manejar flags desconocidos en una586   llamada al sistema: https://lwn.net/Articles/588444/587 - Artículo LWN de Jake Edge describiendo restricciones en argumentos en588   64-bit system call: https://lwn.net/Articles/311630/589 - Par de artículos LWN de David Drysdale que describen la ruta de implementación590   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 el596   :manpage:`syscall(2)` man-page:597   http://man7.org/linux/man-pages/man2/syscall.2.html#NOTES598 - Recopilación de emails de Linus Torvalds discutiendo problemas con ``ioctl()``:599   https://yarchive.net/comp/linux/ioctl.html600 - "How to not invent kernel interfaces", Arnd Bergmann,601   https://www.ukuug.org/events/linux2007/2007/papers/Bergmann.pdf602 - 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 nueva605   llamada al sistema debe venir en el mismo hilo de correos:606   https://lore.kernel.org/r/20140724144747.3041b208832bbdf9fbce5d96@linux-foundation.org607 - Recomendaciones de Michael Kerrisk que una nueva llamada al sistema debe venir608   con un man-page: https://lore.kernel.org/r/CAKgNAkgMA39AfoSoA5Pe1r9N+ZzfYQNvNPvcRN7tOvRb8+v06Q@mail.gmail.com609 - Sugerencias de Thomas Gleixner que conexiones x86 deben ir en commits610   separados: https://lore.kernel.org/r/alpine.DEB.2.11.1411191249560.3909@nanos611 - Sugerencias de Greg Kroah-Hartman que es bueno para las nueva llamadas al sistema612   que vengan con man-page y selftest: https://lore.kernel.org/r/20140320025530.GA25469@kroah.com613 - 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.com615 - Sugerencias de Ingo Molnar que llamadas al sistema que involucran múltiples616   argumentos deben encapsular estos argumentos en una estructura, la cual incluye617   un campo de tamaño para futura extensibilidad: https://lore.kernel.org/r/20150730083831.GA22182@gmail.com618 - Enumerando rarezas por la (re-)utilización de O_* numbering space flags:619 620    - commit 75069f2b5bfb ("vfs: renumber FMODE_NONOTIFY and add to uniqueness621      check")622    - commit 12ed2e36c98a ("fanotify: FMODE_NONOTIFY and __O_SYNC in sparc623      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.org628 - Recomendaciones de Greg Kroah-Hartman sobre flags desconocidos deben ser629   vigilados: https://lore.kernel.org/r/20140717193330.GB4703@kroah.com630 - Recomendaciones de Linus Torvalds que las llamadas al sistema x32 deben favorecer631   compatibilidad con versiones 64-bit sobre versiones 32-bit:632   https://lore.kernel.org/r/CA+55aFxfmwfB7jbbrXxa=K7VBYPfAvmu3XOkGrLbB1UFjX1+Ew@mail.gmail.com633