如何在x86-64架构上使用INVLPG?

3
我正在尝试测量内存访问时间,并需要减少由TLB命中和未命中产生的噪声。
为了清除TLB中的特定页面,我尝试使用INVLPG指令,按照以下两个示例:http://wiki.osdev.org/Paginghttp://wiki.osdev.org/Inline_Assembly/Examples 我编写了以下代码:
static inline void __native_flush_tlb_single(unsigned long addr)
{
   asm volatile("invlpg (%0)" ::"r" (addr) : "memory");
}

但是生成的二进制文件在执行时会抛出SIGSEGV错误。 由于我更喜欢使用Intel语法,所以我查看了特定的反汇编代码:

invlpg BYTE PTR [rdi]

如果我理解正确,invlpg将使用RDI的字节值调用,但实际上需要一个QWORD地址。
然而第二个链接说:"m指针指向逻辑地址,而不是物理或虚拟地址:ds段的偏移量"
那么INVLPG需要来自ds段的偏移量吗?但在AMD64中不再使用ds段,是吗?
有人能解释一下如何在AMD64上使用INVLPG指令或如何驱逐TLB条目吗?

在AMD64上,虚拟地址和数据段基址的偏移量之间的区别是无关紧要的,因为数据段基址无论如何都是零。但我无法确定为什么这个信息会导致错误。你在那里放了什么地址? - harold
3
你知道这是一条特权指令,对吗?它只能在内核代码中执行。 - Cody Gray
哦,好观点,我之前不知道那个..有了这个信息,我也找到了这篇帖子:https://stackoverflow.com/questions/13253498/segfault-when-invlpg-instruction-is-called 所以我打算写一个内核模块来完成这个任务... - mightymo
我真的不明白为什么这是必要的。除非我严重误解了什么,否则没有必要使引用用户模式地址的TLB条目无效。内核不访问用户模式地址空间,这可能是您传递给此函数的内容。如果您只想计时内存访问或代码等内容,通常的做法是在循环中执行代码或查询内存足够多次,以淹没噪音。 - Cody Gray
1个回答

7

SIGSEGV错误发生是因为INVLPG是特权指令,只能在内核代码之外调用(感谢Cody Gray)。

为了演示INVLPG的使用,我编写了一个小型LKMinvlpg_mod.c

#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/moduleparam.h>
#include <linux/unistd.h>
#include <linux/types.h>

// LICENSE
MODULE_LICENSE("GPL");

static inline void invlpg(unsigned long addr) {
    asm volatile("invlpg (%0)" ::"r" (addr) : "memory");
}


// init module
static int __init module_load(void) {
    int mem;
    invlpg((unsigned long) &mem);
    printk("Evicted %p from TLB", &mem);
}


//unload modules
static void __exit module_unload(void) {
    printk("Goodbye.");
}

module_init(module_load);
module_exit(module_unload);

请确保您已安装了Linux头文件,并使用此Makefile构建LKM:

KDIR = /lib/modules/$(shell uname -r)/build
PWD = $(shell pwd)

obj-m = invlpg_mod.o

all:
    make -C $(KDIR) M=$(PWD) modules

clean:
    make -C $(KDIR) M=$(PWD) clean

使用以下命令加载LKM:

 sudo insmod invlpg_mod.ko

并卸载它:

sudo rmmod invlpg_mod.ko

请看输出:
dmesg | tail

您可能更喜欢使用导出的内核包装器来包装此指令。我相信其中一些是导出的,可用于与kmodules一起使用。 - Roi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接