2010-11-09 4 views
5

Conformément à la conception Linux sur x86 et ppc, l'espace d'adressage virtuel 4g est divisé en 3: 1. Les adresses virtuelles des utilisateurs sont jusqu'à 3g.Pourquoi copy_to/from_user est-il requis?

Maintenant, si l'application utilisateur fait un ioctl en passant un pointeur sur le tampon, le module du noyau, peut directement faire un memcpy, j'ai essayé et cela a fonctionné. => Pourquoi avons-nous besoin d'un utilisateur copy_to/copy_from?

Remarque: Si la page est permutée, le gestionnaire de faille de page du noyau la ramènera et sera invisible pour le module du noyau.

besoin de vos idées ... commentaires

Répondre

9

Il y a plusieurs bonnes raisons qui copy_to_user/copy_from_user sont les fonctions exactes à utiliser:

  • Sur certaines architectures, un memcpy() simple ne pas travail, donc l'utilisation de ces fonctions permet à votre code pour y travailler. Je crois que même x86 avec l'option de configuration HIGHMEM sélectionnée est dans ce bateau.

  • Ces fonctions effectuent une vérification access_ok() pour s'assurer que les adresses d'espace utilisateur référencées réellement sont véritables adresses d'espace utilisateur. Si vous faites simplement un memcpy(), l'appelant du ioctl() peut fournir une plage d'adresses chevauchant les adresses de noyau, qui est un trou de sécurité.

  • Toutefois, la raison principale est de gérer correctement les mauvaises adresses d'utilisateur. Si vous utilisez simplement un memcpy() nu, la faute non gérée entraînera un oops du noyau. Les fonctions d'accès utilisateur utilisent le "fixup" mechanism, ce qui permet de gérer le défaut (la lecture ou l'écriture est courte et, en général, EFAULT est renvoyé à l'espace utilisateur dans ce cas).

+0

ok, donc la raison principale est la gestion des ** mauvaises ** adresses. – mSO

+0

et si les adresses sont valides (disons le meilleur des cas, personne ne fait de mal) le memcpy devrait fonctionner. – mSO

+0

@Manish: Il ne s'agit pas forcément d'un "méfait", il pourrait s'agir simplement d'un ancien bogue dans l'espace utilisateur - ces bogues devraient être gérés gracieusement par le noyau. Et le 'memcpy()' ne fonctionnera que sur certaines architectures. – caf

0

Vous avez eu de la chance que cela a fonctionné.

L'espace utilisateur et l'espace noyau fonctionnent dans des espaces adresse complètement différents. Quand vous copiez_utilisateur, le noyau traduit l'adresse virtuelle des espaces utilisateur en une adresse physique réelle et copie les données à cet emplacement. Un processus similaire se produit dans l'autre sens.

Il est possible de passer directement de la copie à/depuis les étapes si votre matériel prend en charge la diffusion/collecte de DMA. Ici, vous mappez un morceau contigu de mémoire virtuelle dans une série de pages physiques, puis utilisez cette information pour DMA directement dans l'espace utilisateur. Bien sûr, cela a des complications si l'un des espaces d'adressage virtuel n'est pas actuellement mappé dans la mémoire physique (pensez à un échange de fichier ou à un fichier sauvegardé).

+0

la division 3g: 1g devrait prendre soin de cela. AFAIK kernel n'a pas besoin de traduire va en pa pour copier. – mSO