Back to home page

OSCL-LXR

 
 

    


0001 .. include:: ../disclaimer-ita.rst
0002 
0003 :Original: :ref:`Documentation/process/adding-syscalls.rst <addsyscalls>`
0004 :Translator: Federico Vaga <federico.vaga@vaga.pv.it>
0005 
0006 .. _it_addsyscalls:
0007 
0008 Aggiungere una nuova chiamata di sistema
0009 ========================================
0010 
0011 Questo documento descrive quello che è necessario sapere per aggiungere
0012 nuove chiamate di sistema al kernel Linux; questo è da considerarsi come
0013 un'aggiunta ai soliti consigli su come proporre nuove modifiche
0014 :ref:`Documentation/translations/it_IT/process/submitting-patches.rst <it_submittingpatches>`.
0015 
0016 
0017 Alternative alle chiamate di sistema
0018 ------------------------------------
0019 
0020 La prima considerazione da fare quando si aggiunge una nuova chiamata di
0021 sistema è quella di valutare le alternative.  Nonostante le chiamate di sistema
0022 siano il punto di interazione fra spazio utente e kernel più tradizionale ed
0023 ovvio, esistono altre possibilità - scegliete quella che meglio si adatta alle
0024 vostra interfaccia.
0025 
0026  - Se le operazioni coinvolte possono rassomigliare a quelle di un filesystem,
0027    allora potrebbe avere molto più senso la creazione di un nuovo filesystem o
0028    dispositivo.  Inoltre, questo rende più facile incapsulare la nuova
0029    funzionalità in un modulo kernel piuttosto che essere sviluppata nel cuore
0030    del kernel.
0031 
0032      - Se la nuova funzionalità prevede operazioni dove il kernel notifica
0033        lo spazio utente su un avvenimento, allora restituire un descrittore
0034        di file all'oggetto corrispondente permette allo spazio utente di
0035        utilizzare ``poll``/``select``/``epoll`` per ricevere quelle notifiche.
0036      - Tuttavia, le operazioni che non si sposano bene con operazioni tipo
0037        :manpage:`read(2)`/:manpage:`write(2)` dovrebbero essere implementate
0038        come chiamate :manpage:`ioctl(2)`, il che potrebbe portare ad un'API in
0039        un qualche modo opaca.
0040 
0041  - Se dovete esporre solo delle informazioni sul sistema, un nuovo nodo in
0042    sysfs (vedere ``Documentation/filesystems/sysfs.rst``) o
0043    in procfs potrebbe essere sufficiente.  Tuttavia, l'accesso a questi
0044    meccanismi richiede che il filesystem sia montato, il che potrebbe non
0045    essere sempre vero (per esempio, in ambienti come namespace/sandbox/chroot).
0046    Evitate d'aggiungere nuove API in debugfs perché questo non viene
0047    considerata un'interfaccia di 'produzione' verso lo spazio utente.
0048  - Se l'operazione è specifica ad un particolare file o descrittore, allora
0049    potrebbe essere appropriata l'aggiunta di un comando :manpage:`fcntl(2)`.
0050    Tuttavia, :manpage:`fcntl(2)` è una chiamata di sistema multiplatrice che
0051    nasconde una notevole complessità, quindi è ottima solo quando la nuova
0052    funzione assomiglia a quelle già esistenti in :manpage:`fcntl(2)`, oppure
0053    la nuova funzionalità è veramente semplice (per esempio, leggere/scrivere
0054    un semplice flag associato ad un descrittore di file).
0055  - Se l'operazione è specifica ad un particolare processo, allora
0056    potrebbe essere appropriata l'aggiunta di un comando :manpage:`prctl(2)`.
0057    Come per :manpage:`fcntl(2)`, questa chiamata di sistema è un complesso
0058    multiplatore quindi è meglio usarlo per cose molto simili a quelle esistenti
0059    nel comando ``prctl`` oppure per leggere/scrivere un semplice flag relativo
0060    al processo.
0061 
0062 
0063 Progettare l'API: pianificare le estensioni
0064 -------------------------------------------
0065 
0066 Una nuova chiamata di sistema diventerà parte dell'API del kernel, e
0067 dev'essere supportata per un periodo indefinito.  Per questo, è davvero
0068 un'ottima idea quella di discutere apertamente l'interfaccia sulla lista
0069 di discussione del kernel, ed è altrettanto importante pianificarne eventuali
0070 estensioni future.
0071 
0072 (Nella tabella delle chiamate di sistema sono disseminati esempi dove questo
0073 non fu fatto, assieme ai corrispondenti aggiornamenti -
0074 ``eventfd``/``eventfd2``, ``dup2``/``dup3``, ``inotify_init``/``inotify_init1``,
0075 ``pipe``/``pipe2``, ``renameat``/``renameat2`` --quindi imparate dalla storia
0076 del kernel e pianificate le estensioni fin dall'inizio)
0077 
0078 Per semplici chiamate di sistema che accettano solo un paio di argomenti,
0079 il modo migliore di permettere l'estensibilità è quello di includere un
0080 argomento *flags* alla chiamata di sistema.  Per assicurarsi che i programmi
0081 dello spazio utente possano usare in sicurezza *flags* con diverse versioni
0082 del kernel, verificate se *flags* contiene un qualsiasi valore sconosciuto,
0083 in qual caso rifiutate la chiamata di sistema (con ``EINVAL``)::
0084 
0085     if (flags & ~(THING_FLAG1 | THING_FLAG2 | THING_FLAG3))
0086         return -EINVAL;
0087 
0088 (Se *flags* non viene ancora utilizzato, verificate che l'argomento sia zero)
0089 
0090 Per chiamate di sistema più sofisticate che coinvolgono un numero più grande di
0091 argomenti, il modo migliore è quello di incapsularne la maggior parte in una
0092 struttura dati che verrà passata per puntatore.  Questa struttura potrà
0093 funzionare con future estensioni includendo un campo *size*::
0094 
0095     struct xyzzy_params {
0096         u32 size; /* userspace sets p->size = sizeof(struct xyzzy_params) */
0097         u32 param_1;
0098         u64 param_2;
0099         u64 param_3;
0100     };
0101 
0102 Fintanto che un qualsiasi campo nuovo, diciamo ``param_4``, è progettato per
0103 offrire il comportamento precedente quando vale zero, allora questo permetterà
0104 di gestire un conflitto di versione in entrambe le direzioni:
0105 
0106  - un vecchio kernel può gestire l'accesso di una versione moderna di un
0107    programma in spazio utente verificando che la memoria oltre la dimensione
0108    della struttura dati attesa sia zero (in pratica verificare che
0109    ``param_4 == 0``).
0110  - un nuovo kernel può gestire l'accesso di una versione vecchia di un
0111    programma in spazio utente estendendo la struttura dati con zeri (in pratica
0112    ``param_4 = 0``).
0113 
0114 Vedere :manpage:`perf_event_open(2)` e la funzione ``perf_copy_attr()`` (in
0115 ``kernel/events/core.c``) per un esempio pratico di questo approccio.
0116 
0117 
0118 Progettare l'API: altre considerazioni
0119 --------------------------------------
0120 
0121 Se la vostra nuova chiamata di sistema permette allo spazio utente di fare
0122 riferimento ad un oggetto del kernel, allora questa dovrebbe usare un
0123 descrittore di file per accesso all'oggetto - non inventatevi nuovi tipi di
0124 accesso da spazio utente quando il kernel ha già dei meccanismi e una semantica
0125 ben definita per utilizzare i descrittori di file.
0126 
0127 Se la vostra nuova chiamata di sistema :manpage:`xyzzy(2)` ritorna un nuovo
0128 descrittore di file, allora l'argomento *flags* dovrebbe includere un valore
0129 equivalente a ``O_CLOEXEC`` per i nuovi descrittori.  Questo rende possibile,
0130 nello spazio utente, la chiusura della finestra temporale fra le chiamate a
0131 ``xyzzy()`` e ``fcntl(fd, F_SETFD, FD_CLOEXEC)``, dove un inaspettato
0132 ``fork()`` o ``execve()`` potrebbe trasferire il descrittore al programma
0133 eseguito (Comunque, resistete alla tentazione di riutilizzare il valore di
0134 ``O_CLOEXEC`` dato che è specifico dell'architettura e fa parte di una
0135 enumerazione di flag ``O_*`` che è abbastanza ricca).
0136 
0137 Se la vostra nuova chiamata di sistema ritorna un nuovo descrittore di file,
0138 dovreste considerare che significato avrà l'uso delle chiamate di sistema
0139 della famiglia di :manpage:`poll(2)`. Rendere un descrittore di file pronto
0140 per la lettura o la scrittura è il tipico modo del kernel per notificare lo
0141 spazio utente circa un evento associato all'oggetto del kernel.
0142 
0143 Se la vostra nuova chiamata di sistema :manpage:`xyzzy(2)` ha un argomento
0144 che è il percorso ad un file::
0145 
0146     int sys_xyzzy(const char __user *path, ..., unsigned int flags);
0147 
0148 dovreste anche considerare se non sia più appropriata una versione
0149 :manpage:`xyzzyat(2)`::
0150 
0151     int sys_xyzzyat(int dfd, const char __user *path, ..., unsigned int flags);
0152 
0153 Questo permette più flessibilità su come lo spazio utente specificherà il file
0154 in questione; in particolare, permette allo spazio utente di richiedere la
0155 funzionalità su un descrittore di file già aperto utilizzando il *flag*
0156 ``AT_EMPTY_PATH``, in pratica otterremmo gratuitamente l'operazione
0157 :manpage:`fxyzzy(3)`::
0158 
0159  - xyzzyat(AT_FDCWD, path, ..., 0) is equivalent to xyzzy(path,...)
0160  - xyzzyat(fd, "", ..., AT_EMPTY_PATH) is equivalent to fxyzzy(fd, ...)
0161 
0162 (Per maggiori dettagli sulla logica delle chiamate \*at(), leggete la pagina
0163 man :manpage:`openat(2)`; per un esempio di AT_EMPTY_PATH, leggere la pagina
0164 man :manpage:`fstatat(2)`).
0165 
0166 Se la vostra nuova chiamata di sistema :manpage:`xyzzy(2)` prevede un parametro
0167 per descrivere uno scostamento all'interno di un file, usate ``loff_t`` come
0168 tipo cosicché scostamenti a 64-bit potranno essere supportati anche su
0169 architetture a 32-bit.
0170 
0171 Se la vostra nuova chiamata di sistema :manpage:`xyzzy(2)` prevede l'uso di
0172 funzioni riservate, allora dev'essere gestita da un opportuno bit di privilegio
0173 (verificato con una chiamata a ``capable()``), come descritto nella pagina man
0174 :manpage:`capabilities(7)`.  Scegliete un bit di privilegio già esistente per
0175 gestire la funzionalità associata, ma evitate la combinazione di diverse
0176 funzionalità vagamente collegate dietro lo stesso bit, in quanto va contro il
0177 principio di *capabilities* di separare i poteri di root.  In particolare,
0178 evitate di aggiungere nuovi usi al fin-troppo-generico privilegio
0179 ``CAP_SYS_ADMIN``.
0180 
0181 Se la vostra nuova chiamata di sistema :manpage:`xyzzy(2)` manipola altri
0182 processi oltre a quello chiamato, allora dovrebbe essere limitata (usando
0183 la chiamata ``ptrace_may_access()``) di modo che solo un processo chiamante
0184 con gli stessi permessi del processo in oggetto, o con i necessari privilegi,
0185 possa manipolarlo.
0186 
0187 Infine, state attenti che in alcune architetture non-x86 la vita delle chiamate
0188 di sistema con argomenti a 64-bit viene semplificata se questi argomenti
0189 ricadono in posizioni dispari (pratica, i parametri 1, 3, 5); questo permette
0190 l'uso di coppie contigue di registri a 32-bit.  (Questo non conta se gli
0191 argomenti sono parte di una struttura dati che viene passata per puntatore).
0192 
0193 
0194 Proporre l'API
0195 --------------
0196 
0197 Al fine di rendere le nuove chiamate di sistema di facile revisione, è meglio
0198 che dividiate le modifiche i pezzi separati.  Questi dovrebbero includere
0199 almeno le seguenti voci in *commit* distinti (ognuno dei quali sarà descritto
0200 più avanti):
0201 
0202  - l'essenza dell'implementazione della chiamata di sistema, con i prototipi,
0203    i numeri generici, le modifiche al Kconfig e l'implementazione *stub* di
0204    ripiego.
0205  - preparare la nuova chiamata di sistema per un'architettura specifica,
0206    solitamente x86 (ovvero tutti: x86_64, x86_32 e x32).
0207  - un programma di auto-verifica da mettere in ``tools/testing/selftests/``
0208    che mostri l'uso della chiamata di sistema.
0209  - una bozza di pagina man per la nuova chiamata di sistema. Può essere
0210    scritta nell'email di presentazione, oppure come modifica vera e propria
0211    al repositorio delle pagine man.
0212 
0213 Le proposte di nuove chiamate di sistema, come ogni altro modifica all'API del
0214 kernel, deve essere sottomessa alla lista di discussione
0215 linux-api@vger.kernel.org.
0216 
0217 
0218 Implementazione di chiamate di sistema generiche
0219 ------------------------------------------------
0220 
0221 Il principale punto d'accesso alla vostra nuova chiamata di sistema
0222 :manpage:`xyzzy(2)` verrà chiamato ``sys_xyzzy()``; ma, piuttosto che in modo
0223 esplicito, lo aggiungerete tramite la macro ``SYSCALL_DEFINEn``. La 'n'
0224 indica il numero di argomenti della chiamata di sistema; la macro ha come
0225 argomento il nome della chiamata di sistema, seguito dalle coppie (tipo, nome)
0226 per definire i suoi parametri.  L'uso di questa macro permette di avere
0227 i metadati della nuova chiamata di sistema disponibili anche per altri
0228 strumenti.
0229 
0230 Il nuovo punto d'accesso necessita anche del suo prototipo di funzione in
0231 ``include/linux/syscalls.h``, marcato come asmlinkage di modo da abbinargli
0232 il modo in cui quelle chiamate di sistema verranno invocate::
0233 
0234     asmlinkage long sys_xyzzy(...);
0235 
0236 Alcune architetture (per esempio x86) hanno le loro specifiche tabelle di
0237 chiamate di sistema (syscall), ma molte altre architetture condividono una
0238 tabella comune di syscall. Aggiungete alla lista generica la vostra nuova
0239 chiamata di sistema aggiungendo un nuovo elemento alla lista in
0240 ``include/uapi/asm-generic/unistd.h``::
0241 
0242     #define __NR_xyzzy 292
0243     __SYSCALL(__NR_xyzzy, sys_xyzzy)
0244 
0245 Aggiornate anche il contatore __NR_syscalls di modo che sia coerente con
0246 l'aggiunta della nuove chiamate di sistema; va notato che se più di una nuova
0247 chiamata di sistema viene aggiunga nella stessa finestra di sviluppo, il numero
0248 della vostra nuova syscall potrebbe essere aggiustato al fine di risolvere i
0249 conflitti.
0250 
0251 Il file ``kernel/sys_ni.c`` fornisce le implementazioni *stub* di ripiego che
0252 ritornano ``-ENOSYS``.  Aggiungete la vostra nuova chiamata di sistema anche
0253 qui::
0254 
0255     COND_SYSCALL(xyzzy);
0256 
0257 La vostra nuova funzionalità del kernel, e la chiamata di sistema che la
0258 controlla, dovrebbero essere opzionali. Quindi, aggiungete un'opzione
0259 ``CONFIG`` (solitamente in ``init/Kconfig``).  Come al solito per le nuove
0260 opzioni ``CONFIG``:
0261 
0262  - Includete una descrizione della nuova funzionalità e della chiamata di
0263    sistema che la controlla.
0264  - Rendete l'opzione dipendente da EXPERT se dev'essere nascosta agli utenti
0265    normali.
0266  - Nel Makefile, rendere tutti i nuovi file sorgenti, che implementano la
0267    nuova funzionalità, dipendenti dall'opzione CONFIG (per esempio
0268    ``obj-$(CONFIG_XYZZY_SYSCALL) += xyzzy.o``).
0269  - Controllate due volte che sia possibile generare il kernel con la nuova
0270    opzione CONFIG disabilitata.
0271 
0272 Per riassumere, vi serve un *commit* che includa:
0273 
0274  - un'opzione ``CONFIG``per la nuova funzione, normalmente in ``init/Kconfig``
0275  - ``SYSCALL_DEFINEn(xyzzy, ...)`` per il punto d'accesso
0276  - il corrispondente prototipo in ``include/linux/syscalls.h``
0277  - un elemento nella tabella generica in ``include/uapi/asm-generic/unistd.h``
0278  - *stub* di ripiego in ``kernel/sys_ni.c``
0279 
0280 
0281 Implementazione delle chiamate di sistema x86
0282 ---------------------------------------------
0283 
0284 Per collegare la vostra nuova chiamate di sistema alle piattaforme x86,
0285 dovete aggiornate la tabella principale di syscall.  Assumendo che la vostra
0286 nuova chiamata di sistema non sia particolarmente speciale (vedere sotto),
0287 dovete aggiungere un elemento *common* (per x86_64 e x32) in
0288 arch/x86/entry/syscalls/syscall_64.tbl::
0289 
0290     333   common   xyzzy     sys_xyzzy
0291 
0292 e un elemento per *i386* ``arch/x86/entry/syscalls/syscall_32.tbl``::
0293 
0294     380   i386     xyzzy     sys_xyzzy
0295 
0296 Ancora una volta, questi numeri potrebbero essere cambiati se generano
0297 conflitti durante la finestra di integrazione.
0298 
0299 
0300 Chiamate di sistema compatibili (generico)
0301 ------------------------------------------
0302 
0303 Per molte chiamate di sistema, la stessa implementazione a 64-bit può essere
0304 invocata anche quando il programma in spazio utente è a 32-bit; anche se la
0305 chiamata di sistema include esplicitamente un puntatore, questo viene gestito
0306 in modo trasparente.
0307 
0308 Tuttavia, ci sono un paio di situazione dove diventa necessario avere un
0309 livello di gestione della compatibilità per risolvere le differenze di
0310 dimensioni fra 32-bit e 64-bit.
0311 
0312 Il primo caso è quando un kernel a 64-bit supporta anche programmi in spazio
0313 utente a 32-bit, perciò dovrà ispezionare aree della memoria (``__user``) che
0314 potrebbero contenere valori a 32-bit o a 64-bit.  In particolar modo, questo
0315 è necessario quando un argomento di una chiamata di sistema è:
0316 
0317  - un puntatore ad un puntatore
0318  - un puntatore ad una struttura dati contenente a sua volta un puntatore
0319    ( ad esempio ``struct iovec __user *``)
0320  - un puntatore ad un tipo intero di dimensione variabile (``time_t``,
0321    ``off_t``, ``long``, ...)
0322  - un puntatore ad una struttura dati contenente un tipo intero di dimensione
0323    variabile.
0324 
0325 Il secondo caso che richiede un livello di gestione della compatibilità è
0326 quando uno degli argomenti di una chiamata a sistema è esplicitamente un tipo
0327 a 64-bit anche su architetture a 32-bit, per esempio ``loff_t`` o ``__u64``.
0328 In questo caso, un valore che arriva ad un kernel a 64-bit da un'applicazione
0329 a 32-bit verrà diviso in due valori a 32-bit che dovranno essere riassemblati
0330 in questo livello di compatibilità.
0331 
0332 (Da notare che non serve questo livello di compatibilità per argomenti che
0333 sono puntatori ad un tipo esplicitamente a 64-bit; per esempio, in
0334 :manpage:`splice(2)` l'argomento di tipo ``loff_t __user *`` non necessita
0335 di una chiamata di sistema ``compat_``)
0336 
0337 La versione compatibile della nostra chiamata di sistema si chiamerà
0338 ``compat_sys_xyzzy()``, e viene aggiunta utilizzando la macro
0339 ``COMPAT_SYSCALL_DEFINEn()`` (simile a SYSCALL_DEFINEn).  Questa versione
0340 dell'implementazione è parte del kernel a 64-bit ma accetta parametri a 32-bit
0341 che trasformerà secondo le necessità (tipicamente, la versione
0342 ``compat_sys_`` converte questi valori nello loro corrispondente a 64-bit e
0343 può chiamare la versione ``sys_`` oppure invocare una funzione che implementa
0344 le parti comuni).
0345 
0346 Il punto d'accesso *compat* deve avere il corrispondente prototipo di funzione
0347 in ``include/linux/compat.h``, marcato come asmlinkage di modo da abbinargli
0348 il modo in cui quelle chiamate di sistema verranno invocate::
0349 
0350     asmlinkage long compat_sys_xyzzy(...);
0351 
0352 Se la chiamata di sistema prevede una struttura dati organizzata in modo
0353 diverso per sistemi a 32-bit e per quelli a 64-bit, diciamo
0354 ``struct xyzzy_args``, allora il file d'intestazione
0355 ``then the include/linux/compat.h`` deve includere la sua versione
0356 *compatibile* (``struct compat_xyzzy_args``); ogni variabile con
0357 dimensione variabile deve avere il proprio tipo ``compat_`` corrispondente
0358 a quello in ``struct xyzzy_args``.  La funzione ``compat_sys_xyzzy()``
0359 può usare la struttura ``compat_`` per analizzare gli argomenti ricevuti
0360 da una chiamata a 32-bit.
0361 
0362 Per esempio, se avete i seguenti campi::
0363 
0364     struct xyzzy_args {
0365         const char __user *ptr;
0366         __kernel_long_t varying_val;
0367         u64 fixed_val;
0368         /* ... */
0369     };
0370 
0371 nella struttura ``struct xyzzy_args``, allora la struttura
0372 ``struct compat_xyzzy_args`` dovrebbe avere::
0373 
0374     struct compat_xyzzy_args {
0375         compat_uptr_t ptr;
0376         compat_long_t varying_val;
0377         u64 fixed_val;
0378         /* ... */
0379     };
0380 
0381 La lista generica delle chiamate di sistema ha bisogno di essere
0382 aggiustata al fine di permettere l'uso della versione *compatibile*;
0383 la voce in ``include/uapi/asm-generic/unistd.h`` dovrebbero usare
0384 ``__SC_COMP`` piuttosto di ``__SYSCALL``::
0385 
0386     #define __NR_xyzzy 292
0387     __SC_COMP(__NR_xyzzy, sys_xyzzy, compat_sys_xyzzy)
0388 
0389 Riassumendo, vi serve:
0390 
0391  - un ``COMPAT_SYSCALL_DEFINEn(xyzzy, ...)`` per il punto d'accesso
0392    *compatibile*
0393  - un prototipo in ``include/linux/compat.h``
0394  - (se necessario) una struttura di compatibilità a 32-bit in
0395    ``include/linux/compat.h``
0396  - una voce ``__SC_COMP``, e non ``__SYSCALL``, in
0397    ``include/uapi/asm-generic/unistd.h``
0398 
0399 Compatibilità delle chiamate di sistema (x86)
0400 ---------------------------------------------
0401 
0402 Per collegare una chiamata di sistema, su un'architettura x86, con la sua
0403 versione *compatibile*, è necessario aggiustare la voce nella tabella
0404 delle syscall.
0405 
0406 Per prima cosa, la voce in ``arch/x86/entry/syscalls/syscall_32.tbl`` prende
0407 un argomento aggiuntivo per indicare che un programma in spazio utente
0408 a 32-bit, eseguito su un kernel a 64-bit, dovrebbe accedere tramite il punto
0409 d'accesso compatibile::
0410 
0411     380   i386     xyzzy     sys_xyzzy    __ia32_compat_sys_xyzzy
0412 
0413 Secondo, dovete capire cosa dovrebbe succedere alla nuova chiamata di sistema
0414 per la versione dell'ABI x32.  Qui C'è una scelta da fare: gli argomenti
0415 possono corrisponde alla versione a 64-bit o a quella a 32-bit.
0416 
0417 Se c'è un puntatore ad un puntatore, la decisione è semplice: x32 è ILP32,
0418 quindi gli argomenti dovrebbero corrispondere a quelli a 32-bit, e la voce in
0419 ``arch/x86/entry/syscalls/syscall_64.tbl`` sarà divisa cosicché i programmi
0420 x32 eseguano la chiamata *compatibile*::
0421 
0422     333   64       xyzzy     sys_xyzzy
0423     ...
0424     555   x32      xyzzy     __x32_compat_sys_xyzzy
0425 
0426 Se non ci sono puntatori, allora è preferibile riutilizzare la chiamata di
0427 sistema a 64-bit per l'ABI x32 (e di conseguenza la voce in
0428 arch/x86/entry/syscalls/syscall_64.tbl rimane immutata).
0429 
0430 In ambo i casi, dovreste verificare che i tipi usati dagli argomenti
0431 abbiano un'esatta corrispondenza da x32 (-mx32) al loro equivalente a
0432 32-bit (-m32) o 64-bit (-m64).
0433 
0434 
0435 Chiamate di sistema che ritornano altrove
0436 -----------------------------------------
0437 
0438 Nella maggior parte delle chiamate di sistema, al termine della loro
0439 esecuzione, i programmi in spazio utente riprendono esattamente dal punto
0440 in cui si erano interrotti -- quindi dall'istruzione successiva, con lo
0441 stesso *stack* e con la maggior parte del registri com'erano stati
0442 lasciati prima della chiamata di sistema, e anche con la stessa memoria
0443 virtuale.
0444 
0445 Tuttavia, alcune chiamata di sistema fanno le cose in modo differente.
0446 Potrebbero ritornare ad un punto diverso (``rt_sigreturn``) o cambiare
0447 la memoria in spazio utente (``fork``/``vfork``/``clone``) o perfino
0448 l'architettura del programma (``execve``/``execveat``).
0449 
0450 Per permettere tutto ciò, l'implementazione nel kernel di questo tipo di
0451 chiamate di sistema potrebbero dover salvare e ripristinare registri
0452 aggiuntivi nello *stack* del kernel, permettendo così un controllo completo
0453 su dove e come l'esecuzione dovrà continuare dopo l'esecuzione della
0454 chiamata di sistema.
0455 
0456 Queste saranno specifiche per ogni architettura, ma tipicamente si definiscono
0457 dei punti d'accesso in *assembly* per salvare/ripristinare i registri
0458 aggiuntivi e quindi chiamare il vero punto d'accesso per la chiamata di
0459 sistema.
0460 
0461 Per l'architettura x86_64, questo è implementato come un punto d'accesso
0462 ``stub_xyzzy`` in ``arch/x86/entry/entry_64.S``, e la voce nella tabella
0463 di syscall (``arch/x86/entry/syscalls/syscall_64.tbl``) verrà corretta di
0464 conseguenza::
0465 
0466     333   common   xyzzy     stub_xyzzy
0467 
0468 L'equivalente per programmi a 32-bit eseguiti su un kernel a 64-bit viene
0469 normalmente chiamato ``stub32_xyzzy`` e implementato in
0470 ``arch/x86/entry/entry_64_compat.S`` con la corrispondente voce nella tabella
0471 di syscall ``arch/x86/entry/syscalls/syscall_32.tbl`` corretta nel
0472 seguente modo::
0473 
0474     380   i386     xyzzy     sys_xyzzy    stub32_xyzzy
0475 
0476 Se una chiamata di sistema necessita di un livello di compatibilità (come
0477 nella sezione precedente), allora la versione ``stub32_`` deve invocare
0478 la versione ``compat_sys_`` piuttosto che quella nativa a 64-bit.  In aggiunta,
0479 se l'implementazione dell'ABI x32 è diversa da quella x86_64, allora la sua
0480 voce nella tabella di syscall dovrà chiamare uno *stub* che invoca la versione
0481 ``compat_sys_``,
0482 
0483 Per completezza, sarebbe carino impostare una mappatura cosicché
0484 *user-mode* Linux (UML) continui a funzionare -- la sua tabella di syscall
0485 farà riferimento a stub_xyzzy, ma UML non include l'implementazione
0486 in ``arch/x86/entry/entry_64.S`` (perché UML simula i registri eccetera).
0487 Correggerlo è semplice, basta aggiungere una #define in
0488 ``arch/x86/um/sys_call_table_64.c``::
0489 
0490     #define stub_xyzzy sys_xyzzy
0491 
0492 
0493 Altri dettagli
0494 --------------
0495 
0496 La maggior parte dei kernel tratta le chiamate di sistema allo stesso modo,
0497 ma possono esserci rare eccezioni per le quali potrebbe essere necessario
0498 l'aggiornamento della vostra chiamata di sistema.
0499 
0500 Il sotto-sistema di controllo (*audit subsystem*) è uno di questi casi
0501 speciali; esso include (per architettura) funzioni che classificano alcuni
0502 tipi di chiamate di sistema -- in particolare apertura dei file
0503 (``open``/``openat``), esecuzione dei programmi (``execve``/``exeveat``)
0504 oppure multiplatori di socket (``socketcall``). Se la vostra nuova chiamata
0505 di sistema è simile ad una di queste, allora il sistema di controllo dovrebbe
0506 essere aggiornato.
0507 
0508 Più in generale, se esiste una chiamata di sistema che è simile alla vostra,
0509 vale la pena fare una ricerca con ``grep`` su tutto il kernel per la chiamata
0510 di sistema esistente per verificare che non ci siano altri casi speciali.
0511 
0512 
0513 Verifica
0514 --------
0515 
0516 Una nuova chiamata di sistema dev'essere, ovviamente, provata; è utile fornire
0517 ai revisori un programma in spazio utente che mostri l'uso della chiamata di
0518 sistema.  Un buon modo per combinare queste cose è quello di aggiungere un
0519 semplice programma di auto-verifica in una nuova cartella in
0520 ``tools/testing/selftests/``.
0521 
0522 Per una nuova chiamata di sistema, ovviamente, non ci sarà alcuna funzione
0523 in libc e quindi il programma di verifica dovrà invocarla usando ``syscall()``;
0524 inoltre, se la nuova chiamata di sistema prevede un nuova struttura dati
0525 visibile in spazio utente, il file d'intestazione necessario dev'essere
0526 installato al fine di compilare il programma.
0527 
0528 Assicuratevi che il programma di auto-verifica possa essere eseguito
0529 correttamente su tutte le architetture supportate.  Per esempio, verificate che
0530 funzioni quando viene compilato per x86_64 (-m64), x86_32 (-m32) e x32 (-mx32).
0531 
0532 Al fine di una più meticolosa ed estesa verifica della nuova funzionalità,
0533 dovreste considerare l'aggiunta di nuove verifica al progetto 'Linux Test',
0534 oppure al progetto xfstests per cambiamenti relativi al filesystem.
0535 
0536  - https://linux-test-project.github.io/
0537  - git://git.kernel.org/pub/scm/fs/xfs/xfstests-dev.git
0538 
0539 
0540 Pagine man
0541 ----------
0542 
0543 Tutte le nuove chiamate di sistema dovrebbero avere una pagina man completa,
0544 idealmente usando i marcatori groff, ma anche il puro testo può andare.  Se
0545 state usando groff, è utile che includiate nella email di presentazione una
0546 versione già convertita in formato ASCII: semplificherà la vita dei revisori.
0547 
0548 Le pagine man dovrebbero essere in copia-conoscenza verso
0549 linux-man@vger.kernel.org
0550 Per maggiori dettagli, leggere
0551 https://www.kernel.org/doc/man-pages/patches.html
0552 
0553 
0554 Non invocate chiamate di sistema dal kernel
0555 -------------------------------------------
0556 
0557 Le chiamate di sistema sono, come già detto prima, punti di interazione fra
0558 lo spazio utente e il kernel.  Perciò, le chiamate di sistema come
0559 ``sys_xyzzy()`` o ``compat_sys_xyzzy()`` dovrebbero essere chiamate solo dallo
0560 spazio utente attraverso la tabella syscall, ma non da nessun altro punto nel
0561 kernel.  Se la nuova funzionalità è utile all'interno del kernel, per esempio
0562 dev'essere condivisa fra una vecchia e una nuova chiamata di sistema o
0563 dev'essere utilizzata da una chiamata di sistema e la sua variante compatibile,
0564 allora dev'essere implementata come una funzione di supporto
0565 (*helper function*) (per esempio ``ksys_xyzzy()``).  Questa funzione potrà
0566 essere chiamata dallo *stub* (``sys_xyzzy()``), dalla variante compatibile
0567 (``compat_sys_xyzzy()``), e/o da altri parti del kernel.
0568 
0569 Sui sistemi x86 a 64-bit, a partire dalla versione v4.17 è un requisito
0570 fondamentale quello di non invocare chiamate di sistema all'interno del kernel.
0571 Esso usa una diversa convenzione per l'invocazione di chiamate di sistema dove
0572 ``struct pt_regs`` viene decodificata al volo in una funzione che racchiude
0573 la chiamata di sistema la quale verrà eseguita successivamente.
0574 Questo significa che verranno passati solo i parametri che sono davvero
0575 necessari ad una specifica chiamata di sistema, invece che riempire ogni volta
0576 6 registri del processore con contenuti presi dallo spazio utente (potrebbe
0577 causare seri problemi nella sequenza di chiamate).
0578 
0579 Inoltre, le regole su come i dati possano essere usati potrebbero differire
0580 fra il kernel e l'utente.  Questo è un altro motivo per cui invocare
0581 ``sys_xyzzy()`` è generalmente una brutta idea.
0582 
0583 Eccezioni a questa regola vengono accettate solo per funzioni d'architetture
0584 che surclassano quelle generiche, per funzioni d'architettura di compatibilità,
0585 o per altro codice in arch/
0586 
0587 
0588 Riferimenti e fonti
0589 -------------------
0590 
0591  - Articolo di Michael Kerris su LWN sull'uso dell'argomento flags nelle
0592    chiamate di sistema: https://lwn.net/Articles/585415/
0593  - Articolo di Michael Kerris su LWN su come gestire flag sconosciuti in
0594    una chiamata di sistema: https://lwn.net/Articles/588444/
0595  - Articolo di Jake Edge su LWN che descrive i limiti degli argomenti a 64-bit
0596    delle chiamate di sistema: https://lwn.net/Articles/311630/
0597  - Una coppia di articoli di David Drysdale che descrivono i dettagli del
0598    percorso implementativo di una chiamata di sistema per la versione v3.14:
0599 
0600     - https://lwn.net/Articles/604287/
0601     - https://lwn.net/Articles/604515/
0602 
0603  - Requisiti specifici alle architetture sono discussi nella pagina man
0604    :manpage:`syscall(2)` :
0605    http://man7.org/linux/man-pages/man2/syscall.2.html#NOTES
0606  - Collezione di email di Linux Torvalds sui problemi relativi a ``ioctl()``:
0607    http://yarchive.net/comp/linux/ioctl.html
0608  - "Come non inventare interfacce del kernel", Arnd Bergmann,
0609    http://www.ukuug.org/events/linux2007/2007/papers/Bergmann.pdf
0610  - Articolo di Michael Kerris su LWN sull'evitare nuovi usi di CAP_SYS_ADMIN:
0611    https://lwn.net/Articles/486306/
0612  - Raccomandazioni da Andrew Morton circa il fatto che tutte le informazioni
0613    su una nuova chiamata di sistema dovrebbero essere contenute nello stesso
0614    filone di discussione di email: https://lore.kernel.org/r/20140724144747.3041b208832bbdf9fbce5d96@linux-foundation.org
0615  - Raccomandazioni da Michael Kerrisk circa il fatto che le nuove chiamate di
0616    sistema dovrebbero avere una pagina man: https://lore.kernel.org/r/CAKgNAkgMA39AfoSoA5Pe1r9N+ZzfYQNvNPvcRN7tOvRb8+v06Q@mail.gmail.com
0617  - Consigli da Thomas Gleixner sul fatto che il collegamento all'architettura
0618    x86 dovrebbe avvenire in un *commit* differente:
0619    https://lore.kernel.org/r/alpine.DEB.2.11.1411191249560.3909@nanos
0620  - Consigli da Greg Kroah-Hartman circa la bontà d'avere una pagina man e un
0621    programma di auto-verifica per le nuove chiamate di sistema:
0622    https://lore.kernel.org/r/20140320025530.GA25469@kroah.com
0623  - Discussione di Michael Kerrisk sulle nuove chiamate di sistema contro
0624    le estensioni :manpage:`prctl(2)`: https://lore.kernel.org/r/CAHO5Pa3F2MjfTtfNxa8LbnkeeU8=YJ+9tDqxZpw7Gz59E-4AUg@mail.gmail.com
0625  - Consigli da Ingo Molnar che le chiamate di sistema con più argomenti
0626    dovrebbero incapsularli in una struttura che includa un argomento
0627    *size* per garantire l'estensibilità futura:
0628    https://lore.kernel.org/r/20150730083831.GA22182@gmail.com
0629  - Un certo numero di casi strani emersi dall'uso (riuso) dei flag O_*:
0630 
0631     - commit 75069f2b5bfb ("vfs: renumber FMODE_NONOTIFY and add to uniqueness
0632       check")
0633     - commit 12ed2e36c98a ("fanotify: FMODE_NONOTIFY and __O_SYNC in sparc
0634       conflict")
0635     - commit bb458c644a59 ("Safer ABI for O_TMPFILE")
0636 
0637  - Discussion from Matthew Wilcox about restrictions on 64-bit arguments:
0638    https://lore.kernel.org/r/20081212152929.GM26095@parisc-linux.org
0639  - Raccomandazioni da Greg Kroah-Hartman sul fatto che i flag sconosciuti dovrebbero
0640    essere controllati: https://lore.kernel.org/r/20140717193330.GB4703@kroah.com
0641  - Raccomandazioni da Linus Torvalds che le chiamate di sistema x32 dovrebbero
0642    favorire la compatibilità con le versioni a 64-bit piuttosto che quelle a 32-bit:
0643    https://lore.kernel.org/r/CA+55aFxfmwfB7jbbrXxa=K7VBYPfAvmu3XOkGrLbB1UFjX1+Ew@mail.gmail.com