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

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

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

  1 .. include:: ../disclaimer-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 
  8 Aggiungere una nuova chiamata di sistema
  9 ========================================
 10 
 11 Questo documento descrive quello che è necessario sapere per aggiungere
 12 nuove chiamate di sistema al kernel Linux; questo è da considerarsi come
 13 un'aggiunta ai soliti consigli su come proporre nuove modifiche
 14 :ref:`Documentation/translations/it_IT/process/submitting-patches.rst <it_submittingpatches>`.
 15 
 16 
 17 Alternative alle chiamate di sistema
 18 ------------------------------------
 19 
 20 La prima considerazione da fare quando si aggiunge una nuova chiamata di
 21 sistema è quella di valutare le alternative.  Nonostante le chiamate di sistema
 22 siano il punto di interazione fra spazio utente e kernel più tradizionale ed
 23 ovvio, esistono altre possibilità - scegliete quella che meglio si adatta alle
 24 vostra 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 
 63 Progettare l'API: pianificare le estensioni
 64 -------------------------------------------
 65 
 66 Una nuova chiamata di sistema diventerà parte dell'API del kernel, e
 67 dev'essere supportata per un periodo indefinito.  Per questo, è davvero
 68 un'ottima idea quella di discutere apertamente l'interfaccia sulla lista
 69 di discussione del kernel, ed è altrettanto importante pianificarne eventuali
 70 estensioni future.
 71 
 72 (Nella tabella delle chiamate di sistema sono disseminati esempi dove questo
 73 non fu fatto, assieme ai corrispondenti aggiornamenti -
 74 ``eventfd``/``eventfd2``, ``dup2``/``dup3``, ``inotify_init``/``inotify_init1``,
 75 ``pipe``/``pipe2``, ``renameat``/``renameat2`` --quindi imparate dalla storia
 76 del kernel e pianificate le estensioni fin dall'inizio)
 77 
 78 Per semplici chiamate di sistema che accettano solo un paio di argomenti,
 79 il modo migliore di permettere l'estensibilità è quello di includere un
 80 argomento *flags* alla chiamata di sistema.  Per assicurarsi che i programmi
 81 dello spazio utente possano usare in sicurezza *flags* con diverse versioni
 82 del kernel, verificate se *flags* contiene un qualsiasi valore sconosciuto,
 83 in 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 
 90 Per chiamate di sistema più sofisticate che coinvolgono un numero più grande di
 91 argomenti, il modo migliore è quello di incapsularne la maggior parte in una
 92 struttura dati che verrà passata per puntatore.  Questa struttura potrà
 93 funzionare 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 
102 Fintanto che un qualsiasi campo nuovo, diciamo ``param_4``, è progettato per
103 offrire il comportamento precedente quando vale zero, allora questo permetterà
104 di 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 
114 Vedere :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 
118 Progettare l'API: altre considerazioni
119 --------------------------------------
120 
121 Se la vostra nuova chiamata di sistema permette allo spazio utente di fare
122 riferimento ad un oggetto del kernel, allora questa dovrebbe usare un
123 descrittore di file per accesso all'oggetto - non inventatevi nuovi tipi di
124 accesso da spazio utente quando il kernel ha già dei meccanismi e una semantica
125 ben definita per utilizzare i descrittori di file.
126 
127 Se la vostra nuova chiamata di sistema :manpage:`xyzzy(2)` ritorna un nuovo
128 descrittore di file, allora l'argomento *flags* dovrebbe includere un valore
129 equivalente a ``O_CLOEXEC`` per i nuovi descrittori.  Questo rende possibile,
130 nello 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
133 eseguito (Comunque, resistete alla tentazione di riutilizzare il valore di
134 ``O_CLOEXEC`` dato che è specifico dell'architettura e fa parte di una
135 enumerazione di flag ``O_*`` che è abbastanza ricca).
136 
137 Se la vostra nuova chiamata di sistema ritorna un nuovo descrittore di file,
138 dovreste considerare che significato avrà l'uso delle chiamate di sistema
139 della famiglia di :manpage:`poll(2)`. Rendere un descrittore di file pronto
140 per la lettura o la scrittura è il tipico modo del kernel per notificare lo
141 spazio utente circa un evento associato all'oggetto del kernel.
142 
143 Se la vostra nuova chiamata di sistema :manpage:`xyzzy(2)` ha un argomento
144 che è il percorso ad un file::
145 
146     int sys_xyzzy(const char __user *path, ..., unsigned int flags);
147 
148 dovreste anche considerare se non sia più appropriata una versione
149 :manpage:`xyzzyat(2)`::
150 
151     int sys_xyzzyat(int dfd, const char __user *path, ..., unsigned int flags);
152 
153 Questo permette più flessibilità su come lo spazio utente specificherà il file
154 in questione; in particolare, permette allo spazio utente di richiedere la
155 funzionalità su un descrittore di file già aperto utilizzando il *flag*
156 ``AT_EMPTY_PATH``, in pratica otterremmo gratuitamente l'operazione
157 :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 pagina
163 man :manpage:`openat(2)`; per un esempio di AT_EMPTY_PATH, leggere la pagina
164 man :manpage:`fstatat(2)`).
165 
166 Se la vostra nuova chiamata di sistema :manpage:`xyzzy(2)` prevede un parametro
167 per descrivere uno scostamento all'interno di un file, usate ``loff_t`` come
168 tipo cosicché scostamenti a 64-bit potranno essere supportati anche su
169 architetture a 32-bit.
170 
171 Se la vostra nuova chiamata di sistema :manpage:`xyzzy(2)` prevede l'uso di
172 funzioni 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
175 gestire la funzionalità associata, ma evitate la combinazione di diverse
176 funzionalità vagamente collegate dietro lo stesso bit, in quanto va contro il
177 principio di *capabilities* di separare i poteri di root.  In particolare,
178 evitate di aggiungere nuovi usi al fin-troppo-generico privilegio
179 ``CAP_SYS_ADMIN``.
180 
181 Se la vostra nuova chiamata di sistema :manpage:`xyzzy(2)` manipola altri
182 processi oltre a quello chiamato, allora dovrebbe essere limitata (usando
183 la chiamata ``ptrace_may_access()``) di modo che solo un processo chiamante
184 con gli stessi permessi del processo in oggetto, o con i necessari privilegi,
185 possa manipolarlo.
186 
187 Infine, state attenti che in alcune architetture non-x86 la vita delle chiamate
188 di sistema con argomenti a 64-bit viene semplificata se questi argomenti
189 ricadono in posizioni dispari (pratica, i parametri 1, 3, 5); questo permette
190 l'uso di coppie contigue di registri a 32-bit.  (Questo non conta se gli
191 argomenti sono parte di una struttura dati che viene passata per puntatore).
192 
193 
194 Proporre l'API
195 --------------
196 
197 Al fine di rendere le nuove chiamate di sistema di facile revisione, è meglio
198 che dividiate le modifiche i pezzi separati.  Questi dovrebbero includere
199 almeno le seguenti voci in *commit* distinti (ognuno dei quali sarà descritto
200 più 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 
213 Le proposte di nuove chiamate di sistema, come ogni altro modifica all'API del
214 kernel, deve essere sottomessa alla lista di discussione
215 linux-api@vger.kernel.org.
216 
217 
218 Implementazione di chiamate di sistema generiche
219 ------------------------------------------------
220 
221 Il principale punto d'accesso alla vostra nuova chiamata di sistema
222 :manpage:`xyzzy(2)` verrà chiamato ``sys_xyzzy()``; ma, piuttosto che in modo
223 esplicito, lo aggiungerete tramite la macro ``SYSCALL_DEFINEn``. La 'n'
224 indica il numero di argomenti della chiamata di sistema; la macro ha come
225 argomento il nome della chiamata di sistema, seguito dalle coppie (tipo, nome)
226 per definire i suoi parametri.  L'uso di questa macro permette di avere
227 i metadati della nuova chiamata di sistema disponibili anche per altri
228 strumenti.
229 
230 Il nuovo punto d'accesso necessita anche del suo prototipo di funzione in
231 ``include/linux/syscalls.h``, marcato come asmlinkage di modo da abbinargli
232 il modo in cui quelle chiamate di sistema verranno invocate::
233 
234     asmlinkage long sys_xyzzy(...);
235 
236 Alcune architetture (per esempio x86) hanno le loro specifiche tabelle di
237 chiamate di sistema (syscall), ma molte altre architetture condividono una
238 tabella comune di syscall. Aggiungete alla lista generica la vostra nuova
239 chiamata 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 
245 Aggiornate anche il contatore __NR_syscalls di modo che sia coerente con
246 l'aggiunta della nuove chiamate di sistema; va notato che se più di una nuova
247 chiamata di sistema viene aggiunga nella stessa finestra di sviluppo, il numero
248 della vostra nuova syscall potrebbe essere aggiustato al fine di risolvere i
249 conflitti.
250 
251 Il file ``kernel/sys_ni.c`` fornisce le implementazioni *stub* di ripiego che
252 ritornano ``-ENOSYS``.  Aggiungete la vostra nuova chiamata di sistema anche
253 qui::
254 
255     COND_SYSCALL(xyzzy);
256 
257 La vostra nuova funzionalità del kernel, e la chiamata di sistema che la
258 controlla, dovrebbero essere opzionali. Quindi, aggiungete un'opzione
259 ``CONFIG`` (solitamente in ``init/Kconfig``).  Come al solito per le nuove
260 opzioni ``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 
272 Per 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 Implementazione delle chiamate di sistema x86
282 ---------------------------------------------
283 
284 Per collegare la vostra nuova chiamate di sistema alle piattaforme x86,
285 dovete aggiornate la tabella principale di syscall.  Assumendo che la vostra
286 nuova chiamata di sistema non sia particolarmente speciale (vedere sotto),
287 dovete aggiungere un elemento *common* (per x86_64 e x32) in
288 arch/x86/entry/syscalls/syscall_64.tbl::
289 
290     333   common   xyzzy     sys_xyzzy
291 
292 e un elemento per *i386* ``arch/x86/entry/syscalls/syscall_32.tbl``::
293 
294     380   i386     xyzzy     sys_xyzzy
295 
296 Ancora una volta, questi numeri potrebbero essere cambiati se generano
297 conflitti durante la finestra di integrazione.
298 
299 
300 Chiamate di sistema compatibili (generico)
301 ------------------------------------------
302 
303 Per molte chiamate di sistema, la stessa implementazione a 64-bit può essere
304 invocata anche quando il programma in spazio utente è a 32-bit; anche se la
305 chiamata di sistema include esplicitamente un puntatore, questo viene gestito
306 in modo trasparente.
307 
308 Tuttavia, ci sono un paio di situazione dove diventa necessario avere un
309 livello di gestione della compatibilità per risolvere le differenze di
310 dimensioni fra 32-bit e 64-bit.
311 
312 Il primo caso è quando un kernel a 64-bit supporta anche programmi in spazio
313 utente a 32-bit, perciò dovrà ispezionare aree della memoria (``__user``) che
314 potrebbero contenere valori a 32-bit o a 64-bit.  In particolar modo, questo
315 è necessario quando un argomento di una chiamata di sistema è:
316 
317  - un puntatore ad un puntatore
318  - un puntatore ad una struttura dati contenente a sua volta un puntatore
319    ( 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 dimensione
323    variabile.
324 
325 Il secondo caso che richiede un livello di gestione della compatibilità è
326 quando uno degli argomenti di una chiamata a sistema è esplicitamente un tipo
327 a 64-bit anche su architetture a 32-bit, per esempio ``loff_t`` o ``__u64``.
328 In questo caso, un valore che arriva ad un kernel a 64-bit da un'applicazione
329 a 32-bit verrà diviso in due valori a 32-bit che dovranno essere riassemblati
330 in questo livello di compatibilità.
331 
332 (Da notare che non serve questo livello di compatibilità per argomenti che
333 sono puntatori ad un tipo esplicitamente a 64-bit; per esempio, in
334 :manpage:`splice(2)` l'argomento di tipo ``loff_t __user *`` non necessita
335 di una chiamata di sistema ``compat_``)
336 
337 La versione compatibile della nostra chiamata di sistema si chiamerà
338 ``compat_sys_xyzzy()``, e viene aggiunta utilizzando la macro
339 ``COMPAT_SYSCALL_DEFINEn()`` (simile a SYSCALL_DEFINEn).  Questa versione
340 dell'implementazione è parte del kernel a 64-bit ma accetta parametri a 32-bit
341 che trasformerà secondo le necessità (tipicamente, la versione
342 ``compat_sys_`` converte questi valori nello loro corrispondente a 64-bit e
343 può chiamare la versione ``sys_`` oppure invocare una funzione che implementa
344 le parti comuni).
345 
346 Il punto d'accesso *compat* deve avere il corrispondente prototipo di funzione
347 in ``include/linux/compat.h``, marcato come asmlinkage di modo da abbinargli
348 il modo in cui quelle chiamate di sistema verranno invocate::
349 
350     asmlinkage long compat_sys_xyzzy(...);
351 
352 Se la chiamata di sistema prevede una struttura dati organizzata in modo
353 diverso per sistemi a 32-bit e per quelli a 64-bit, diciamo
354 ``struct xyzzy_args``, allora il file d'intestazione
355 ``then the include/linux/compat.h`` deve includere la sua versione
356 *compatibile* (``struct compat_xyzzy_args``); ogni variabile con
357 dimensione variabile deve avere il proprio tipo ``compat_`` corrispondente
358 a quello in ``struct xyzzy_args``.  La funzione ``compat_sys_xyzzy()``
359 può usare la struttura ``compat_`` per analizzare gli argomenti ricevuti
360 da una chiamata a 32-bit.
361 
362 Per 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 
371 nella struttura ``struct xyzzy_args``, allora la struttura
372 ``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 
381 La lista generica delle chiamate di sistema ha bisogno di essere
382 aggiustata al fine di permettere l'uso della versione *compatibile*;
383 la voce in ``include/uapi/asm-generic/unistd.h`` dovrebbero usare
384 ``__SC_COMP`` piuttosto di ``__SYSCALL``::
385 
386     #define __NR_xyzzy 292
387     __SC_COMP(__NR_xyzzy, sys_xyzzy, compat_sys_xyzzy)
388 
389 Riassumendo, vi serve:
390 
391  - un ``COMPAT_SYSCALL_DEFINEn(xyzzy, ...)`` per il punto d'accesso
392    *compatibile*
393  - un prototipo in ``include/linux/compat.h``
394  - (se necessario) una struttura di compatibilità a 32-bit in
395    ``include/linux/compat.h``
396  - una voce ``__SC_COMP``, e non ``__SYSCALL``, in
397    ``include/uapi/asm-generic/unistd.h``
398 
399 Compatibilità delle chiamate di sistema (x86)
400 ---------------------------------------------
401 
402 Per collegare una chiamata di sistema, su un'architettura x86, con la sua
403 versione *compatibile*, è necessario aggiustare la voce nella tabella
404 delle syscall.
405 
406 Per prima cosa, la voce in ``arch/x86/entry/syscalls/syscall_32.tbl`` prende
407 un argomento aggiuntivo per indicare che un programma in spazio utente
408 a 32-bit, eseguito su un kernel a 64-bit, dovrebbe accedere tramite il punto
409 d'accesso compatibile::
410 
411     380   i386     xyzzy     sys_xyzzy    __ia32_compat_sys_xyzzy
412 
413 Secondo, dovete capire cosa dovrebbe succedere alla nuova chiamata di sistema
414 per la versione dell'ABI x32.  Qui C'è una scelta da fare: gli argomenti
415 possono corrisponde alla versione a 64-bit o a quella a 32-bit.
416 
417 Se c'è un puntatore ad un puntatore, la decisione è semplice: x32 è ILP32,
418 quindi gli argomenti dovrebbero corrispondere a quelli a 32-bit, e la voce in
419 ``arch/x86/entry/syscalls/syscall_64.tbl`` sarà divisa cosicché i programmi
420 x32 eseguano la chiamata *compatibile*::
421 
422     333   64       xyzzy     sys_xyzzy
423     ...
424     555   x32      xyzzy     __x32_compat_sys_xyzzy
425 
426 Se non ci sono puntatori, allora è preferibile riutilizzare la chiamata di
427 sistema a 64-bit per l'ABI x32 (e di conseguenza la voce in
428 arch/x86/entry/syscalls/syscall_64.tbl rimane immutata).
429 
430 In ambo i casi, dovreste verificare che i tipi usati dagli argomenti
431 abbiano un'esatta corrispondenza da x32 (-mx32) al loro equivalente a
432 32-bit (-m32) o 64-bit (-m64).
433 
434 
435 Chiamate di sistema che ritornano altrove
436 -----------------------------------------
437 
438 Nella maggior parte delle chiamate di sistema, al termine della loro
439 esecuzione, i programmi in spazio utente riprendono esattamente dal punto
440 in cui si erano interrotti -- quindi dall'istruzione successiva, con lo
441 stesso *stack* e con la maggior parte del registri com'erano stati
442 lasciati prima della chiamata di sistema, e anche con la stessa memoria
443 virtuale.
444 
445 Tuttavia, alcune chiamata di sistema fanno le cose in modo differente.
446 Potrebbero ritornare ad un punto diverso (``rt_sigreturn``) o cambiare
447 la memoria in spazio utente (``fork``/``vfork``/``clone``) o perfino
448 l'architettura del programma (``execve``/``execveat``).
449 
450 Per permettere tutto ciò, l'implementazione nel kernel di questo tipo di
451 chiamate di sistema potrebbero dover salvare e ripristinare registri
452 aggiuntivi nello *stack* del kernel, permettendo così un controllo completo
453 su dove e come l'esecuzione dovrà continuare dopo l'esecuzione della
454 chiamata di sistema.
455 
456 Queste saranno specifiche per ogni architettura, ma tipicamente si definiscono
457 dei punti d'accesso in *assembly* per salvare/ripristinare i registri
458 aggiuntivi e quindi chiamare il vero punto d'accesso per la chiamata di
459 sistema.
460 
461 Per l'architettura x86_64, questo è implementato come un punto d'accesso
462 ``stub_xyzzy`` in ``arch/x86/entry/entry_64.S``, e la voce nella tabella
463 di syscall (``arch/x86/entry/syscalls/syscall_64.tbl``) verrà corretta di
464 conseguenza::
465 
466     333   common   xyzzy     stub_xyzzy
467 
468 L'equivalente per programmi a 32-bit eseguiti su un kernel a 64-bit viene
469 normalmente chiamato ``stub32_xyzzy`` e implementato in
470 ``arch/x86/entry/entry_64_compat.S`` con la corrispondente voce nella tabella
471 di syscall ``arch/x86/entry/syscalls/syscall_32.tbl`` corretta nel
472 seguente modo::
473 
474     380   i386     xyzzy     sys_xyzzy    stub32_xyzzy
475 
476 Se una chiamata di sistema necessita di un livello di compatibilità (come
477 nella sezione precedente), allora la versione ``stub32_`` deve invocare
478 la versione ``compat_sys_`` piuttosto che quella nativa a 64-bit.  In aggiunta,
479 se l'implementazione dell'ABI x32 è diversa da quella x86_64, allora la sua
480 voce nella tabella di syscall dovrà chiamare uno *stub* che invoca la versione
481 ``compat_sys_``,
482 
483 Per completezza, sarebbe carino impostare una mappatura cosicché
484 *user-mode* Linux (UML) continui a funzionare -- la sua tabella di syscall
485 farà riferimento a stub_xyzzy, ma UML non include l'implementazione
486 in ``arch/x86/entry/entry_64.S`` (perché UML simula i registri eccetera).
487 Correggerlo è semplice, basta aggiungere una #define in
488 ``arch/x86/um/sys_call_table_64.c``::
489 
490     #define stub_xyzzy sys_xyzzy
491 
492 
493 Altri dettagli
494 --------------
495 
496 La maggior parte dei kernel tratta le chiamate di sistema allo stesso modo,
497 ma possono esserci rare eccezioni per le quali potrebbe essere necessario
498 l'aggiornamento della vostra chiamata di sistema.
499 
500 Il sotto-sistema di controllo (*audit subsystem*) è uno di questi casi
501 speciali; esso include (per architettura) funzioni che classificano alcuni
502 tipi di chiamate di sistema -- in particolare apertura dei file
503 (``open``/``openat``), esecuzione dei programmi (``execve``/``exeveat``)
504 oppure multiplatori di socket (``socketcall``). Se la vostra nuova chiamata
505 di sistema è simile ad una di queste, allora il sistema di controllo dovrebbe
506 essere aggiornato.
507 
508 Più in generale, se esiste una chiamata di sistema che è simile alla vostra,
509 vale la pena fare una ricerca con ``grep`` su tutto il kernel per la chiamata
510 di sistema esistente per verificare che non ci siano altri casi speciali.
511 
512 
513 Verifica
514 --------
515 
516 Una nuova chiamata di sistema dev'essere, ovviamente, provata; è utile fornire
517 ai revisori un programma in spazio utente che mostri l'uso della chiamata di
518 sistema.  Un buon modo per combinare queste cose è quello di aggiungere un
519 semplice programma di auto-verifica in una nuova cartella in
520 ``tools/testing/selftests/``.
521 
522 Per una nuova chiamata di sistema, ovviamente, non ci sarà alcuna funzione
523 in libc e quindi il programma di verifica dovrà invocarla usando ``syscall()``;
524 inoltre, se la nuova chiamata di sistema prevede un nuova struttura dati
525 visibile in spazio utente, il file d'intestazione necessario dev'essere
526 installato al fine di compilare il programma.
527 
528 Assicuratevi che il programma di auto-verifica possa essere eseguito
529 correttamente su tutte le architetture supportate.  Per esempio, verificate che
530 funzioni quando viene compilato per x86_64 (-m64), x86_32 (-m32) e x32 (-mx32).
531 
532 Al fine di una più meticolosa ed estesa verifica della nuova funzionalità,
533 dovreste considerare l'aggiunta di nuove verifica al progetto 'Linux Test',
534 oppure 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.git
538 
539 
540 Pagine man
541 ----------
542 
543 Tutte le nuove chiamate di sistema dovrebbero avere una pagina man completa,
544 idealmente usando i marcatori groff, ma anche il puro testo può andare.  Se
545 state usando groff, è utile che includiate nella email di presentazione una
546 versione già convertita in formato ASCII: semplificherà la vita dei revisori.
547 
548 Le pagine man dovrebbero essere in copia-conoscenza verso
549 linux-man@vger.kernel.org
550 Per maggiori dettagli, leggere
551 https://www.kernel.org/doc/man-pages/patches.html
552 
553 
554 Non invocate chiamate di sistema dal kernel
555 -------------------------------------------
556 
557 Le chiamate di sistema sono, come già detto prima, punti di interazione fra
558 lo spazio utente e il kernel.  Perciò, le chiamate di sistema come
559 ``sys_xyzzy()`` o ``compat_sys_xyzzy()`` dovrebbero essere chiamate solo dallo
560 spazio utente attraverso la tabella syscall, ma non da nessun altro punto nel
561 kernel.  Se la nuova funzionalità è utile all'interno del kernel, per esempio
562 dev'essere condivisa fra una vecchia e una nuova chiamata di sistema o
563 dev'essere utilizzata da una chiamata di sistema e la sua variante compatibile,
564 allora dev'essere implementata come una funzione di supporto
565 (*helper function*) (per esempio ``ksys_xyzzy()``).  Questa funzione potrà
566 essere chiamata dallo *stub* (``sys_xyzzy()``), dalla variante compatibile
567 (``compat_sys_xyzzy()``), e/o da altri parti del kernel.
568 
569 Sui sistemi x86 a 64-bit, a partire dalla versione v4.17 è un requisito
570 fondamentale quello di non invocare chiamate di sistema all'interno del kernel.
571 Esso usa una diversa convenzione per l'invocazione di chiamate di sistema dove
572 ``struct pt_regs`` viene decodificata al volo in una funzione che racchiude
573 la chiamata di sistema la quale verrà eseguita successivamente.
574 Questo significa che verranno passati solo i parametri che sono davvero
575 necessari ad una specifica chiamata di sistema, invece che riempire ogni volta
576 6 registri del processore con contenuti presi dallo spazio utente (potrebbe
577 causare seri problemi nella sequenza di chiamate).
578 
579 Inoltre, le regole su come i dati possano essere usati potrebbero differire
580 fra il kernel e l'utente.  Questo è un altro motivo per cui invocare
581 ``sys_xyzzy()`` è generalmente una brutta idea.
582 
583 Eccezioni a questa regola vengono accettate solo per funzioni d'architetture
584 che surclassano quelle generiche, per funzioni d'architettura di compatibilità,
585 o per altro codice in arch/
586 
587 
588 Riferimenti e fonti
589 -------------------
590 
591  - Articolo di Michael Kerris su LWN sull'uso dell'argomento flags nelle
592    chiamate di sistema: https://lwn.net/Articles/585415/
593  - Articolo di Michael Kerris su LWN su come gestire flag sconosciuti in
594    una chiamata di sistema: https://lwn.net/Articles/588444/
595  - Articolo di Jake Edge su LWN che descrive i limiti degli argomenti a 64-bit
596    delle chiamate di sistema: https://lwn.net/Articles/311630/
597  - Una coppia di articoli di David Drysdale che descrivono i dettagli del
598    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 man
604    :manpage:`syscall(2)` :
605    http://man7.org/linux/man-pages/man2/syscall.2.html#NOTES
606  - Collezione di email di Linux Torvalds sui problemi relativi a ``ioctl()``:
607    http://yarchive.net/comp/linux/ioctl.html
608  - "Come non inventare interfacce del kernel", Arnd Bergmann,
609    http://www.ukuug.org/events/linux2007/2007/papers/Bergmann.pdf
610  - 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 informazioni
613    su una nuova chiamata di sistema dovrebbero essere contenute nello stesso
614    filone di discussione di email: https://lore.kernel.org/r/20140724144747.3041b208832bbdf9fbce5d96@linux-foundation.org
615  - Raccomandazioni da Michael Kerrisk circa il fatto che le nuove chiamate di
616    sistema dovrebbero avere una pagina man: https://lore.kernel.org/r/CAKgNAkgMA39AfoSoA5Pe1r9N+ZzfYQNvNPvcRN7tOvRb8+v06Q@mail.gmail.com
617  - Consigli da Thomas Gleixner sul fatto che il collegamento all'architettura
618    x86 dovrebbe avvenire in un *commit* differente:
619    https://lore.kernel.org/r/alpine.DEB.2.11.1411191249560.3909@nanos
620  - Consigli da Greg Kroah-Hartman circa la bontà d'avere una pagina man e un
621    programma di auto-verifica per le nuove chiamate di sistema:
622    https://lore.kernel.org/r/20140320025530.GA25469@kroah.com
623  - Discussione di Michael Kerrisk sulle nuove chiamate di sistema contro
624    le estensioni :manpage:`prctl(2)`: https://lore.kernel.org/r/CAHO5Pa3F2MjfTtfNxa8LbnkeeU8=YJ+9tDqxZpw7Gz59E-4AUg@mail.gmail.com
625  - Consigli da Ingo Molnar che le chiamate di sistema con più argomenti
626    dovrebbero incapsularli in una struttura che includa un argomento
627    *size* per garantire l'estensibilità futura:
628    https://lore.kernel.org/r/20150730083831.GA22182@gmail.com
629  - Un certo numero di casi strani emersi dall'uso (riuso) dei flag O_*:
630 
631     - commit 75069f2b5bfb ("vfs: renumber FMODE_NONOTIFY and add to uniqueness
632       check")
633     - commit 12ed2e36c98a ("fanotify: FMODE_NONOTIFY and __O_SYNC in sparc
634       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.org
639  - Raccomandazioni da Greg Kroah-Hartman sul fatto che i flag sconosciuti dovrebbero
640    essere controllati: https://lore.kernel.org/r/20140717193330.GB4703@kroah.com
641  - Raccomandazioni da Linus Torvalds che le chiamate di sistema x32 dovrebbero
642    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.com

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

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

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

sflogo.php