kfree调用崩溃(在内核模块中)

时间:2013-12-01 20:20:45

标签: c linux assembly free kernel-module

我有这段代码

int64_t ret;
char *fmt = "\n\n\n%s\n\n\n";
char *s;

s = kmalloc(13, GFP_KERNEL);
memcpy(s, "Hello world!\0", 13);

__asm__ __volatile__ (
    "movq %2, %%rdi;"
    "movq %1, %%rsi;"
    "movq $2, %%rax;"

    "call printk;"
    "movq %%rax, %0;"

    : "=r" (ret)
    : "r" (s), "r" (fmt)
    :
);

__asm__ __volatile__ (
    "movq %0, %%rdi;"
    "movq $1, %%rax;"
    "call kfree;"

    :
    : "r" (s)
    :
);

return ret;

kfree来电时崩溃。它一定是傻事,但我不知道它是什么。有什么问题?

编辑:“崩溃”==内核模块触发Oops。

编辑:如果我使用m代替r,似乎工作得很好。但为什么呢?

1 个答案:

答案 0 :(得分:3)

您应该查看生成的汇编代码(使用-S的{​​{1}}选项)以确切了解正在发生的事情。

我猜测问题是你没有为gcc块指定正确的clobbers。请记住,某些寄存器可以被被调用的函数自由使用。编译器不处理内联asm块的内容,因此它不知道里面有printk。它期望未指定为输出或clobber的寄存器将从asm块中保持不变。因此,我假设编译器将变量call缓存到s或您使用printkraxrdi所销毁的寄存器中也不要告诉编译器。请注意,存在特定的寄存器约束,因此您可以使用它们而不是在汇编中移动参数。

另请注意rsi(实际上rax)仅用于varargs和stdargs函数,即使这样,它也只包含通过sse vector(al)传递的参数数量寄存器,而不是总数。有关更多信息,请参阅x86-64 ABI文档。

最后,如果你真的想编写asm代码,你应该考虑编写独立的asm模块而不是C语言。你可以省去一些头痛。有关示例,请参阅this question