xref: /linux/Documentation/translations/it_IT/process/adding-syscalls.rst (revision 3a2c4d55e32ad65efebdb6de44eef3bfa08bb49d)
1.. include:: ../disclaimer-ita.rst
2
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 sistema
9========================================
10
11Questo documento descrive quello che è necessario sapere per aggiungere
12nuove chiamate di sistema al kernel Linux; questo è da considerarsi come
13un'aggiunta ai soliti consigli su come proporre nuove modifiche
14:ref:`Documentation/translations/it_IT/process/submitting-patches.rst <it_submittingpatches>`.
15
16
17Alternative alle chiamate di sistema
18------------------------------------
19
20La prima considerazione da fare quando si aggiunge una nuova chiamata di
21sistema è quella di valutare le alternative.  Nonostante le chiamate di sistema
22siano il punto di interazione fra spazio utente e kernel più tradizionale ed
23ovvio, esistono altre possibilità - scegliete quella che meglio si adatta alle
24vostra 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 o
28   dispositivo.  Inoltre, questo rende più facile incapsulare la nuova
29   funzionalità in un modulo kernel piuttosto che essere sviluppata nel cuore
30   del kernel.
31
32     - Se la nuova funzionalità prevede operazioni dove il kernel notifica
33       lo spazio utente su un avvenimento, allora restituire un descrittore
34       di file all'oggetto corrispondente permette allo spazio utente di
35       utilizzare ``poll``/``select``/``epoll`` per ricevere quelle notifiche.
36     - Tuttavia, le operazioni che non si sposano bene con operazioni tipo
37       :manpage:`read(2)`/:manpage:`write(2)` dovrebbero essere implementate
38       come chiamate :manpage:`ioctl(2)`, il che potrebbe portare ad un'API in
39       un qualche modo opaca.
40
41 - Se dovete esporre solo delle informazioni sul sistema, un nuovo nodo in
42   sysfs (vedere ``Documentation/filesystems/sysfs.rst``) o
43   in procfs potrebbe essere sufficiente.  Tuttavia, l'accesso a questi
44   meccanismi richiede che il filesystem sia montato, il che potrebbe non
45   essere sempre vero (per esempio, in ambienti come namespace/sandbox/chroot).
46   Evitate d'aggiungere nuove API in debugfs perché questo non viene
47   considerata un'interfaccia di 'produzione' verso lo spazio utente.
48 - Se l'operazione è specifica ad un particolare file o descrittore, allora
49   potrebbe essere appropriata l'aggiunta di un comando :manpage:`fcntl(2)`.
50   Tuttavia, :manpage:`fcntl(2)` è una chiamata di sistema multiplatrice che
51   nasconde una notevole complessità, quindi è ottima solo quando la nuova
52   funzione assomiglia a quelle già esistenti in :manpage:`fcntl(2)`, oppure
53   la nuova funzionalità è veramente semplice (per esempio, leggere/scrivere
54   un semplice flag associato ad un descrittore di file).
55 - Se l'operazione è specifica ad un particolare processo, allora
56   potrebbe essere appropriata l'aggiunta di un comando :manpage:`prctl(2)`.
57   Come per :manpage:`fcntl(2)`, questa chiamata di sistema è un complesso
58   multiplatore quindi è meglio usarlo per cose molto simili a quelle esistenti
59   nel comando ``prctl`` oppure per leggere/scrivere un semplice flag relativo
60   al processo.
61
62
63Progettare l'API: pianificare le estensioni
64-------------------------------------------
65
66Una nuova chiamata di sistema diventerà parte dell'API del kernel, e
67dev'essere supportata per un periodo indefinito.  Per questo, è davvero
68un'ottima idea quella di discutere apertamente l'interfaccia sulla lista
69di discussione del kernel, ed è altrettanto importante pianificarne eventuali
70estensioni future.
71
72(Nella tabella delle chiamate di sistema sono disseminati esempi dove questo
73non fu fatto, assieme ai corrispondenti aggiornamenti -
74``eventfd``/``eventfd2``, ``dup2``/``dup3``, ``inotify_init``/``inotify_init1``,
75``pipe``/``pipe2``, ``renameat``/``renameat2`` --quindi imparate dalla storia
76del 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 un
80argomento *flags* alla chiamata di sistema.  Per assicurarsi che i programmi
81dello spazio utente possano usare in sicurezza *flags* con diverse versioni
82del 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 di
91argomenti, il modo migliore è quello di incapsularne la maggior parte in una
92struttura 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 per
103offrire 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 un
107   programma in spazio utente verificando che la memoria oltre la dimensione
108   della struttura dati attesa sia zero (in pratica verificare che
109   ``param_4 == 0``).
110 - un nuovo kernel può gestire l'accesso di una versione vecchia di un
111   programma in spazio utente estendendo la struttura dati con zeri (in pratica
112   ``param_4 = 0``).
113
114Vedere :manpage:`perf_event_open(2)` e la funzione ``perf_copy_attr()`` (in
115``kernel/events/core.c``) per un esempio pratico di questo approccio.
116
117
118Progettare l'API: altre considerazioni
119--------------------------------------
120
121Se la vostra nuova chiamata di sistema permette allo spazio utente di fare
122riferimento ad un oggetto del kernel, allora questa dovrebbe usare un
123descrittore di file per accesso all'oggetto - non inventatevi nuovi tipi di
124accesso da spazio utente quando il kernel ha già dei meccanismi e una semantica
125ben definita per utilizzare i descrittori di file.
126
127Se la vostra nuova chiamata di sistema xyzzy(2) ritorna un nuovo
128descrittore di file, allora l'argomento *flags* dovrebbe includere un valore
129equivalente a ``O_CLOEXEC`` per i nuovi descrittori.  Questo rende possibile,
130nello spazio utente, la chiusura della finestra temporale fra le chiamate a
131``xyzzy()`` e ``fcntl(fd, F_SETFD, FD_CLOEXEC)``, dove un inaspettato
132``fork()`` o ``execve()`` potrebbe trasferire il descrittore al programma
133eseguito (Comunque, resistete alla tentazione di riutilizzare il valore di
134``O_CLOEXEC`` dato che è specifico dell'architettura e fa parte di una
135enumerazione 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 sistema
139della famiglia di :manpage:`poll(2)`. Rendere un descrittore di file pronto
140per la lettura o la scrittura è il tipico modo del kernel per notificare lo
141spazio utente circa un evento associato all'oggetto del kernel.
142
143Se la vostra nuova chiamata di sistema xyzzy(2) ha un argomento
144che è 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 versione
149`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 file
154in questione; in particolare, permette allo spazio utente di richiedere la
155funzionalità su un descrittore di file già aperto utilizzando il *flag*
156``AT_EMPTY_PATH``, in pratica otterremmo gratuitamente l'operazione
157fxyzzy(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 pagina
163man :manpage:`openat(2)`; per un esempio di AT_EMPTY_PATH, leggere la pagina
164man :manpage:`fstatat(2)`).
165
166Se la vostra nuova chiamata di sistema xyzzy(2) prevede un parametro
167per descrivere uno scostamento all'interno di un file, usate ``loff_t`` come
168tipo cosicché scostamenti a 64-bit potranno essere supportati anche su
169architetture a 32-bit.
170
171Se la vostra nuova chiamata di sistema xyzzy(2) prevede l'uso di
172funzioni riservate, allora dev'essere gestita da un opportuno bit di privilegio
173(verificato con una chiamata a ``capable()``), come descritto nella pagina man
174:manpage:`capabilities(7)`.  Scegliete un bit di privilegio già esistente per
175gestire la funzionalità associata, ma evitate la combinazione di diverse
176funzionalità vagamente collegate dietro lo stesso bit, in quanto va contro il
177principio di *capabilities* di separare i poteri di root.  In particolare,
178evitate di aggiungere nuovi usi al fin-troppo-generico privilegio
179``CAP_SYS_ADMIN``.
180
181Se la vostra nuova chiamata di sistema xyzzy(2) manipola altri
182processi oltre a quello chiamato, allora dovrebbe essere limitata (usando
183la chiamata ``ptrace_may_access()``) di modo che solo un processo chiamante
184con 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 chiamate
188di sistema con argomenti a 64-bit viene semplificata se questi argomenti
189ricadono in posizioni dispari (pratica, i parametri 1, 3, 5); questo permette
190l'uso di coppie contigue di registri a 32-bit.  (Questo non conta se gli
191argomenti sono parte di una struttura dati che viene passata per puntatore).
192
193
194Proporre l'API
195--------------
196
197Al fine di rendere le nuove chiamate di sistema di facile revisione, è meglio
198che dividiate le modifiche i pezzi separati.  Questi dovrebbero includere
199almeno le seguenti voci in *commit* distinti (ognuno dei quali sarà descritto
200più 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* di
204   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ò essere
210   scritta nell'email di presentazione, oppure come modifica vera e propria
211   al repositorio delle pagine man.
212
213Le proposte di nuove chiamate di sistema, come ogni altro modifica all'API del
214kernel, deve essere sottomessa alla lista di discussione
215linux-api@vger.kernel.org.
216
217
218Implementazione di chiamate di sistema generiche
219------------------------------------------------
220
221Il principale punto d'accesso alla vostra nuova chiamata di sistema
222`xyzzy(2)` verrà chiamato ``sys_xyzzy()``; ma, piuttosto che in modo
223esplicito, lo aggiungerete tramite la macro ``SYSCALL_DEFINEn``. La 'n'
224indica il numero di argomenti della chiamata di sistema; la macro ha come
225argomento il nome della chiamata di sistema, seguito dalle coppie (tipo, nome)
226per definire i suoi parametri.  L'uso di questa macro permette di avere
227i metadati della nuova chiamata di sistema disponibili anche per altri
228strumenti.
229
230Il nuovo punto d'accesso necessita anche del suo prototipo di funzione in
231``include/linux/syscalls.h``, marcato come asmlinkage di modo da abbinargli
232il 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 di
237chiamate di sistema (syscall), ma molte altre architetture condividono una
238tabella comune di syscall. Aggiungete alla lista generica la vostra nuova
239chiamata di sistema aggiungendo un nuovo elemento alla lista in
240``include/uapi/asm-generic/unistd.h``::
241
242    #define __NR_xyzzy 292
243    __SYSCALL(__NR_xyzzy, sys_xyzzy)
244
245Aggiornate anche il contatore __NR_syscalls di modo che sia coerente con
246l'aggiunta della nuove chiamate di sistema; va notato che se più di una nuova
247chiamata di sistema viene aggiunga nella stessa finestra di sviluppo, il numero
248della vostra nuova syscall potrebbe essere aggiustato al fine di risolvere i
249conflitti.
250
251Il file ``kernel/sys_ni.c`` fornisce le implementazioni *stub* di ripiego che
252ritornano ``-ENOSYS``.  Aggiungete la vostra nuova chiamata di sistema anche
253qui::
254
255    COND_SYSCALL(xyzzy);
256
257La vostra nuova funzionalità del kernel, e la chiamata di sistema che la
258controlla, dovrebbero essere opzionali. Quindi, aggiungete un'opzione
259``CONFIG`` (solitamente in ``init/Kconfig``).  Come al solito per le nuove
260opzioni ``CONFIG``:
261
262 - Includete una descrizione della nuova funzionalità e della chiamata di
263   sistema che la controlla.
264 - Rendete l'opzione dipendente da EXPERT se dev'essere nascosta agli utenti
265   normali.
266 - Nel Makefile, rendere tutti i nuovi file sorgenti, che implementano la
267   nuova funzionalità, dipendenti dall'opzione CONFIG (per esempio
268   ``obj-$(CONFIG_XYZZY_SYSCALL) += xyzzy.o``).
269 - Controllate due volte che sia possibile generare il kernel con la nuova
270   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'accesso
276 - 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
281.. _it_syscall_generic_6_11:
282
283Dalla versione 6.11
284~~~~~~~~~~~~~~~~~~~~
285
286A partire dalla versione 6.11 del kernel, l'implementazione generica delle
287chiamate di sistema per le seguenti architetture non richiede più modifiche
288a ``include/uapi/asm-generic/unistd.h``:
289
290 - arc
291 - arm64
292 - csky
293 - hexagon
294 - loongarch
295 - nios2
296 - openrisc
297 - riscv
298
299Al suo posto, dovete aggiornare ``scripts/syscall.tbl`` e, se necessario,
300modificare ``arch/*/kernel/Makefile.syscalls``.
301
302Dato che ``scripts/syscall.tbl`` funge da tabella comune delle chiamate di
303sistema condivisa fra più architetture, in questa tabella è richiesto un
304nuovo elemento::
305
306    468   common   xyzzy     sys_xyzzy
307
308Da notare che l'aggiunta di un elemento a ``scripts/syscall.tbl`` con l'ABI
309"common" influisce anche su tutte le architetture che condividono questa
310tabella. Per modifiche più limitate o specifiche di un'architettura,
311considerate l'uso di un'ABI specifica per l'architettura, o la definizione
312di una nuova.
313
314Se viene introdotta una nuova ABI, per esempio ``xyz``, andranno fatti i
315corrispondenti aggiornamenti anche in ``arch/*/kernel/Makefile.syscalls``::
316
317    syscall_abis_{32,64} += xyz (...)
318
319Per riassumere, vi serve un *commit* che includa:
320
321 - un'opzione ``CONFIG`` per la nuova funzione, normalmente in
322   ``init/Kconfig``
323 - ``SYSCALL_DEFINEn(xyzzy, ...)`` per il punto d'accesso
324 - il corrispondente prototipo in ``include/linux/syscalls.h``
325 - un nuovo elemento in ``scripts/syscall.tbl``
326 - (se necessario) aggiornamenti al Makefile in
327   ``arch/*/kernel/Makefile.syscalls``
328 - *stub* di ripiego in ``kernel/sys_ni.c``
329
330
331Implementazione delle chiamate di sistema x86
332---------------------------------------------
333
334Per collegare la vostra nuova chiamate di sistema alle piattaforme x86,
335dovete aggiornate la tabella principale di syscall.  Assumendo che la vostra
336nuova chiamata di sistema non sia particolarmente speciale (vedere sotto),
337dovete aggiungere un elemento *common* (per x86_64 e x32) in
338arch/x86/entry/syscalls/syscall_64.tbl::
339
340    333   common   xyzzy     sys_xyzzy
341
342e un elemento per *i386* ``arch/x86/entry/syscalls/syscall_32.tbl``::
343
344    380   i386     xyzzy     sys_xyzzy
345
346Ancora una volta, questi numeri potrebbero essere cambiati se generano
347conflitti durante la finestra di integrazione.
348
349
350Chiamate di sistema compatibili (generico)
351------------------------------------------
352
353Per molte chiamate di sistema, la stessa implementazione a 64-bit può essere
354invocata anche quando il programma in spazio utente è a 32-bit; anche se la
355chiamata di sistema include esplicitamente un puntatore, questo viene gestito
356in modo trasparente.
357
358Tuttavia, ci sono un paio di situazione dove diventa necessario avere un
359livello di gestione della compatibilità per risolvere le differenze di
360dimensioni fra 32-bit e 64-bit.
361
362Il primo caso è quando un kernel a 64-bit supporta anche programmi in spazio
363utente a 32-bit, perciò dovrà ispezionare aree della memoria (``__user``) che
364potrebbero contenere valori a 32-bit o a 64-bit.  In particolar modo, questo
365è necessario quando un argomento di una chiamata di sistema è:
366
367 - un puntatore ad un puntatore
368 - un puntatore ad una struttura dati contenente a sua volta un puntatore
369   ( ad esempio ``struct iovec __user *``)
370 - un puntatore ad un tipo intero di dimensione variabile (``time_t``,
371   ``off_t``, ``long``, ...)
372 - un puntatore ad una struttura dati contenente un tipo intero di dimensione
373   variabile.
374
375Il secondo caso che richiede un livello di gestione della compatibilità è
376quando uno degli argomenti di una chiamata a sistema è esplicitamente un tipo
377a 64-bit anche su architetture a 32-bit, per esempio ``loff_t`` o ``__u64``.
378In questo caso, un valore che arriva ad un kernel a 64-bit da un'applicazione
379a 32-bit verrà diviso in due valori a 32-bit che dovranno essere riassemblati
380in questo livello di compatibilità.
381
382(Da notare che non serve questo livello di compatibilità per argomenti che
383sono puntatori ad un tipo esplicitamente a 64-bit; per esempio, in
384:manpage:`splice(2)` l'argomento di tipo ``loff_t __user *`` non necessita
385di una chiamata di sistema ``compat_``)
386
387La versione compatibile della nostra chiamata di sistema si chiamerà
388``compat_sys_xyzzy()``, e viene aggiunta utilizzando la macro
389``COMPAT_SYSCALL_DEFINEn()`` (simile a SYSCALL_DEFINEn).  Questa versione
390dell'implementazione è parte del kernel a 64-bit ma accetta parametri a 32-bit
391che trasformerà secondo le necessità (tipicamente, la versione
392``compat_sys_`` converte questi valori nello loro corrispondente a 64-bit e
393può chiamare la versione ``sys_`` oppure invocare una funzione che implementa
394le parti comuni).
395
396Il punto d'accesso *compat* deve avere il corrispondente prototipo di funzione
397in ``include/linux/compat.h``, marcato come asmlinkage di modo da abbinargli
398il modo in cui quelle chiamate di sistema verranno invocate::
399
400    asmlinkage long compat_sys_xyzzy(...);
401
402Se la chiamata di sistema prevede una struttura dati organizzata in modo
403diverso per sistemi a 32-bit e per quelli a 64-bit, diciamo
404``struct xyzzy_args``, allora il file d'intestazione
405``then the include/linux/compat.h`` deve includere la sua versione
406*compatibile* (``struct compat_xyzzy_args``); ogni variabile con
407dimensione variabile deve avere il proprio tipo ``compat_`` corrispondente
408a quello in ``struct xyzzy_args``.  La funzione ``compat_sys_xyzzy()``
409può usare la struttura ``compat_`` per analizzare gli argomenti ricevuti
410da una chiamata a 32-bit.
411
412Per esempio, se avete i seguenti campi::
413
414    struct xyzzy_args {
415        const char __user *ptr;
416        __kernel_long_t varying_val;
417        u64 fixed_val;
418        /* ... */
419    };
420
421nella struttura ``struct xyzzy_args``, allora la struttura
422``struct compat_xyzzy_args`` dovrebbe avere::
423
424    struct compat_xyzzy_args {
425        compat_uptr_t ptr;
426        compat_long_t varying_val;
427        u64 fixed_val;
428        /* ... */
429    };
430
431La lista generica delle chiamate di sistema ha bisogno di essere
432aggiustata al fine di permettere l'uso della versione *compatibile*;
433la voce in ``include/uapi/asm-generic/unistd.h`` dovrebbero usare
434``__SC_COMP`` piuttosto di ``__SYSCALL``::
435
436    #define __NR_xyzzy 292
437    __SC_COMP(__NR_xyzzy, sys_xyzzy, compat_sys_xyzzy)
438
439Riassumendo, vi serve:
440
441 - un ``COMPAT_SYSCALL_DEFINEn(xyzzy, ...)`` per il punto d'accesso
442   *compatibile*
443 - un prototipo in ``include/linux/compat.h``
444 - (se necessario) una struttura di compatibilità a 32-bit in
445   ``include/linux/compat.h``
446 - una voce ``__SC_COMP``, e non ``__SYSCALL``, in
447   ``include/uapi/asm-generic/unistd.h``
448
449
450Dalla versione 6.11
451~~~~~~~~~~~~~~~~~~~~
452
453Questo si applica a tutte le architetture elencate in
454:ref:`Dalla versione 6.11<it_syscall_generic_6_11>` sotto "Implementazione
455di chiamate di sistema generiche", eccetto arm64. Vedere
456:ref:`Chiamate di sistema compatibili (arm64)<it_compat_arm64>` per maggiori
457informazioni.
458
459Dovete estendere la voce in ``scripts/syscall.tbl`` con una colonna
460aggiuntiva per indicare che un programma in spazio utente a 32-bit in
461esecuzione su un kernel a 64-bit deve invocare il punto d'accesso
462*compatibile*::
463
464    468   common     xyzzy     sys_xyzzy    compat_sys_xyzzy
465
466Riassumendo, vi serve:
467
468 - un ``COMPAT_SYSCALL_DEFINEn(xyzzy, ...)`` per il punto d'accesso
469   *compatibile*
470 - il corrispondente prototipo in ``include/linux/compat.h``
471 - la modifica della voce in ``scripts/syscall.tbl`` per includere una
472   colonna "compat" aggiuntiva
473 - (se necessario) una struttura di mappatura a 32-bit in
474   ``include/linux/compat.h``
475
476
477.. _it_compat_arm64:
478
479Chiamate di sistema compatibili (arm64)
480^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
481
482Su arm64 esiste una tabella delle chiamate di sistema dedicata per le
483chiamate di sistema compatibili rivolte allo spazio utente a 32-bit
484(AArch32): ``arch/arm64/tools/syscall_32.tbl``. Dovete aggiungere una riga
485aggiuntiva a questa tabella specificando il punto d'accesso *compatibile*::
486
487    468   common     xyzzy     sys_xyzzy    compat_sys_xyzzy
488
489
490Compatibilità delle chiamate di sistema (x86)
491---------------------------------------------
492
493Per collegare una chiamata di sistema, su un'architettura x86, con la sua
494versione *compatibile*, è necessario aggiustare la voce nella tabella
495delle syscall.
496
497Per prima cosa, la voce in ``arch/x86/entry/syscalls/syscall_32.tbl`` prende
498un argomento aggiuntivo per indicare che un programma in spazio utente
499a 32-bit, eseguito su un kernel a 64-bit, dovrebbe accedere tramite il punto
500d'accesso compatibile::
501
502    380   i386     xyzzy     sys_xyzzy    __ia32_compat_sys_xyzzy
503
504Secondo, dovete capire cosa dovrebbe succedere alla nuova chiamata di sistema
505per la versione dell'ABI x32.  Qui C'è una scelta da fare: gli argomenti
506possono corrisponde alla versione a 64-bit o a quella a 32-bit.
507
508Se c'è un puntatore ad un puntatore, la decisione è semplice: x32 è ILP32,
509quindi gli argomenti dovrebbero corrispondere a quelli a 32-bit, e la voce in
510``arch/x86/entry/syscalls/syscall_64.tbl`` sarà divisa cosicché i programmi
511x32 eseguano la chiamata *compatibile*::
512
513    333   64       xyzzy     sys_xyzzy
514    ...
515    555   x32      xyzzy     __x32_compat_sys_xyzzy
516
517Se non ci sono puntatori, allora è preferibile riutilizzare la chiamata di
518sistema a 64-bit per l'ABI x32 (e di conseguenza la voce in
519arch/x86/entry/syscalls/syscall_64.tbl rimane immutata).
520
521In ambo i casi, dovreste verificare che i tipi usati dagli argomenti
522abbiano un'esatta corrispondenza da x32 (-mx32) al loro equivalente a
52332-bit (-m32) o 64-bit (-m64).
524
525
526Chiamate di sistema che ritornano altrove
527-----------------------------------------
528
529Nella maggior parte delle chiamate di sistema, al termine della loro
530esecuzione, i programmi in spazio utente riprendono esattamente dal punto
531in cui si erano interrotti -- quindi dall'istruzione successiva, con lo
532stesso *stack* e con la maggior parte del registri com'erano stati
533lasciati prima della chiamata di sistema, e anche con la stessa memoria
534virtuale.
535
536Tuttavia, alcune chiamata di sistema fanno le cose in modo differente.
537Potrebbero ritornare ad un punto diverso (``rt_sigreturn``) o cambiare
538la memoria in spazio utente (``fork``/``vfork``/``clone``) o perfino
539l'architettura del programma (``execve``/``execveat``).
540
541Per permettere tutto ciò, l'implementazione nel kernel di questo tipo di
542chiamate di sistema potrebbero dover salvare e ripristinare registri
543aggiuntivi nello *stack* del kernel, permettendo così un controllo completo
544su dove e come l'esecuzione dovrà continuare dopo l'esecuzione della
545chiamata di sistema.
546
547Queste saranno specifiche per ogni architettura, ma tipicamente si definiscono
548dei punti d'accesso in *assembly* per salvare/ripristinare i registri
549aggiuntivi e quindi chiamare il vero punto d'accesso per la chiamata di
550sistema.
551
552Per l'architettura x86_64, questo è implementato come un punto d'accesso
553``stub_xyzzy`` in ``arch/x86/entry/entry_64.S``, e la voce nella tabella
554di syscall (``arch/x86/entry/syscalls/syscall_64.tbl``) verrà corretta di
555conseguenza::
556
557    333   common   xyzzy     stub_xyzzy
558
559L'equivalente per programmi a 32-bit eseguiti su un kernel a 64-bit viene
560normalmente chiamato ``stub32_xyzzy`` e implementato in
561``arch/x86/entry/entry_64_compat.S`` con la corrispondente voce nella tabella
562di syscall ``arch/x86/entry/syscalls/syscall_32.tbl`` corretta nel
563seguente modo::
564
565    380   i386     xyzzy     sys_xyzzy    stub32_xyzzy
566
567Se una chiamata di sistema necessita di un livello di compatibilità (come
568nella sezione precedente), allora la versione ``stub32_`` deve invocare
569la versione ``compat_sys_`` piuttosto che quella nativa a 64-bit.  In aggiunta,
570se l'implementazione dell'ABI x32 è diversa da quella x86_64, allora la sua
571voce nella tabella di syscall dovrà chiamare uno *stub* che invoca la versione
572``compat_sys_``,
573
574Per completezza, sarebbe carino impostare una mappatura cosicché
575*user-mode* Linux (UML) continui a funzionare -- la sua tabella di syscall
576farà riferimento a stub_xyzzy, ma UML non include l'implementazione
577in ``arch/x86/entry/entry_64.S`` (perché UML simula i registri eccetera).
578Correggerlo è semplice, basta aggiungere una #define in
579``arch/x86/um/sys_call_table_64.c``::
580
581    #define stub_xyzzy sys_xyzzy
582
583
584Altri dettagli
585--------------
586
587La maggior parte dei kernel tratta le chiamate di sistema allo stesso modo,
588ma possono esserci rare eccezioni per le quali potrebbe essere necessario
589l'aggiornamento della vostra chiamata di sistema.
590
591Il sotto-sistema di controllo (*audit subsystem*) è uno di questi casi
592speciali; esso include (per architettura) funzioni che classificano alcuni
593tipi di chiamate di sistema -- in particolare apertura dei file
594(``open``/``openat``), esecuzione dei programmi (``execve``/``exeveat``)
595oppure multiplatori di socket (``socketcall``). Se la vostra nuova chiamata
596di sistema è simile ad una di queste, allora il sistema di controllo dovrebbe
597essere aggiornato.
598
599Più in generale, se esiste una chiamata di sistema che è simile alla vostra,
600vale la pena fare una ricerca con ``grep`` su tutto il kernel per la chiamata
601di sistema esistente per verificare che non ci siano altri casi speciali.
602
603
604Verifica
605--------
606
607Una nuova chiamata di sistema dev'essere, ovviamente, provata; è utile fornire
608ai revisori un programma in spazio utente che mostri l'uso della chiamata di
609sistema.  Un buon modo per combinare queste cose è quello di aggiungere un
610semplice programma di auto-verifica in una nuova cartella in
611``tools/testing/selftests/``.
612
613Per una nuova chiamata di sistema, ovviamente, non ci sarà alcuna funzione
614in libc e quindi il programma di verifica dovrà invocarla usando ``syscall()``;
615inoltre, se la nuova chiamata di sistema prevede un nuova struttura dati
616visibile in spazio utente, il file d'intestazione necessario dev'essere
617installato al fine di compilare il programma.
618
619Assicuratevi che il programma di auto-verifica possa essere eseguito
620correttamente su tutte le architetture supportate.  Per esempio, verificate che
621funzioni quando viene compilato per x86_64 (-m64), x86_32 (-m32) e x32 (-mx32).
622
623Al fine di una più meticolosa ed estesa verifica della nuova funzionalità,
624dovreste considerare l'aggiunta di nuove verifica al progetto 'Linux Test',
625oppure al progetto xfstests per cambiamenti relativi al filesystem.
626
627 - https://linux-test-project.github.io/
628 - git://git.kernel.org/pub/scm/fs/xfs/xfstests-dev.git
629
630
631Pagine man
632----------
633
634Tutte le nuove chiamate di sistema dovrebbero avere una pagina man completa,
635idealmente usando i marcatori groff, ma anche il puro testo può andare.  Se
636state usando groff, è utile che includiate nella email di presentazione una
637versione già convertita in formato ASCII: semplificherà la vita dei revisori.
638
639Le pagine man dovrebbero essere in copia-conoscenza verso
640linux-man@vger.kernel.org
641Per maggiori dettagli, leggere
642https://www.kernel.org/doc/man-pages/patches.html
643
644
645Non invocate chiamate di sistema dal kernel
646-------------------------------------------
647
648Le chiamate di sistema sono, come già detto prima, punti di interazione fra
649lo spazio utente e il kernel.  Perciò, le chiamate di sistema come
650``sys_xyzzy()`` o ``compat_sys_xyzzy()`` dovrebbero essere chiamate solo dallo
651spazio utente attraverso la tabella syscall, ma non da nessun altro punto nel
652kernel.  Se la nuova funzionalità è utile all'interno del kernel, per esempio
653dev'essere condivisa fra una vecchia e una nuova chiamata di sistema o
654dev'essere utilizzata da una chiamata di sistema e la sua variante compatibile,
655allora dev'essere implementata come una funzione di supporto
656(*helper function*) (per esempio ``ksys_xyzzy()``).  Questa funzione potrà
657essere chiamata dallo *stub* (``sys_xyzzy()``), dalla variante compatibile
658(``compat_sys_xyzzy()``), e/o da altri parti del kernel.
659
660Sui sistemi x86 a 64-bit, a partire dalla versione v4.17 è un requisito
661fondamentale quello di non invocare chiamate di sistema all'interno del kernel.
662Esso usa una diversa convenzione per l'invocazione di chiamate di sistema dove
663``struct pt_regs`` viene decodificata al volo in una funzione che racchiude
664la chiamata di sistema la quale verrà eseguita successivamente.
665Questo significa che verranno passati solo i parametri che sono davvero
666necessari ad una specifica chiamata di sistema, invece che riempire ogni volta
6676 registri del processore con contenuti presi dallo spazio utente (potrebbe
668causare seri problemi nella sequenza di chiamate).
669
670Inoltre, le regole su come i dati possano essere usati potrebbero differire
671fra il kernel e l'utente.  Questo è un altro motivo per cui invocare
672``sys_xyzzy()`` è generalmente una brutta idea.
673
674Eccezioni a questa regola vengono accettate solo per funzioni d'architetture
675che surclassano quelle generiche, per funzioni d'architettura di compatibilità,
676o per altro codice in arch/
677
678
679Riferimenti e fonti
680-------------------
681
682 - Articolo di Michael Kerris su LWN sull'uso dell'argomento flags nelle
683   chiamate di sistema: https://lwn.net/Articles/585415/
684 - Articolo di Michael Kerris su LWN su come gestire flag sconosciuti in
685   una chiamata di sistema: https://lwn.net/Articles/588444/
686 - Articolo di Jake Edge su LWN che descrive i limiti degli argomenti a 64-bit
687   delle chiamate di sistema: https://lwn.net/Articles/311630/
688 - Una coppia di articoli di David Drysdale che descrivono i dettagli del
689   percorso implementativo di una chiamata di sistema per la versione v3.14:
690
691    - https://lwn.net/Articles/604287/
692    - https://lwn.net/Articles/604515/
693
694 - Requisiti specifici alle architetture sono discussi nella pagina man
695   :manpage:`syscall(2)` :
696   http://man7.org/linux/man-pages/man2/syscall.2.html#NOTES
697 - Collezione di email di Linux Torvalds sui problemi relativi a ``ioctl()``:
698   http://yarchive.net/comp/linux/ioctl.html
699 - "Come non inventare interfacce del kernel", Arnd Bergmann,
700   http://www.ukuug.org/events/linux2007/2007/papers/Bergmann.pdf
701 - Articolo di Michael Kerris su LWN sull'evitare nuovi usi di CAP_SYS_ADMIN:
702   https://lwn.net/Articles/486306/
703 - Raccomandazioni da Andrew Morton circa il fatto che tutte le informazioni
704   su una nuova chiamata di sistema dovrebbero essere contenute nello stesso
705   filone di discussione di email: https://lore.kernel.org/r/20140724144747.3041b208832bbdf9fbce5d96@linux-foundation.org
706 - Raccomandazioni da Michael Kerrisk circa il fatto che le nuove chiamate di
707   sistema dovrebbero avere una pagina man: https://lore.kernel.org/r/CAKgNAkgMA39AfoSoA5Pe1r9N+ZzfYQNvNPvcRN7tOvRb8+v06Q@mail.gmail.com
708 - Consigli da Thomas Gleixner sul fatto che il collegamento all'architettura
709   x86 dovrebbe avvenire in un *commit* differente:
710   https://lore.kernel.org/r/alpine.DEB.2.11.1411191249560.3909@nanos
711 - Consigli da Greg Kroah-Hartman circa la bontà d'avere una pagina man e un
712   programma di auto-verifica per le nuove chiamate di sistema:
713   https://lore.kernel.org/r/20140320025530.GA25469@kroah.com
714 - Discussione di Michael Kerrisk sulle nuove chiamate di sistema contro
715   le estensioni :manpage:`prctl(2)`: https://lore.kernel.org/r/CAHO5Pa3F2MjfTtfNxa8LbnkeeU8=YJ+9tDqxZpw7Gz59E-4AUg@mail.gmail.com
716 - Consigli da Ingo Molnar che le chiamate di sistema con più argomenti
717   dovrebbero incapsularli in una struttura che includa un argomento
718   *size* per garantire l'estensibilità futura:
719   https://lore.kernel.org/r/20150730083831.GA22182@gmail.com
720 - Un certo numero di casi strani emersi dall'uso (riuso) dei flag O_*:
721
722    - commit 75069f2b5bfb ("vfs: renumber FMODE_NONOTIFY and add to uniqueness
723      check")
724    - commit 12ed2e36c98a ("fanotify: FMODE_NONOTIFY and __O_SYNC in sparc
725      conflict")
726    - commit bb458c644a59 ("Safer ABI for O_TMPFILE")
727
728 - Discussion from Matthew Wilcox about restrictions on 64-bit arguments:
729   https://lore.kernel.org/r/20081212152929.GM26095@parisc-linux.org
730 - Raccomandazioni da Greg Kroah-Hartman sul fatto che i flag sconosciuti dovrebbero
731   essere controllati: https://lore.kernel.org/r/20140717193330.GB4703@kroah.com
732 - Raccomandazioni da Linus Torvalds che le chiamate di sistema x32 dovrebbero
733   favorire la compatibilità con le versioni a 64-bit piuttosto che quelle a 32-bit:
734   https://lore.kernel.org/r/CA+55aFxfmwfB7jbbrXxa=K7VBYPfAvmu3XOkGrLbB1UFjX1+Ew@mail.gmail.com
735 - Serie di patch che revisiona l'infrastruttura della tabella delle chiamate
736   di sistema per usare scripts/syscall.tbl su più architetture:
737   https://lore.kernel.org/lkml/20240704143611.2979589-1-arnd@kernel.org
738