Hello Nikos,

On Wed, Oct 13, 2010 at 05:52:57PM +0200, Nikos Mavrogiannopoulos wrote:
> On 10/13/2010 05:17 PM, Phil Sutter wrote:
> > Still ugly as hell (and therefore TODO):
> > - having to pass task_struct and mm_struct from the calling process
> >   around
> > - need to copy the IV right at write() time (copy_from_user seems to
> >   work in process context only)
> 
>  If you could elaborate on those TODO maybe I can help. The second
> sounds quite serious, but maybe I don't understand the details.

Starting with the first one, this is actually a requirement when using
get_user_pages() which is needed for zero-copy operation - when calling
get_user_pages(), mm->mmap_sem needs to be held. Also, the mm_struct and
task_struct objects of the process whose pages should be addressed have
to be passed to get_user_pages() as parameters.

My current solution for that, extending all relevant functions'
parameters is ugly and proven functional by trial and error. But the
sole alternative I see so far is to move the complete code-path around
get_userbuf() into the process context, i.e. before returning from the
CIOCASYNCCRYPT ioctl. Sounds doable, but this provides another trap
door: one cannot use a single array of page structs anymore, there needs
to be an array per pending job. So the whole dynamic page array
increasing won't work anymore, besides that there is a much bigger
kmalloc-related overhead for each job submitted.

Now the second one, something that could actually be solved without
going nuts: I had to find out that copy_from_user() uses the get_fs()
macro internally, which forcibly needs to be run from inside process
context. So one simply can't call copy_from_user() from
cryptask_routine(), no matter what information about the ioctl-calling
process has formerly been made available. This is actually why my code
copies any given IV to a temporary buffer for circumventing the call to
copy_from_user() in crypto_run().

The upside of that problem in contrast to the first one is that there
already exists a "temporary" IV buffer, namely in struct cipher_data. So
maybe this can be munged together somehow.

Besides, I'm not quite sure how that really works: the IV is saved
per-session, but I can pass a different one with each crypt_op? So maybe
cipher_data.async.iv is not needed at all.

Greetings, Phil
-- 
Viprinet GmbH
Mainzer Str. 43
55411 Bingen am Rhein
Germany

Zentrale:     +49-6721-49030-0
Durchwahl:    +49-6721-49030-134
Fax:          +49-6721-49030-209

phil.sut...@viprinet.com
http://www.viprinet.com

Sitz der Gesellschaft: Bingen am Rhein
Handelsregister: Amtsgericht Mainz HRB40380
Geschäftsführer: Simon Kissel


_______________________________________________
Cryptodev-linux-devel mailing list
Cryptodev-linux-devel@gna.org
https://mail.gna.org/listinfo/cryptodev-linux-devel

Reply via email to