c - 在 CR4 中设置 TSD 位会导致崩溃

标签 c linux-kernel kernel-module

我想限制 rdtsc 指令的使用,使其只能在环 0 中执行。根据英特尔手册,这可以通过设置 CR4.TSD 来实现,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);

但是,加载此模块会立即导致操作系统崩溃。有什么办法可以避免这种情况吗?

操作系统信息:

$ uname -r | cat /etc/debian_version -
7.8
3.2.0-4-amd64

最佳答案

首先,你的方式是与机器上运行的其他线程竞争。我建议查看 arch/x86/kernel/process.c 中的代码,如何以正确的方式或多或少地做到这一点。

检查宏SET_TSC_CTL(),以及系统调用prctl

关于c - 在 CR4 中设置 TSD 位会导致崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28815929/

相关文章:

linux - 使用 Linux 字符设备驱动程序的 'write' 函数中的参数之一

c - Linux内核模块构建中的特定宏值

c - 全局指针(链表头)未正确更新

c - gcc 编译器是否始终将整数放在内存中的字符数组之前?

linux - 新的 linux tc 队列规则来创建突发......知识用完了

c - 在内核空间中,如何获取ext4格式磁盘上的文件对应的物理地址

linux - 在 Linux 中启用和分配 IRQ

linux - 将内核模块添加到 Debian

c++ - 将电影转换为 OpenNI *.oni 视频

C数组压入,为什么减去 '0'?