644 lines · plain
1.. include:: ../disclaimer-ita.rst2 3:Original: :ref:`Documentation/process/adding-syscalls.rst <addsyscalls>`4:Translator: Federico Vaga <federico.vaga@vaga.pv.it>5 6.. _it_addsyscalls:7 8Aggiungere una nuova chiamata di sistema9========================================10 11Questo documento descrive quello che è necessario sapere per aggiungere12nuove chiamate di sistema al kernel Linux; questo è da considerarsi come13un'aggiunta ai soliti consigli su come proporre nuove modifiche14:ref:`Documentation/translations/it_IT/process/submitting-patches.rst <it_submittingpatches>`.15 16 17Alternative alle chiamate di sistema18------------------------------------19 20La prima considerazione da fare quando si aggiunge una nuova chiamata di21sistema è quella di valutare le alternative. Nonostante le chiamate di sistema22siano il punto di interazione fra spazio utente e kernel più tradizionale ed23ovvio, esistono altre possibilità - scegliete quella che meglio si adatta alle24vostra interfaccia.25 26 - Se le operazioni coinvolte possono rassomigliare a quelle di un filesystem,27 allora potrebbe avere molto più senso la creazione di un nuovo filesystem o28 dispositivo. Inoltre, questo rende più facile incapsulare la nuova29 funzionalità in un modulo kernel piuttosto che essere sviluppata nel cuore30 del kernel.31 32 - Se la nuova funzionalità prevede operazioni dove il kernel notifica33 lo spazio utente su un avvenimento, allora restituire un descrittore34 di file all'oggetto corrispondente permette allo spazio utente di35 utilizzare ``poll``/``select``/``epoll`` per ricevere quelle notifiche.36 - Tuttavia, le operazioni che non si sposano bene con operazioni tipo37 :manpage:`read(2)`/:manpage:`write(2)` dovrebbero essere implementate38 come chiamate :manpage:`ioctl(2)`, il che potrebbe portare ad un'API in39 un qualche modo opaca.40 41 - Se dovete esporre solo delle informazioni sul sistema, un nuovo nodo in42 sysfs (vedere ``Documentation/filesystems/sysfs.rst``) o43 in procfs potrebbe essere sufficiente. Tuttavia, l'accesso a questi44 meccanismi richiede che il filesystem sia montato, il che potrebbe non45 essere sempre vero (per esempio, in ambienti come namespace/sandbox/chroot).46 Evitate d'aggiungere nuove API in debugfs perché questo non viene47 considerata un'interfaccia di 'produzione' verso lo spazio utente.48 - Se l'operazione è specifica ad un particolare file o descrittore, allora49 potrebbe essere appropriata l'aggiunta di un comando :manpage:`fcntl(2)`.50 Tuttavia, :manpage:`fcntl(2)` è una chiamata di sistema multiplatrice che51 nasconde una notevole complessità, quindi è ottima solo quando la nuova52 funzione assomiglia a quelle già esistenti in :manpage:`fcntl(2)`, oppure53 la nuova funzionalità è veramente semplice (per esempio, leggere/scrivere54 un semplice flag associato ad un descrittore di file).55 - Se l'operazione è specifica ad un particolare processo, allora56 potrebbe essere appropriata l'aggiunta di un comando :manpage:`prctl(2)`.57 Come per :manpage:`fcntl(2)`, questa chiamata di sistema è un complesso58 multiplatore quindi è meglio usarlo per cose molto simili a quelle esistenti59 nel comando ``prctl`` oppure per leggere/scrivere un semplice flag relativo60 al processo.61 62 63Progettare l'API: pianificare le estensioni64-------------------------------------------65 66Una nuova chiamata di sistema diventerà parte dell'API del kernel, e67dev'essere supportata per un periodo indefinito. Per questo, è davvero68un'ottima idea quella di discutere apertamente l'interfaccia sulla lista69di discussione del kernel, ed è altrettanto importante pianificarne eventuali70estensioni future.71 72(Nella tabella delle chiamate di sistema sono disseminati esempi dove questo73non fu fatto, assieme ai corrispondenti aggiornamenti -74``eventfd``/``eventfd2``, ``dup2``/``dup3``, ``inotify_init``/``inotify_init1``,75``pipe``/``pipe2``, ``renameat``/``renameat2`` --quindi imparate dalla storia76del kernel e pianificate le estensioni fin dall'inizio)77 78Per semplici chiamate di sistema che accettano solo un paio di argomenti,79il modo migliore di permettere l'estensibilità è quello di includere un80argomento *flags* alla chiamata di sistema. Per assicurarsi che i programmi81dello spazio utente possano usare in sicurezza *flags* con diverse versioni82del kernel, verificate se *flags* contiene un qualsiasi valore sconosciuto,83in qual caso rifiutate la chiamata di sistema (con ``EINVAL``)::84 85 if (flags & ~(THING_FLAG1 | THING_FLAG2 | THING_FLAG3))86 return -EINVAL;87 88(Se *flags* non viene ancora utilizzato, verificate che l'argomento sia zero)89 90Per chiamate di sistema più sofisticate che coinvolgono un numero più grande di91argomenti, il modo migliore è quello di incapsularne la maggior parte in una92struttura dati che verrà passata per puntatore. Questa struttura potrà93funzionare con future estensioni includendo un campo *size*::94 95 struct xyzzy_params {96 u32 size; /* userspace sets p->size = sizeof(struct xyzzy_params) */97 u32 param_1;98 u64 param_2;99 u64 param_3;100 };101 102Fintanto che un qualsiasi campo nuovo, diciamo ``param_4``, è progettato per103offrire il comportamento precedente quando vale zero, allora questo permetterà104di gestire un conflitto di versione in entrambe le direzioni:105 106 - un vecchio kernel può gestire l'accesso di una versione moderna di un107 programma in spazio utente verificando che la memoria oltre la dimensione108 della struttura dati attesa sia zero (in pratica verificare che109 ``param_4 == 0``).110 - un nuovo kernel può gestire l'accesso di una versione vecchia di un111 programma in spazio utente estendendo la struttura dati con zeri (in pratica112 ``param_4 = 0``).113 114Vedere :manpage:`perf_event_open(2)` e la funzione ``perf_copy_attr()`` (in115``kernel/events/core.c``) per un esempio pratico di questo approccio.116 117 118Progettare l'API: altre considerazioni119--------------------------------------120 121Se la vostra nuova chiamata di sistema permette allo spazio utente di fare122riferimento ad un oggetto del kernel, allora questa dovrebbe usare un123descrittore di file per accesso all'oggetto - non inventatevi nuovi tipi di124accesso da spazio utente quando il kernel ha già dei meccanismi e una semantica125ben definita per utilizzare i descrittori di file.126 127Se la vostra nuova chiamata di sistema :manpage:`xyzzy(2)` ritorna un nuovo128descrittore di file, allora l'argomento *flags* dovrebbe includere un valore129equivalente a ``O_CLOEXEC`` per i nuovi descrittori. Questo rende possibile,130nello spazio utente, la chiusura della finestra temporale fra le chiamate a131``xyzzy()`` e ``fcntl(fd, F_SETFD, FD_CLOEXEC)``, dove un inaspettato132``fork()`` o ``execve()`` potrebbe trasferire il descrittore al programma133eseguito (Comunque, resistete alla tentazione di riutilizzare il valore di134``O_CLOEXEC`` dato che è specifico dell'architettura e fa parte di una135enumerazione di flag ``O_*`` che è abbastanza ricca).136 137Se la vostra nuova chiamata di sistema ritorna un nuovo descrittore di file,138dovreste considerare che significato avrà l'uso delle chiamate di sistema139della famiglia di :manpage:`poll(2)`. Rendere un descrittore di file pronto140per la lettura o la scrittura è il tipico modo del kernel per notificare lo141spazio utente circa un evento associato all'oggetto del kernel.142 143Se la vostra nuova chiamata di sistema :manpage:`xyzzy(2)` ha un argomento144che è il percorso ad un file::145 146 int sys_xyzzy(const char __user *path, ..., unsigned int flags);147 148dovreste anche considerare se non sia più appropriata una versione149:manpage:`xyzzyat(2)`::150 151 int sys_xyzzyat(int dfd, const char __user *path, ..., unsigned int flags);152 153Questo permette più flessibilità su come lo spazio utente specificherà il file154in questione; in particolare, permette allo spazio utente di richiedere la155funzionalità su un descrittore di file già aperto utilizzando il *flag*156``AT_EMPTY_PATH``, in pratica otterremmo gratuitamente l'operazione157:manpage:`fxyzzy(3)`::158 159 - xyzzyat(AT_FDCWD, path, ..., 0) is equivalent to xyzzy(path,...)160 - xyzzyat(fd, "", ..., AT_EMPTY_PATH) is equivalent to fxyzzy(fd, ...)161 162(Per maggiori dettagli sulla logica delle chiamate \*at(), leggete la pagina163man :manpage:`openat(2)`; per un esempio di AT_EMPTY_PATH, leggere la pagina164man :manpage:`fstatat(2)`).165 166Se la vostra nuova chiamata di sistema :manpage:`xyzzy(2)` prevede un parametro167per descrivere uno scostamento all'interno di un file, usate ``loff_t`` come168tipo cosicché scostamenti a 64-bit potranno essere supportati anche su169architetture a 32-bit.170 171Se la vostra nuova chiamata di sistema :manpage:`xyzzy(2)` prevede l'uso di172funzioni riservate, allora dev'essere gestita da un opportuno bit di privilegio173(verificato con una chiamata a ``capable()``), come descritto nella pagina man174:manpage:`capabilities(7)`. Scegliete un bit di privilegio già esistente per175gestire la funzionalità associata, ma evitate la combinazione di diverse176funzionalità vagamente collegate dietro lo stesso bit, in quanto va contro il177principio di *capabilities* di separare i poteri di root. In particolare,178evitate di aggiungere nuovi usi al fin-troppo-generico privilegio179``CAP_SYS_ADMIN``.180 181Se la vostra nuova chiamata di sistema :manpage:`xyzzy(2)` manipola altri182processi oltre a quello chiamato, allora dovrebbe essere limitata (usando183la chiamata ``ptrace_may_access()``) di modo che solo un processo chiamante184con gli stessi permessi del processo in oggetto, o con i necessari privilegi,185possa manipolarlo.186 187Infine, state attenti che in alcune architetture non-x86 la vita delle chiamate188di sistema con argomenti a 64-bit viene semplificata se questi argomenti189ricadono in posizioni dispari (pratica, i parametri 1, 3, 5); questo permette190l'uso di coppie contigue di registri a 32-bit. (Questo non conta se gli191argomenti sono parte di una struttura dati che viene passata per puntatore).192 193 194Proporre l'API195--------------196 197Al fine di rendere le nuove chiamate di sistema di facile revisione, è meglio198che dividiate le modifiche i pezzi separati. Questi dovrebbero includere199almeno le seguenti voci in *commit* distinti (ognuno dei quali sarà descritto200più avanti):201 202 - l'essenza dell'implementazione della chiamata di sistema, con i prototipi,203 i numeri generici, le modifiche al Kconfig e l'implementazione *stub* di204 ripiego.205 - preparare la nuova chiamata di sistema per un'architettura specifica,206 solitamente x86 (ovvero tutti: x86_64, x86_32 e x32).207 - un programma di auto-verifica da mettere in ``tools/testing/selftests/``208 che mostri l'uso della chiamata di sistema.209 - una bozza di pagina man per la nuova chiamata di sistema. Può essere210 scritta nell'email di presentazione, oppure come modifica vera e propria211 al repositorio delle pagine man.212 213Le proposte di nuove chiamate di sistema, come ogni altro modifica all'API del214kernel, deve essere sottomessa alla lista di discussione215linux-api@vger.kernel.org.216 217 218Implementazione di chiamate di sistema generiche219------------------------------------------------220 221Il principale punto d'accesso alla vostra nuova chiamata di sistema222:manpage:`xyzzy(2)` verrà chiamato ``sys_xyzzy()``; ma, piuttosto che in modo223esplicito, lo aggiungerete tramite la macro ``SYSCALL_DEFINEn``. La 'n'224indica il numero di argomenti della chiamata di sistema; la macro ha come225argomento il nome della chiamata di sistema, seguito dalle coppie (tipo, nome)226per definire i suoi parametri. L'uso di questa macro permette di avere227i metadati della nuova chiamata di sistema disponibili anche per altri228strumenti.229 230Il nuovo punto d'accesso necessita anche del suo prototipo di funzione in231``include/linux/syscalls.h``, marcato come asmlinkage di modo da abbinargli232il modo in cui quelle chiamate di sistema verranno invocate::233 234 asmlinkage long sys_xyzzy(...);235 236Alcune architetture (per esempio x86) hanno le loro specifiche tabelle di237chiamate di sistema (syscall), ma molte altre architetture condividono una238tabella comune di syscall. Aggiungete alla lista generica la vostra nuova239chiamata di sistema aggiungendo un nuovo elemento alla lista in240``include/uapi/asm-generic/unistd.h``::241 242 #define __NR_xyzzy 292243 __SYSCALL(__NR_xyzzy, sys_xyzzy)244 245Aggiornate anche il contatore __NR_syscalls di modo che sia coerente con246l'aggiunta della nuove chiamate di sistema; va notato che se più di una nuova247chiamata di sistema viene aggiunga nella stessa finestra di sviluppo, il numero248della vostra nuova syscall potrebbe essere aggiustato al fine di risolvere i249conflitti.250 251Il file ``kernel/sys_ni.c`` fornisce le implementazioni *stub* di ripiego che252ritornano ``-ENOSYS``. Aggiungete la vostra nuova chiamata di sistema anche253qui::254 255 COND_SYSCALL(xyzzy);256 257La vostra nuova funzionalità del kernel, e la chiamata di sistema che la258controlla, dovrebbero essere opzionali. Quindi, aggiungete un'opzione259``CONFIG`` (solitamente in ``init/Kconfig``). Come al solito per le nuove260opzioni ``CONFIG``:261 262 - Includete una descrizione della nuova funzionalità e della chiamata di263 sistema che la controlla.264 - Rendete l'opzione dipendente da EXPERT se dev'essere nascosta agli utenti265 normali.266 - Nel Makefile, rendere tutti i nuovi file sorgenti, che implementano la267 nuova funzionalità, dipendenti dall'opzione CONFIG (per esempio268 ``obj-$(CONFIG_XYZZY_SYSCALL) += xyzzy.o``).269 - Controllate due volte che sia possibile generare il kernel con la nuova270 opzione CONFIG disabilitata.271 272Per riassumere, vi serve un *commit* che includa:273 274 - un'opzione ``CONFIG``per la nuova funzione, normalmente in ``init/Kconfig``275 - ``SYSCALL_DEFINEn(xyzzy, ...)`` per il punto d'accesso276 - il corrispondente prototipo in ``include/linux/syscalls.h``277 - un elemento nella tabella generica in ``include/uapi/asm-generic/unistd.h``278 - *stub* di ripiego in ``kernel/sys_ni.c``279 280 281Implementazione delle chiamate di sistema x86282---------------------------------------------283 284Per collegare la vostra nuova chiamate di sistema alle piattaforme x86,285dovete aggiornate la tabella principale di syscall. Assumendo che la vostra286nuova chiamata di sistema non sia particolarmente speciale (vedere sotto),287dovete aggiungere un elemento *common* (per x86_64 e x32) in288arch/x86/entry/syscalls/syscall_64.tbl::289 290 333 common xyzzy sys_xyzzy291 292e un elemento per *i386* ``arch/x86/entry/syscalls/syscall_32.tbl``::293 294 380 i386 xyzzy sys_xyzzy295 296Ancora una volta, questi numeri potrebbero essere cambiati se generano297conflitti durante la finestra di integrazione.298 299 300Chiamate di sistema compatibili (generico)301------------------------------------------302 303Per molte chiamate di sistema, la stessa implementazione a 64-bit può essere304invocata anche quando il programma in spazio utente è a 32-bit; anche se la305chiamata di sistema include esplicitamente un puntatore, questo viene gestito306in modo trasparente.307 308Tuttavia, ci sono un paio di situazione dove diventa necessario avere un309livello di gestione della compatibilità per risolvere le differenze di310dimensioni fra 32-bit e 64-bit.311 312Il primo caso è quando un kernel a 64-bit supporta anche programmi in spazio313utente a 32-bit, perciò dovrà ispezionare aree della memoria (``__user``) che314potrebbero contenere valori a 32-bit o a 64-bit. In particolar modo, questo315è necessario quando un argomento di una chiamata di sistema è:316 317 - un puntatore ad un puntatore318 - un puntatore ad una struttura dati contenente a sua volta un puntatore319 ( ad esempio ``struct iovec __user *``)320 - un puntatore ad un tipo intero di dimensione variabile (``time_t``,321 ``off_t``, ``long``, ...)322 - un puntatore ad una struttura dati contenente un tipo intero di dimensione323 variabile.324 325Il secondo caso che richiede un livello di gestione della compatibilità è326quando uno degli argomenti di una chiamata a sistema è esplicitamente un tipo327a 64-bit anche su architetture a 32-bit, per esempio ``loff_t`` o ``__u64``.328In questo caso, un valore che arriva ad un kernel a 64-bit da un'applicazione329a 32-bit verrà diviso in due valori a 32-bit che dovranno essere riassemblati330in questo livello di compatibilità.331 332(Da notare che non serve questo livello di compatibilità per argomenti che333sono puntatori ad un tipo esplicitamente a 64-bit; per esempio, in334:manpage:`splice(2)` l'argomento di tipo ``loff_t __user *`` non necessita335di una chiamata di sistema ``compat_``)336 337La versione compatibile della nostra chiamata di sistema si chiamerà338``compat_sys_xyzzy()``, e viene aggiunta utilizzando la macro339``COMPAT_SYSCALL_DEFINEn()`` (simile a SYSCALL_DEFINEn). Questa versione340dell'implementazione è parte del kernel a 64-bit ma accetta parametri a 32-bit341che trasformerà secondo le necessità (tipicamente, la versione342``compat_sys_`` converte questi valori nello loro corrispondente a 64-bit e343può chiamare la versione ``sys_`` oppure invocare una funzione che implementa344le parti comuni).345 346Il punto d'accesso *compat* deve avere il corrispondente prototipo di funzione347in ``include/linux/compat.h``, marcato come asmlinkage di modo da abbinargli348il modo in cui quelle chiamate di sistema verranno invocate::349 350 asmlinkage long compat_sys_xyzzy(...);351 352Se la chiamata di sistema prevede una struttura dati organizzata in modo353diverso per sistemi a 32-bit e per quelli a 64-bit, diciamo354``struct xyzzy_args``, allora il file d'intestazione355``then the include/linux/compat.h`` deve includere la sua versione356*compatibile* (``struct compat_xyzzy_args``); ogni variabile con357dimensione variabile deve avere il proprio tipo ``compat_`` corrispondente358a quello in ``struct xyzzy_args``. La funzione ``compat_sys_xyzzy()``359può usare la struttura ``compat_`` per analizzare gli argomenti ricevuti360da una chiamata a 32-bit.361 362Per esempio, se avete i seguenti campi::363 364 struct xyzzy_args {365 const char __user *ptr;366 __kernel_long_t varying_val;367 u64 fixed_val;368 /* ... */369 };370 371nella struttura ``struct xyzzy_args``, allora la struttura372``struct compat_xyzzy_args`` dovrebbe avere::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 generica delle chiamate di sistema ha bisogno di essere382aggiustata al fine di permettere l'uso della versione *compatibile*;383la voce in ``include/uapi/asm-generic/unistd.h`` dovrebbero usare384``__SC_COMP`` piuttosto di ``__SYSCALL``::385 386 #define __NR_xyzzy 292387 __SC_COMP(__NR_xyzzy, sys_xyzzy, compat_sys_xyzzy)388 389Riassumendo, vi serve:390 391 - un ``COMPAT_SYSCALL_DEFINEn(xyzzy, ...)`` per il punto d'accesso392 *compatibile*393 - un prototipo in ``include/linux/compat.h``394 - (se necessario) una struttura di compatibilità a 32-bit in395 ``include/linux/compat.h``396 - una voce ``__SC_COMP``, e non ``__SYSCALL``, in397 ``include/uapi/asm-generic/unistd.h``398 399Compatibilità delle chiamate di sistema (x86)400---------------------------------------------401 402Per collegare una chiamata di sistema, su un'architettura x86, con la sua403versione *compatibile*, è necessario aggiustare la voce nella tabella404delle syscall.405 406Per prima cosa, la voce in ``arch/x86/entry/syscalls/syscall_32.tbl`` prende407un argomento aggiuntivo per indicare che un programma in spazio utente408a 32-bit, eseguito su un kernel a 64-bit, dovrebbe accedere tramite il punto409d'accesso compatibile::410 411 380 i386 xyzzy sys_xyzzy __ia32_compat_sys_xyzzy412 413Secondo, dovete capire cosa dovrebbe succedere alla nuova chiamata di sistema414per la versione dell'ABI x32. Qui C'è una scelta da fare: gli argomenti415possono corrisponde alla versione a 64-bit o a quella a 32-bit.416 417Se c'è un puntatore ad un puntatore, la decisione è semplice: x32 è ILP32,418quindi gli argomenti dovrebbero corrispondere a quelli a 32-bit, e la voce in419``arch/x86/entry/syscalls/syscall_64.tbl`` sarà divisa cosicché i programmi420x32 eseguano la chiamata *compatibile*::421 422 333 64 xyzzy sys_xyzzy423 ...424 555 x32 xyzzy __x32_compat_sys_xyzzy425 426Se non ci sono puntatori, allora è preferibile riutilizzare la chiamata di427sistema a 64-bit per l'ABI x32 (e di conseguenza la voce in428arch/x86/entry/syscalls/syscall_64.tbl rimane immutata).429 430In ambo i casi, dovreste verificare che i tipi usati dagli argomenti431abbiano un'esatta corrispondenza da x32 (-mx32) al loro equivalente a43232-bit (-m32) o 64-bit (-m64).433 434 435Chiamate di sistema che ritornano altrove436-----------------------------------------437 438Nella maggior parte delle chiamate di sistema, al termine della loro439esecuzione, i programmi in spazio utente riprendono esattamente dal punto440in cui si erano interrotti -- quindi dall'istruzione successiva, con lo441stesso *stack* e con la maggior parte del registri com'erano stati442lasciati prima della chiamata di sistema, e anche con la stessa memoria443virtuale.444 445Tuttavia, alcune chiamata di sistema fanno le cose in modo differente.446Potrebbero ritornare ad un punto diverso (``rt_sigreturn``) o cambiare447la memoria in spazio utente (``fork``/``vfork``/``clone``) o perfino448l'architettura del programma (``execve``/``execveat``).449 450Per permettere tutto ciò, l'implementazione nel kernel di questo tipo di451chiamate di sistema potrebbero dover salvare e ripristinare registri452aggiuntivi nello *stack* del kernel, permettendo così un controllo completo453su dove e come l'esecuzione dovrà continuare dopo l'esecuzione della454chiamata di sistema.455 456Queste saranno specifiche per ogni architettura, ma tipicamente si definiscono457dei punti d'accesso in *assembly* per salvare/ripristinare i registri458aggiuntivi e quindi chiamare il vero punto d'accesso per la chiamata di459sistema.460 461Per l'architettura x86_64, questo è implementato come un punto d'accesso462``stub_xyzzy`` in ``arch/x86/entry/entry_64.S``, e la voce nella tabella463di syscall (``arch/x86/entry/syscalls/syscall_64.tbl``) verrà corretta di464conseguenza::465 466 333 common xyzzy stub_xyzzy467 468L'equivalente per programmi a 32-bit eseguiti su un kernel a 64-bit viene469normalmente chiamato ``stub32_xyzzy`` e implementato in470``arch/x86/entry/entry_64_compat.S`` con la corrispondente voce nella tabella471di syscall ``arch/x86/entry/syscalls/syscall_32.tbl`` corretta nel472seguente modo::473 474 380 i386 xyzzy sys_xyzzy stub32_xyzzy475 476Se una chiamata di sistema necessita di un livello di compatibilità (come477nella sezione precedente), allora la versione ``stub32_`` deve invocare478la versione ``compat_sys_`` piuttosto che quella nativa a 64-bit. In aggiunta,479se l'implementazione dell'ABI x32 è diversa da quella x86_64, allora la sua480voce nella tabella di syscall dovrà chiamare uno *stub* che invoca la versione481``compat_sys_``,482 483Per completezza, sarebbe carino impostare una mappatura cosicché484*user-mode* Linux (UML) continui a funzionare -- la sua tabella di syscall485farà riferimento a stub_xyzzy, ma UML non include l'implementazione486in ``arch/x86/entry/entry_64.S`` (perché UML simula i registri eccetera).487Correggerlo è semplice, basta aggiungere una #define in488``arch/x86/um/sys_call_table_64.c``::489 490 #define stub_xyzzy sys_xyzzy491 492 493Altri dettagli494--------------495 496La maggior parte dei kernel tratta le chiamate di sistema allo stesso modo,497ma possono esserci rare eccezioni per le quali potrebbe essere necessario498l'aggiornamento della vostra chiamata di sistema.499 500Il sotto-sistema di controllo (*audit subsystem*) è uno di questi casi501speciali; esso include (per architettura) funzioni che classificano alcuni502tipi di chiamate di sistema -- in particolare apertura dei file503(``open``/``openat``), esecuzione dei programmi (``execve``/``exeveat``)504oppure multiplatori di socket (``socketcall``). Se la vostra nuova chiamata505di sistema è simile ad una di queste, allora il sistema di controllo dovrebbe506essere aggiornato.507 508Più in generale, se esiste una chiamata di sistema che è simile alla vostra,509vale la pena fare una ricerca con ``grep`` su tutto il kernel per la chiamata510di sistema esistente per verificare che non ci siano altri casi speciali.511 512 513Verifica514--------515 516Una nuova chiamata di sistema dev'essere, ovviamente, provata; è utile fornire517ai revisori un programma in spazio utente che mostri l'uso della chiamata di518sistema. Un buon modo per combinare queste cose è quello di aggiungere un519semplice programma di auto-verifica in una nuova cartella in520``tools/testing/selftests/``.521 522Per una nuova chiamata di sistema, ovviamente, non ci sarà alcuna funzione523in libc e quindi il programma di verifica dovrà invocarla usando ``syscall()``;524inoltre, se la nuova chiamata di sistema prevede un nuova struttura dati525visibile in spazio utente, il file d'intestazione necessario dev'essere526installato al fine di compilare il programma.527 528Assicuratevi che il programma di auto-verifica possa essere eseguito529correttamente su tutte le architetture supportate. Per esempio, verificate che530funzioni quando viene compilato per x86_64 (-m64), x86_32 (-m32) e x32 (-mx32).531 532Al fine di una più meticolosa ed estesa verifica della nuova funzionalità,533dovreste considerare l'aggiunta di nuove verifica al progetto 'Linux Test',534oppure al progetto xfstests per cambiamenti relativi al filesystem.535 536 - https://linux-test-project.github.io/537 - git://git.kernel.org/pub/scm/fs/xfs/xfstests-dev.git538 539 540Pagine man541----------542 543Tutte le nuove chiamate di sistema dovrebbero avere una pagina man completa,544idealmente usando i marcatori groff, ma anche il puro testo può andare. Se545state usando groff, è utile che includiate nella email di presentazione una546versione già convertita in formato ASCII: semplificherà la vita dei revisori.547 548Le pagine man dovrebbero essere in copia-conoscenza verso549linux-man@vger.kernel.org550Per maggiori dettagli, leggere551https://www.kernel.org/doc/man-pages/patches.html552 553 554Non invocate chiamate di sistema dal kernel555-------------------------------------------556 557Le chiamate di sistema sono, come già detto prima, punti di interazione fra558lo spazio utente e il kernel. Perciò, le chiamate di sistema come559``sys_xyzzy()`` o ``compat_sys_xyzzy()`` dovrebbero essere chiamate solo dallo560spazio utente attraverso la tabella syscall, ma non da nessun altro punto nel561kernel. Se la nuova funzionalità è utile all'interno del kernel, per esempio562dev'essere condivisa fra una vecchia e una nuova chiamata di sistema o563dev'essere utilizzata da una chiamata di sistema e la sua variante compatibile,564allora dev'essere implementata come una funzione di supporto565(*helper function*) (per esempio ``ksys_xyzzy()``). Questa funzione potrà566essere chiamata dallo *stub* (``sys_xyzzy()``), dalla variante compatibile567(``compat_sys_xyzzy()``), e/o da altri parti del kernel.568 569Sui sistemi x86 a 64-bit, a partire dalla versione v4.17 è un requisito570fondamentale quello di non invocare chiamate di sistema all'interno del kernel.571Esso usa una diversa convenzione per l'invocazione di chiamate di sistema dove572``struct pt_regs`` viene decodificata al volo in una funzione che racchiude573la chiamata di sistema la quale verrà eseguita successivamente.574Questo significa che verranno passati solo i parametri che sono davvero575necessari ad una specifica chiamata di sistema, invece che riempire ogni volta5766 registri del processore con contenuti presi dallo spazio utente (potrebbe577causare seri problemi nella sequenza di chiamate).578 579Inoltre, le regole su come i dati possano essere usati potrebbero differire580fra il kernel e l'utente. Questo è un altro motivo per cui invocare581``sys_xyzzy()`` è generalmente una brutta idea.582 583Eccezioni a questa regola vengono accettate solo per funzioni d'architetture584che surclassano quelle generiche, per funzioni d'architettura di compatibilità,585o per altro codice in arch/586 587 588Riferimenti e fonti589-------------------590 591 - Articolo di Michael Kerris su LWN sull'uso dell'argomento flags nelle592 chiamate di sistema: https://lwn.net/Articles/585415/593 - Articolo di Michael Kerris su LWN su come gestire flag sconosciuti in594 una chiamata di sistema: https://lwn.net/Articles/588444/595 - Articolo di Jake Edge su LWN che descrive i limiti degli argomenti a 64-bit596 delle chiamate di sistema: https://lwn.net/Articles/311630/597 - Una coppia di articoli di David Drysdale che descrivono i dettagli del598 percorso implementativo di una chiamata di sistema per la versione v3.14:599 600 - https://lwn.net/Articles/604287/601 - https://lwn.net/Articles/604515/602 603 - Requisiti specifici alle architetture sono discussi nella pagina man604 :manpage:`syscall(2)` :605 http://man7.org/linux/man-pages/man2/syscall.2.html#NOTES606 - Collezione di email di Linux Torvalds sui problemi relativi a ``ioctl()``:607 http://yarchive.net/comp/linux/ioctl.html608 - "Come non inventare interfacce del kernel", Arnd Bergmann,609 http://www.ukuug.org/events/linux2007/2007/papers/Bergmann.pdf610 - Articolo di Michael Kerris su LWN sull'evitare nuovi usi di CAP_SYS_ADMIN:611 https://lwn.net/Articles/486306/612 - Raccomandazioni da Andrew Morton circa il fatto che tutte le informazioni613 su una nuova chiamata di sistema dovrebbero essere contenute nello stesso614 filone di discussione di email: https://lore.kernel.org/r/20140724144747.3041b208832bbdf9fbce5d96@linux-foundation.org615 - Raccomandazioni da Michael Kerrisk circa il fatto che le nuove chiamate di616 sistema dovrebbero avere una pagina man: https://lore.kernel.org/r/CAKgNAkgMA39AfoSoA5Pe1r9N+ZzfYQNvNPvcRN7tOvRb8+v06Q@mail.gmail.com617 - Consigli da Thomas Gleixner sul fatto che il collegamento all'architettura618 x86 dovrebbe avvenire in un *commit* differente:619 https://lore.kernel.org/r/alpine.DEB.2.11.1411191249560.3909@nanos620 - Consigli da Greg Kroah-Hartman circa la bontà d'avere una pagina man e un621 programma di auto-verifica per le nuove chiamate di sistema:622 https://lore.kernel.org/r/20140320025530.GA25469@kroah.com623 - Discussione di Michael Kerrisk sulle nuove chiamate di sistema contro624 le estensioni :manpage:`prctl(2)`: https://lore.kernel.org/r/CAHO5Pa3F2MjfTtfNxa8LbnkeeU8=YJ+9tDqxZpw7Gz59E-4AUg@mail.gmail.com625 - Consigli da Ingo Molnar che le chiamate di sistema con più argomenti626 dovrebbero incapsularli in una struttura che includa un argomento627 *size* per garantire l'estensibilità futura:628 https://lore.kernel.org/r/20150730083831.GA22182@gmail.com629 - Un certo numero di casi strani emersi dall'uso (riuso) dei flag O_*:630 631 - commit 75069f2b5bfb ("vfs: renumber FMODE_NONOTIFY and add to uniqueness632 check")633 - commit 12ed2e36c98a ("fanotify: FMODE_NONOTIFY and __O_SYNC in sparc634 conflict")635 - commit bb458c644a59 ("Safer ABI for O_TMPFILE")636 637 - Discussion from Matthew Wilcox about restrictions on 64-bit arguments:638 https://lore.kernel.org/r/20081212152929.GM26095@parisc-linux.org639 - Raccomandazioni da Greg Kroah-Hartman sul fatto che i flag sconosciuti dovrebbero640 essere controllati: https://lore.kernel.org/r/20140717193330.GB4703@kroah.com641 - Raccomandazioni da Linus Torvalds che le chiamate di sistema x32 dovrebbero642 favorire la compatibilità con le versioni a 64-bit piuttosto che quelle a 32-bit:643 https://lore.kernel.org/r/CA+55aFxfmwfB7jbbrXxa=K7VBYPfAvmu3XOkGrLbB1UFjX1+Ew@mail.gmail.com644