在 CR4 中设置 TSD 位会导致崩溃
Setting TSD Bit in CR4 causes crash
我想限制 rdtsc
指令的使用,使其只能在环 0 中执行。根据 Intel 手册,这可以通过设置 CR4.TSD 来实现以下内核模块:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
MODULE_LICENSE("GPL");
#define TSD_BIT 2
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 void settsd(void* info) {
uint64_t cr4 = getcr4();
cr4 |= (1 << TSD_BIT);
setcr4(cr4);
}
static void cleartsd(void* info) {
uint64_t cr4 = getcr4();
cr4 &= ~(1 << TSD_BIT);
setcr4(cr4);
}
static int __init init_routine(void) {
on_each_cpu(settsd, NULL, 0);
printk(KERN_INFO "CR4.TSD set: %u!\n", (int)(getcr4() >> TSD_BIT) & 1);
return 0;
}
static void __exit exit_routine(void) {
on_each_cpu(cleartsd, NULL, 0);
printk(KERN_INFO "CR4.TSD cleared: %u!\n", (int)(getcr4() >> TSD_BIT) & 1);
}
module_init(init_routine);
module_exit(exit_routine);
但是,加载此模块会立即导致 OS 崩溃。有什么办法可以避免吗?
OS信息:
$ uname -r | cat /etc/debian_version -
7.8
3.2.0-4-amd64
首先,您的方法是与机器上的其他线程竞争运行。我建议查看 arch/x86/kernel/process.c
中的代码如何以正确的方式或多或少地做到这一点。
检查宏SET_TSC_CTL()
,系统调用prctl
。
我想限制 rdtsc
指令的使用,使其只能在环 0 中执行。根据 Intel 手册,这可以通过设置 CR4.TSD 来实现以下内核模块:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
MODULE_LICENSE("GPL");
#define TSD_BIT 2
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 void settsd(void* info) {
uint64_t cr4 = getcr4();
cr4 |= (1 << TSD_BIT);
setcr4(cr4);
}
static void cleartsd(void* info) {
uint64_t cr4 = getcr4();
cr4 &= ~(1 << TSD_BIT);
setcr4(cr4);
}
static int __init init_routine(void) {
on_each_cpu(settsd, NULL, 0);
printk(KERN_INFO "CR4.TSD set: %u!\n", (int)(getcr4() >> TSD_BIT) & 1);
return 0;
}
static void __exit exit_routine(void) {
on_each_cpu(cleartsd, NULL, 0);
printk(KERN_INFO "CR4.TSD cleared: %u!\n", (int)(getcr4() >> TSD_BIT) & 1);
}
module_init(init_routine);
module_exit(exit_routine);
但是,加载此模块会立即导致 OS 崩溃。有什么办法可以避免吗?
OS信息:
$ uname -r | cat /etc/debian_version -
7.8
3.2.0-4-amd64
首先,您的方法是与机器上的其他线程竞争运行。我建议查看 arch/x86/kernel/process.c
中的代码如何以正确的方式或多或少地做到这一点。
检查宏SET_TSC_CTL()
,系统调用prctl
。