47187

How to use INVLPG on x86-64 architecture?

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

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

I wrote the following code:

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

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]

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

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"

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

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

Answer1:

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

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);

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

Load the LKM with:

sudo insmod invlpg_mod.ko

And unload it:

sudo rmmod invlpg_mod.ko

See the output:

dmesg | tail

Recommend

  • Spring MVC : What is the best way to pass the controller + action name to the view?
  • Segfault when invlpg instruction is called
  • What C/C++ compiler can use push pop instructions for creating local variables, instead of just incr
  • What x86 instructions take two (or more) memory operands?
  • How to view the Assembly code for C# in Visual Studio (not the MSIL)?
  • How can I declare a variable at an absolute address with GCC?
  • Excel VBA - Extract the correct dates from badly formatted dates?
  • How to use INVLPG on x86-64 architecture?
  • Unit test C with compiler specific keywords
  • The internet calendar file “abc.ics” does not contain any appointments
  • OpenGL Compute shader sync different work groups
  • synchronization on single statement?
  • What Causes Instruction Replay Overhead in CUDA
  • C/C++ returning struct by value under the hood
  • Calling C function from x64 assembly with registers instead of stack
  • when the c++ program stack size used is determined?
  • Javascript's SetTimeout, SetInterval and ClearInterval equivalent in c#
  • How to refresh ALL cell through VBA
  • Is assigning a frequently used field to a local variable more efficient?
  • Can I make a variable temporarily volatile?
  • python - connecting to a database with pyodbc - not working
  • Sorting an array of pointers
  • Execute a piece of code from the data-section
  • Monotouch floating point pointer throws NullReferenceException when not 4-byte aligned
  • how to force the use of cmov in gcc and VS
  • Initializing a class using malloc
  • HALF_PTR Windows data type
  • ZipList with Scalaz
  • Alamofire and Reachability.swift not working on xCode8-beta5
  • python mysqldb delete row
  • MeeGo Handset Emulator not starting on Windows 7
  • Redshift Querying: error xx000 disk full redshift
  • Question about instantiating object
  • Bash if statement with multiple conditions
  • How to remove a SwiftyJSON element?
  • Convert Type Decimal to Hex (string) in .NET 3.5
  • Swift: Switch statement fallthrough behavior
  • copying resource to sdcard gives a damaged file in android
  • Email verification using google app script and google forms
  • How do you troubleshoot character encoding problems?