本文介绍了如何在x86-64架构使用INVLPG?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图来衡量内存访问时序,需要减少TLB产生的噪音命中和未命中

I'm trying to measure memory access timings and need to reduce the noise produced by TLB hits and misses

为了清除特定页面出了TLB的我试图用INVLPG指令,下面的两个例子:并

In order to clear a specific page out of the TLB I tried to use the INVLPG instruction, following those two examples: http://wiki.osdev.org/Paging and http://wiki.osdev.org/Inline_Assembly/Examples

我写了下面code:

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

但产生的二元抛出上执行一个SIGSEGV。
正如我prefere Intel语法,我看了一眼在特定的拆卸:

But the resulting binary throws an SIGSEGV on execution.As I prefere Intel syntax, I had a look at the particular disassembly:

invlpg BYTE PTR [rdi]

如果我理解正确此,INVLPG将与RDI字节值调用,但宁愿需要一个QWORD地址。

If I understand this correctly, invlpg will be called with the byte value at RDI, but would rather require a QWORD address.

然而第二连杆说m个指针指向的逻辑地址,而不是一个物理或虚拟之一:一个用于将DS段偏移

However the second link says "The m pointer points to a logical address, not a physical or virtual one: an offset for your ds segment"

所以INVLPG需要一个从DS段偏移?但DS段不使用AMD64了,是吗?

So INVLPG needs an offset from the ds segment? But the ds segment isn't used in AMD64 anymore, is it?

有人能解释我如何使用INVLPG指令与AMD64或如何驱逐在此架构的TLB项?

Can someone explain me how to use the INVLPG instruction with AMD64 or how to evict an TLB entry on this architecture?

推荐答案

该SIGSEGV是因为INVLPG是特权指令,只能叫出来的内核code(感谢的)。

The SIGSEGV happens because INVLPG is a privileged instruction and can only be called out of kernel code (Thanks Cody Gray).

为了证明使用INVLPG我写了一个小LKM的 invlpg_mod.c 的:

In order to demonstrate the use of INVLPG I wrote a little 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-头和建立与这个Makefile的LKM:

Make sure you have the linux-headers installed and build the LKM with this Makefile:

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

这篇关于如何在x86-64架构使用INVLPG?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-18 23:58