Linux内核模块:设置CR4.VMXE不会持续

我正在使用XUbuntu 16.04上的VMX,但是我遇到了一些设置CR4的VMXE位的问题。 问题是,当我的退出函数被调用时,该位不再设置。

vmmod.c

#include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/types.h> #define AUTHOR "me" #define DESC "Test" extern u64 read_cr4(void); extern void write_cr4(u64 val); static bool IsVMXEEnabled(void) { return (read_cr4() >> 13) & 1; } static void SetVMXEEnabled(void* _val) { bool val = *(bool*)_val; u64 mask = (1 << 13); u64 cr4 = read_cr4(); if (val) cr4 |= mask; else cr4 &= (~mask); write_cr4(cr4); } static void LogVMXEState(void* info) { (void) info; printk(KERN_INFO "CR4: %08LX\n", read_cr4()); } static int __init init_(void) { printk(KERN_INFO "===================================\n"); if (IsVMXEEnabled()) printk(KERN_INFO "VMXE Is Enabled\n"); else { bool new_vmxe_state = true; printk(KERN_INFO "Enabling VMXE\n"); on_each_cpu(SetVMXEEnabled, &new_vmxe_state, 1); if (IsVMXEEnabled()) { printk(KERN_INFO "VMXE Has Been Enabled\n"); on_each_cpu(LogVMXEState, NULL, 1); } else { printk(KERN_INFO "VMXE Could Not Be Enabled\n"); return -1; } } return 0; } static void __exit exit_(void) { printk(KERN_INFO "----------------------------------------\n"); on_each_cpu(LogVMXEState, NULL, 1); if (IsVMXEEnabled()) { bool new_val = false; printk(KERN_INFO "Disabling VMXE\n"); on_each_cpu(SetVMXEEnabled, &new_val, 1); if (!IsVMXEEnabled()) printk(KERN_INFO "VMXE Has Been Disabled\n"); else printk(KERN_INFO "Couldn't disabled VMXE...\n"); } else printk(KERN_INFO "VMXE Wasn't enabled?\n"); printk(KERN_INFO "===================================\n"); } MODULE_LICENSE("GPL"); MODULE_AUTHOR(AUTHOR); MODULE_DESCRIPTION(DESC); module_init(init_); module_exit(exit_); 

vmasm.S

 .intel_syntax noprefix .text .global read_cr4 read_cr4: mov rax, cr4 ret .global write_cr4 write_cr4: mov cr4, rdi ret 

Makefile文件

 obj-m += testmod.o testmod-objs := vmmod.o vmasm.o all: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules clean: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean 

testing

 $> sudo insmod testmod.ko && sudo rmmod testmod 

产量

 [ 607.459248] =================================== [ 607.459256] Enabling VMXE [ 607.459302] VMXE Has Been Enabled [ 607.459311] CR4: 000426E0 [ 607.459315] CR4: 000426E0 [ 607.459318] CR4: 000426E0 [ 607.459321] CR4: 000426F0 [ 607.459334] CR4: 000426E0 [ 607.459336] CR4: 000426E0 [ 607.459338] CR4: 000426E0 [ 607.459373] CR4: 000426E0 [ 607.473007] ---------------------------------------- [ 607.473025] CR4: 000406E0 [ 607.473065] CR4: 000406E0 [ 607.473068] CR4: 000406F0 [ 607.473072] CR4: 000406E0 [ 607.473074] CR4: 000406E0 [ 607.473078] CR4: 000406E0 [ 607.473080] CR4: 000406E0 [ 607.473103] CR4: 000406E0 [ 607.473121] VMXE Wasn't enabled? [ 607.473129] =================================== 

输出清楚地表明,在模块加载function之后,CR4的第13位(VMXE)被使能,但在模块卸载function期间,它不再被设置。

有一个内核模块可以定期重置VMXE吗? 运行此代码时,卸载了kvm.ko和kvm_intel.ko,并且已启用Intel仿真BIOS设置,并且CPU支持VMX。

根据( 在内核模块中修改控制寄存器 ),我尝试添加on_each_cpu来在每个CPU内核上设置VMXE,但是没有帮助。

有任何想法吗?

谢谢!