gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-02 19:03:38 25 4
gpt4 key购买 nike

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

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com