cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

adding-syscalls.rst (31154B)


      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 :manpage:`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 :manpage:`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:manpage:`xyzzyat(2)`::
    150
    151    int sys_xyzzyat(int dfd, const char __user *path, ..., unsigned int flags);
    152
    153Questo permette più flessibilità su come lo spazio utente specificherà il 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
    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
    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 :manpage:`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 :manpage:`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 :manpage:`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:manpage:`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
    281Implementazione delle chiamate di sistema x86
    282---------------------------------------------
    283
    284Per collegare la vostra nuova chiamate di sistema alle piattaforme x86,
    285dovete aggiornate la tabella principale di syscall.  Assumendo che la vostra
    286nuova chiamata di sistema non sia particolarmente speciale (vedere sotto),
    287dovete aggiungere un elemento *common* (per x86_64 e x32) in
    288arch/x86/entry/syscalls/syscall_64.tbl::
    289
    290    333   common   xyzzy     sys_xyzzy
    291
    292e un elemento per *i386* ``arch/x86/entry/syscalls/syscall_32.tbl``::
    293
    294    380   i386     xyzzy     sys_xyzzy
    295
    296Ancora una volta, questi numeri potrebbero essere cambiati se generano
    297conflitti durante la finestra di integrazione.
    298
    299
    300Chiamate di sistema compatibili (generico)
    301------------------------------------------
    302
    303Per molte chiamate di sistema, la stessa implementazione a 64-bit può essere
    304invocata anche quando il programma in spazio utente è a 32-bit; anche se la
    305chiamata di sistema include esplicitamente un puntatore, questo viene gestito
    306in modo trasparente.
    307
    308Tuttavia, ci sono un paio di situazione dove diventa necessario avere un
    309livello di gestione della compatibilità per risolvere le differenze di
    310dimensioni fra 32-bit e 64-bit.
    311
    312Il primo caso è quando un kernel a 64-bit supporta anche programmi in spazio
    313utente a 32-bit, perciò dovrà ispezionare aree della memoria (``__user``) che
    314potrebbero 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
    325Il secondo caso che richiede un livello di gestione della compatibilità è
    326quando uno degli argomenti di una chiamata a sistema è esplicitamente un tipo
    327a 64-bit anche su architetture a 32-bit, per esempio ``loff_t`` o ``__u64``.
    328In questo caso, un valore che arriva ad un kernel a 64-bit da un'applicazione
    329a 32-bit verrà diviso in due valori a 32-bit che dovranno essere riassemblati
    330in questo livello di compatibilità.
    331
    332(Da notare che non serve questo livello di compatibilità per argomenti che
    333sono puntatori ad un tipo esplicitamente a 64-bit; per esempio, in
    334:manpage:`splice(2)` l'argomento di tipo ``loff_t __user *`` non necessita
    335di una chiamata di sistema ``compat_``)
    336
    337La versione compatibile della nostra chiamata di sistema si chiamerà
    338``compat_sys_xyzzy()``, e viene aggiunta utilizzando la macro
    339``COMPAT_SYSCALL_DEFINEn()`` (simile a SYSCALL_DEFINEn).  Questa versione
    340dell'implementazione è parte del kernel a 64-bit ma accetta parametri a 32-bit
    341che trasformerà secondo le necessità (tipicamente, la versione
    342``compat_sys_`` converte questi valori nello loro corrispondente a 64-bit e
    343può chiamare la versione ``sys_`` oppure invocare una funzione che implementa
    344le parti comuni).
    345
    346Il punto d'accesso *compat* deve avere il corrispondente prototipo di funzione
    347in ``include/linux/compat.h``, marcato come asmlinkage di modo da abbinargli
    348il modo in cui quelle chiamate di sistema verranno invocate::
    349
    350    asmlinkage long compat_sys_xyzzy(...);
    351
    352Se la chiamata di sistema prevede una struttura dati organizzata in modo
    353diverso 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
    357dimensione variabile deve avere il proprio tipo ``compat_`` corrispondente
    358a quello in ``struct xyzzy_args``.  La funzione ``compat_sys_xyzzy()``
    359può usare la struttura ``compat_`` per analizzare gli argomenti ricevuti
    360da una chiamata a 32-bit.
    361
    362Per esempio, se avete i seguenti campi::
    363
    364    struct xyzzy_args {
    365        const char __user *ptr;
    366        __kernel_long_t varying_val;
    367        u64 fixed_val;
    368        /* ... */
    369    };
    370
    371nella struttura ``struct xyzzy_args``, allora la 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
    381La lista generica delle chiamate di sistema ha bisogno di essere
    382aggiustata al fine di permettere l'uso della versione *compatibile*;
    383la 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
    389Riassumendo, 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
    399Compatibilità delle chiamate di sistema (x86)
    400---------------------------------------------
    401
    402Per collegare una chiamata di sistema, su un'architettura x86, con la sua
    403versione *compatibile*, è necessario aggiustare la voce nella tabella
    404delle syscall.
    405
    406Per prima cosa, la voce in ``arch/x86/entry/syscalls/syscall_32.tbl`` prende
    407un argomento aggiuntivo per indicare che un programma in spazio utente
    408a 32-bit, eseguito su un kernel a 64-bit, dovrebbe accedere tramite il punto
    409d'accesso compatibile::
    410
    411    380   i386     xyzzy     sys_xyzzy    __ia32_compat_sys_xyzzy
    412
    413Secondo, dovete capire cosa dovrebbe succedere alla nuova chiamata di sistema
    414per la versione dell'ABI x32.  Qui C'è una scelta da fare: gli argomenti
    415possono corrisponde alla versione a 64-bit o a quella a 32-bit.
    416
    417Se c'è un puntatore ad un puntatore, la decisione è semplice: x32 è ILP32,
    418quindi gli argomenti dovrebbero corrispondere a quelli a 32-bit, e la voce in
    419``arch/x86/entry/syscalls/syscall_64.tbl`` sarà divisa cosicché i programmi
    420x32 eseguano la chiamata *compatibile*::
    421
    422    333   64       xyzzy     sys_xyzzy
    423    ...
    424    555   x32      xyzzy     __x32_compat_sys_xyzzy
    425
    426Se non ci sono puntatori, allora è preferibile riutilizzare la chiamata di
    427sistema a 64-bit per l'ABI x32 (e di conseguenza la voce in
    428arch/x86/entry/syscalls/syscall_64.tbl rimane immutata).
    429
    430In ambo i casi, dovreste verificare che i tipi usati dagli argomenti
    431abbiano un'esatta corrispondenza da x32 (-mx32) al loro equivalente a
    43232-bit (-m32) o 64-bit (-m64).
    433
    434
    435Chiamate di sistema che ritornano altrove
    436-----------------------------------------
    437
    438Nella maggior parte delle chiamate di sistema, al termine della loro
    439esecuzione, i programmi in spazio utente riprendono esattamente dal punto
    440in cui si erano interrotti -- quindi dall'istruzione successiva, con lo
    441stesso *stack* e con la maggior parte del registri com'erano stati
    442lasciati prima della chiamata di sistema, e anche con la stessa memoria
    443virtuale.
    444
    445Tuttavia, alcune chiamata di sistema fanno le cose in modo differente.
    446Potrebbero ritornare ad un punto diverso (``rt_sigreturn``) o cambiare
    447la memoria in spazio utente (``fork``/``vfork``/``clone``) o perfino
    448l'architettura del programma (``execve``/``execveat``).
    449
    450Per permettere tutto ciò, l'implementazione nel kernel di questo tipo di
    451chiamate di sistema potrebbero dover salvare e ripristinare registri
    452aggiuntivi nello *stack* del kernel, permettendo così un controllo completo
    453su dove e come l'esecuzione dovrà continuare dopo l'esecuzione della
    454chiamata di sistema.
    455
    456Queste saranno specifiche per ogni architettura, ma tipicamente si definiscono
    457dei punti d'accesso in *assembly* per salvare/ripristinare i registri
    458aggiuntivi e quindi chiamare il vero punto d'accesso per la chiamata di
    459sistema.
    460
    461Per 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
    463di syscall (``arch/x86/entry/syscalls/syscall_64.tbl``) verrà corretta di
    464conseguenza::
    465
    466    333   common   xyzzy     stub_xyzzy
    467
    468L'equivalente per programmi a 32-bit eseguiti su un kernel a 64-bit viene
    469normalmente chiamato ``stub32_xyzzy`` e implementato in
    470``arch/x86/entry/entry_64_compat.S`` con la corrispondente voce nella tabella
    471di syscall ``arch/x86/entry/syscalls/syscall_32.tbl`` corretta nel
    472seguente modo::
    473
    474    380   i386     xyzzy     sys_xyzzy    stub32_xyzzy
    475
    476Se una chiamata di sistema necessita di un livello di compatibilità (come
    477nella sezione precedente), allora la versione ``stub32_`` deve invocare
    478la versione ``compat_sys_`` piuttosto che quella nativa a 64-bit.  In aggiunta,
    479se l'implementazione dell'ABI x32 è diversa da quella x86_64, allora la sua
    480voce nella tabella di syscall dovrà chiamare uno *stub* che invoca la versione
    481``compat_sys_``,
    482
    483Per completezza, sarebbe carino impostare una mappatura cosicché
    484*user-mode* Linux (UML) continui a funzionare -- la sua tabella di syscall
    485farà riferimento a stub_xyzzy, ma UML non include l'implementazione
    486in ``arch/x86/entry/entry_64.S`` (perché UML simula i registri eccetera).
    487Correggerlo è semplice, basta aggiungere una #define in
    488``arch/x86/um/sys_call_table_64.c``::
    489
    490    #define stub_xyzzy sys_xyzzy
    491
    492
    493Altri dettagli
    494--------------
    495
    496La maggior parte dei kernel tratta le chiamate di sistema allo stesso modo,
    497ma possono esserci rare eccezioni per le quali potrebbe essere necessario
    498l'aggiornamento della vostra chiamata di sistema.
    499
    500Il sotto-sistema di controllo (*audit subsystem*) è uno di questi casi
    501speciali; esso include (per architettura) funzioni che classificano alcuni
    502tipi di chiamate di sistema -- in particolare apertura dei file
    503(``open``/``openat``), esecuzione dei programmi (``execve``/``exeveat``)
    504oppure multiplatori di socket (``socketcall``). Se la vostra nuova chiamata
    505di sistema è simile ad una di queste, allora il sistema di controllo dovrebbe
    506essere aggiornato.
    507
    508Più in generale, se esiste una chiamata di sistema che è simile alla vostra,
    509vale la pena fare una ricerca con ``grep`` su tutto il kernel per la chiamata
    510di sistema esistente per verificare che non ci siano altri casi speciali.
    511
    512
    513Verifica
    514--------
    515
    516Una nuova chiamata di sistema dev'essere, ovviamente, provata; è utile fornire
    517ai revisori un programma in spazio utente che mostri l'uso della chiamata di
    518sistema.  Un buon modo per combinare queste cose è quello di aggiungere un
    519semplice programma di auto-verifica in una nuova cartella in
    520``tools/testing/selftests/``.
    521
    522Per una nuova chiamata di sistema, ovviamente, non ci sarà alcuna funzione
    523in libc e quindi il programma di verifica dovrà invocarla usando ``syscall()``;
    524inoltre, se la nuova chiamata di sistema prevede un nuova struttura dati
    525visibile in spazio utente, il file d'intestazione necessario dev'essere
    526installato al fine di compilare il programma.
    527
    528Assicuratevi che il programma di auto-verifica possa essere eseguito
    529correttamente su tutte le architetture supportate.  Per esempio, verificate che
    530funzioni quando viene compilato per x86_64 (-m64), x86_32 (-m32) e x32 (-mx32).
    531
    532Al fine di una più meticolosa ed estesa verifica della nuova funzionalità,
    533dovreste considerare l'aggiunta di nuove verifica al progetto 'Linux Test',
    534oppure al progetto xfstests per cambiamenti relativi al filesystem.
    535
    536 - https://linux-test-project.github.io/
    537 - git://git.kernel.org/pub/scm/fs/xfs/xfstests-dev.git
    538
    539
    540Pagine man
    541----------
    542
    543Tutte le nuove chiamate di sistema dovrebbero avere una pagina man completa,
    544idealmente usando i marcatori groff, ma anche il puro testo può andare.  Se
    545state usando groff, è utile che includiate nella email di presentazione una
    546versione già convertita in formato ASCII: semplificherà la vita dei revisori.
    547
    548Le pagine man dovrebbero essere in copia-conoscenza verso
    549linux-man@vger.kernel.org
    550Per maggiori dettagli, leggere
    551https://www.kernel.org/doc/man-pages/patches.html
    552
    553
    554Non invocate chiamate di sistema dal kernel
    555-------------------------------------------
    556
    557Le chiamate di sistema sono, come già detto prima, punti di interazione fra
    558lo spazio utente e il kernel.  Perciò, le chiamate di sistema come
    559``sys_xyzzy()`` o ``compat_sys_xyzzy()`` dovrebbero essere chiamate solo dallo
    560spazio utente attraverso la tabella syscall, ma non da nessun altro punto nel
    561kernel.  Se la nuova funzionalità è utile all'interno del kernel, per esempio
    562dev'essere condivisa fra una vecchia e una nuova chiamata di sistema o
    563dev'essere utilizzata da una chiamata di sistema e la sua variante compatibile,
    564allora dev'essere implementata come una funzione di supporto
    565(*helper function*) (per esempio ``ksys_xyzzy()``).  Questa funzione potrà
    566essere chiamata dallo *stub* (``sys_xyzzy()``), dalla variante compatibile
    567(``compat_sys_xyzzy()``), e/o da altri parti del kernel.
    568
    569Sui sistemi x86 a 64-bit, a partire dalla versione v4.17 è un requisito
    570fondamentale quello di non invocare chiamate di sistema all'interno del kernel.
    571Esso 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
    573la chiamata di sistema la quale verrà eseguita successivamente.
    574Questo significa che verranno passati solo i parametri che sono davvero
    575necessari ad una specifica chiamata di sistema, invece che riempire ogni volta
    5766 registri del processore con contenuti presi dallo spazio utente (potrebbe
    577causare seri problemi nella sequenza di chiamate).
    578
    579Inoltre, le regole su come i dati possano essere usati potrebbero differire
    580fra il kernel e l'utente.  Questo è un altro motivo per cui invocare
    581``sys_xyzzy()`` è generalmente una brutta idea.
    582
    583Eccezioni a questa regola vengono accettate solo per funzioni d'architetture
    584che surclassano quelle generiche, per funzioni d'architettura di compatibilità,
    585o per altro codice in arch/
    586
    587
    588Riferimenti 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