Linux内核:scatterlist允许的最大“长度”是多少?

解决了我的Linux加密示例,我可以正确地调用aead密码,我遇到了一个有趣的问题。

我将散点图定义为:

struct scatterlist sg[2]; sg_init_table(sg, 2 ); sg_set_buf(&sg[0], address, 512); sg_set_buf(&sg[1], mac, 16); aead_request_set_crypt(req, sg, sg, 512, iv); crypto_aead_encrypt(req); 

这很有效。 但是,如果你将缓冲区大小从512增加到131072,那么它将“经常”出现恐慌。

  BUG: unable to handle kernel paging request at ffffeb04000cea80 IP: [] scatterwalk_done+0x50/0x60 

现在,由于所有密码最终都调用了scatterwalk_函数,我认为将sg-> length设置为大的是一个问题。 据推测,它有时会越过下一页。

在这做什么是正确的? 我是否必须将其拆分为多个分散列表,确保每个分散列表都不会转到下一页? 这听起来像一个麻烦,还是有一个function为我做这个? 或者我只是需要确保每个页面都“可用”?

好吧,实际上有两件事困扰着我。 第一个是偶尔向我发送的内存实际上是来自vmalloc()分配的内存。 这意味着我应该使用sg_set_page(,vmalloc_to_page())。

第二个问题是scatterwalk函数是不正确的,如果你设置任何也生成mac的密码作为第二个缓冲区,它很容易测试;

 cipherout = kmalloc( size, ... macout = kmalloc( maclen, ... 

这通常会起作用,因为新分配的内存位于页面边界上。 但是,将其改为;

  macout = kmalloc( maclen + 16, ... macout += 16; 

我所做的只是分配一个更大的缓冲区,然后启动16字节的内存。(+ 1024,或+3480,无关紧要)这将使散射道恐慌。 linux-crypto邮件列表上有一个建议的补丁,这对未来很有帮助,但现在对我没有帮助。 我需要确保mac地址是对齐的,如果没有,则分配临时缓冲区(至少很小)。

@rerito:你可以使用virt_addr_valid 。 看到这个提交 。