下面的簡單內核模塊在加載cr4寄存器(CR4.VMXE
)的第13位時設置它,並在退出時清除該位。在內核模塊中修改控制寄存器
vmx.c
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
MODULE_LICENSE("GPL");
static inline uint64_t getcr4(void) {
register uint64_t ret = 0;
asm volatile (
"movq %%cr4, %0\n"
:"=r"(ret)
);
return ret;
}
static inline void setcr4(register uint64_t val) {
asm volatile (
"movq %0, %%cr4\n"
:
:"r"(val)
);
}
static int __init init_routine(void) {
uint64_t cr4 = getcr4();
printk(KERN_INFO "VTX Test loaded: %llu (%u).\n", cr4, (unsigned char)((cr4 >> 13) & 1));
cr4 |= (1 << 13);
setcr4(cr4);
cr4 = getcr4();
printk(KERN_INFO "cr4: %llu (%u).\n", cr4, (unsigned char)((cr4 >> 13) & 1));
return 0;
}
static void __exit exit_routine(void) {
uint64_t cr4 = getcr4();
printk(KERN_INFO "cr4: %llu (%u).\n", cr4, (unsigned char)((cr4 >> 13) & 1));
cr4 &= ~(1 << 13);
setcr4(cr4);
cr4 = getcr4();
printk(KERN_INFO "VTX Test exited: %llu (%u).\n", cr4, (unsigned char)((cr4 >> 13) & 1));
}
module_init(init_routine);
module_exit(exit_routine);
的Makefile
obj-m += vmx.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
要運行我用make clean && make && sudo insmod vmx.ko && sudo rmmod vmx && sudo dmesg -c
模塊。這有時讓我以下(預期)輸出
[ 2295.121537] VTX Test loaded: 1312736 (0).
[ 2295.121540] cr4: 1320928 (1).
[ 2295.123975] cr4: 1320928 (1).
[ 2295.123977] VTX Test exited: 1312736 (0).
有時也以下:
[ 2296.256982] VTX Test loaded: 1320928 (1).
[ 2296.256984] cr4: 1320928 (1).
[ 2296.259481] cr4: 1312736 (0).
[ 2296.259483] VTX Test exited: 1312736 (0).
在謝勝利,輸出的二,三線看起來很奇怪我,因爲它看起來像修改控制寄存器cr4在離開init_routine
後已被重置。另外奇怪的是,在第一行中,VMXE位似乎被設置,這並沒有任何意義。這種行爲是否正常?如何解釋?有沒有其他的內核模塊可以修改CR4?這似乎相當奇怪,因爲我已經看到了幾個VTX實現,它們都在它們的初始化例程中設置了VMXE位,並以與本模塊相同的方式清除它們的退出例程中的位。
因此,如果這是一個kvm問題,那麼最好向社區報告。 [訂閱](http://vger.kernel.org/vger-lists.html#kvm) – 0andriy
@AndyShevchenko問題與kvm無關。 – user1658887