为简单的 linux 驱动程序获取 "returned with preemption imbalance" 错误
Getting "returned with preemption imbalance" error for a simple linux driver
我编写了一个简单的驱动程序,用于检查是否启用了 VMX,其代码如下。
#include <linux/module.h>
#include <linux/init.h>
inline bool vmxSupport(void)
{
int getVmxSupport, vmxBit;
__asm__ ("mov , %rax");
__asm__ ("cpuid");
__asm__ ("mov %%ecx , %0\n\t":"=r" (getVmxSupport));
//pr_info("\n");
vmxBit = (getVmxSupport >> 5) & 1;
if (vmxBit == 1){
return true;
}
else {
return false;
}
}
static int __init my_init(void)
{
vmxSupport();
pr_info("Hello world from mod1\n");
return 0;
}
static void __exit my_exit(void)
{
pr_info("Goodbye world from mod1\n");
}
module_init(my_init);
module_exit(my_exit);
MODULE_AUTHOR("vpn");
MODULE_DESCRIPTION("module1.c");
MODULE_LICENSE("GPL v2");
我收到的错误的简短片段:
Hello world from mod1
[ 908.381100] ------------[ cut here ]------------
[ 908.389199] initcall my_init+0x0/0x1000 [module1] returned with preemption imbalance
[ 908.396171] WARNING: CPU: 1 PID: 5049 at init/main.c:1300 do_one_initcall+0x2b8/0x320
[ 908.401424] Modules linked in: module1(OE+) intel_rapl_msr(E) intel_rapl_common(E)
.
.
.
R10: 0000000000000003 R11: 0000000000000246 R12: 0000559e223dc260
[ 908.560509] R13: 0000000000000000 R14: 0000559e235ec750 R15: 0000000000000000
[ 908.562768] ---[ end trace 0d070b847da4cd90 ]---
[ 908.565107] BUG: scheduling while atomic: insmod/5049/0x01000800
但是当我在第 3 个 __asm__
之后添加 pr_info
(从共享代码中删除评论)时,我没有得到这个问题。
我尝试过的事情:
- 禁用函数优化
vmxSupport
- 内联/取消内联
vmxSupport
函数
- 检查了反汇编,我没有看到任何异常。
知道我为什么会收到此错误吗?
“Cpuid”改变 RBX、RCX 和 RDX 寄存器。我建议你在指令之前保存它们(push),并在指令之后恢复它们(pop),因为编译器假设它们中的一些被保留了下来。您的问题可能是由于更改寄存器的副作用造成的。
我编写了一个简单的驱动程序,用于检查是否启用了 VMX,其代码如下。
#include <linux/module.h>
#include <linux/init.h>
inline bool vmxSupport(void)
{
int getVmxSupport, vmxBit;
__asm__ ("mov , %rax");
__asm__ ("cpuid");
__asm__ ("mov %%ecx , %0\n\t":"=r" (getVmxSupport));
//pr_info("\n");
vmxBit = (getVmxSupport >> 5) & 1;
if (vmxBit == 1){
return true;
}
else {
return false;
}
}
static int __init my_init(void)
{
vmxSupport();
pr_info("Hello world from mod1\n");
return 0;
}
static void __exit my_exit(void)
{
pr_info("Goodbye world from mod1\n");
}
module_init(my_init);
module_exit(my_exit);
MODULE_AUTHOR("vpn");
MODULE_DESCRIPTION("module1.c");
MODULE_LICENSE("GPL v2");
我收到的错误的简短片段:
Hello world from mod1
[ 908.381100] ------------[ cut here ]------------
[ 908.389199] initcall my_init+0x0/0x1000 [module1] returned with preemption imbalance
[ 908.396171] WARNING: CPU: 1 PID: 5049 at init/main.c:1300 do_one_initcall+0x2b8/0x320
[ 908.401424] Modules linked in: module1(OE+) intel_rapl_msr(E) intel_rapl_common(E)
.
.
.
R10: 0000000000000003 R11: 0000000000000246 R12: 0000559e223dc260
[ 908.560509] R13: 0000000000000000 R14: 0000559e235ec750 R15: 0000000000000000
[ 908.562768] ---[ end trace 0d070b847da4cd90 ]---
[ 908.565107] BUG: scheduling while atomic: insmod/5049/0x01000800
但是当我在第 3 个 __asm__
之后添加 pr_info
(从共享代码中删除评论)时,我没有得到这个问题。
我尝试过的事情:
- 禁用函数优化
vmxSupport
- 内联/取消内联
vmxSupport
函数 - 检查了反汇编,我没有看到任何异常。
知道我为什么会收到此错误吗?
“Cpuid”改变 RBX、RCX 和 RDX 寄存器。我建议你在指令之前保存它们(push),并在指令之后恢复它们(pop),因为编译器假设它们中的一些被保留了下来。您的问题可能是由于更改寄存器的副作用造成的。