I am implementing a memory allocator that is aware about the usage of the memory. The idea is to pass an annotation to the allocator and based on this annotation it can disable the cache for the new memory. Something like this (I am using our OS):
Code: Select all
int *data = new (ALLOC_WR) unsigned int[20];
Code: Select all
//receives the new address (addr), already allocated
static void change_page_flags(Log_Addr addr, int size, IA32_Flags flags) {
//gets the current page directory by reading the CR3 register
Page_Directory * pd = current();
//gets the current page table, accessing the Page directory
//directory() makes a shift >> of 22 bits in the received address
Page_Table * pt = (*pd)[directory(addr)];
//access the specific address page and set the PCD flag (disable cache)
//PCD = 0x010
(*pt)[page(addr)] = (*pt)[page(addr)] | (IA32_Flags::PCD);
//flushes TLB to make the change
flush_tlb();
}
The flush_tlb() code is:
Code: Select all
static void flush_tlb() {
ASMV("movl %cr3,%eax");
ASMV("movl %eax,%cr3");
}
I also tried to use another way to flush the TLB using invlpg instruction with no success:
Code: Select all
static void flush_tlb(Log_Addr addr) {
ASMV("invlpg %0" : : "m"(addr));
}
Thanks in advance,
Giovani