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

标签 c assembly x86 x86-64 tlb

我正在尝试测量内存访问时序,并且需要减少 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]

如果我理解正确的话,将使用 RDI 处的字节值调用 invlpg,但更需要 QWORD 地址。

但是第二个链接显示“m 指针指向逻辑地址,而不是物理或虚拟地址:ds 段的偏移量”

那么 INVLPG 需要距 ds 段的偏移量吗?但是 AMD64 中不再使用 ds 段,是吗?

有人可以解释一下如何在 AMD64 上使用 INVLPG 指令或如何在此架构上驱逐 TLB 条目吗?

最佳答案

发生 SIGSEGV 是因为 INVLPG 是一条特权指令,只能从内核代码中调用(感谢 Cody Gray )。

为了演示 INVLPG 的使用,我编写了一些 LKM invlpg_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-headers 并使用此 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

关于c - 如何在x86-64架构上使用INVLPG?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37752664/

相关文章:

C语言中TCP服务器与客户端的通信

c - 未定义的函数文件引用错误 C(编译)

从 C 文件更改头文件中结构变量中的 char 数组会弄乱数组

multithreading - 是否因为 “lock”而没有使用 “cache coherency mechanism”操作码前缀?

c - 如何在 c(time.h 函数)和 DOS 中设置(或更正)时区和 DST

c - 为什么这个 C 程序不能编译?错误 : undefined reference to `i2c_smbus_read_byte_data'

c - STM8微 Controller STVD IDE中的汇编指令

c - 我如何指示可以使用内联ASM参数*指向*的内存?

c - 为什么 gcc 在优化版本中使用 jmp 调用函数

assembly - 该汇编语言代码是什么意思?