Dipende da cosa intendi per "processo del kernel".
In Linux, ogni processo ha il proprio spazio di indirizzamento, che è incorporato nella MMU e nella sua tabella di configurazione. In parole povere, in qualsiasi momento, la MMU è configurata per trovare informazioni sulle pagine (dove ogni pagina dallo spazio degli indirizzi è nella RAM, se è presente a tutti, e i diritti di accesso) nelle tabelle situate a qualche indirizzo nella RAM fisica (i dettagli variano a seconda dell'architettura, ma in 32 bit x86 viene usato il registro CR3). Quando la CPU passa da un processo a un altro, modifica tale configurazione (ad esempio prima di concedere il controllo a qualsiasi processo, la CPU carica il registro CR3 con il valore corretto per quel processo ). mprotect()
è l'API fornita dal kernel alle applicazioni (insieme a mmap()
) per modificare queste tabelle. È importante notare che la mappatura è molte-a-uno: ogni pagina nello spazio degli indirizzi è mappata su una pagina fisica (o su "nessuna"), ma diverse pagine nello spazio indirizzo possono puntare alla stessa pagina fisica, con diritti di accesso che devono essere uguali.
Ciò significa che se un processo utilizza mprotect()
, modifica il proprio set di tabelle MMU e gli altri processi non sono interessati. Se un processo modifica i diritti di accesso a PROT_NONE
per una pagina che vede, e qualche altro processo vede anche la stessa pagina fisica nel proprio spazio indirizzo (attraverso l'impostazione della memoria condivisa), il secondo processo può comunque accedere alla pagina.
Si noti che quando un processo fa una chiamata di sistema, la CPU salta nello spazio del kernel e ottiene i privilegi a livello di kernel, ma la MMU non è influenzata (beh, in effetti può essere, a seconda dell'architettura e della versione del kernel; normalmente, ogni pagina viene mappata due volte, con una mappatura accessibile solo con i privilegi del kernel, in modo che il kernel possa scrivere nella RAM che è, dal punto di vista del processo, assente o di sola lettura, tuttavia le cose possono diventare un po ' più complesso su x86 a 32 bit perché la doppia mappatura implica una restrizione fino a 2 GB di spazio di indirizzamento per processo, ei kernel recenti hanno alcuni trucchi per passare a 4 GB per processo, basandosi fondamentalmente sui mapping MMU quando si entra nel kernel; non confondiamo ulteriormente la situazione con tali dettagli). Quindi il codice per la chiamata di sistema viene eseguito con il mapping mentre il processo chiamante lo vede (anche se con i privilegi del kernel).
I thread del kernel , a volte noti come processi del kernel, sono qualcosa di diverso. Questi sono processi senza RAM. Funzionano con i privilegi a livello di kernel e occupano uno spazio nello scheduler, ma non hanno uno spazio di indirizzi. Essendo thread, a volte vengono assegnati alla CPU (questo è il punto). Tuttavia, poiché non hanno uno spazio di indirizzamento, non incorrono in un commutatore di tabella MMU quando sono attivati, il che è una benedizione perché gli switch di tabella MMU sono costosi (a causa degli svuotamenti di TLB). Quindi i thread del kernel funzionano fondamentalmente nello spazio degli indirizzi di qualunque processo normale sia stato eseguito l'ultima volta.
Se un thread del kernel fa un mprotect()
su una pagina, partendo dal presupposto che funzioni (il kernel Linux potrebbe avere delle protezioni qui, non ho provato), quindi modificherà lo spazio degli indirizzi corrente, quello di il processo sfortunato che ha funzionato per ultimo, e quale processo è che non può essere previsto in modo affidabile. Se questo influisce su un altro processo del kernel dipende dal fatto che l'altro processo utilizzi lo stesso spazio di indirizzi o meno, qualcosa che può cambiare ad ogni cambio di contesto, centinaia di volte al secondo.
Inoltre, i thread del kernel girano con i privilegi del kernel, il che significa che possono fare più delle normali applicazioni. Tendono ad essere in grado di leggere PROT_NONE
di pagine, a condizione che lo facciano tramite l'indirizzo corretto (anche in questo caso, dipende dall'architettura e dalla versione del kernel, ma i thread del kernel saranno normalmente in grado di vedere tutte le pagine con i diritti di accesso completi per loro).
Riepilogo: se è consentito del tutto dal kernel, sembra poco saggio trafficare con la userland RAM dai thread del kernel.