在内核模块中分配物理上连续的页面
Allocating physically contiguous pages in Kernel Module
我正在尝试使用 alloc_pages_exact 函数在 DRAM 中分配物理上连续的页面。当我尝试分配 10MB 的页面时,返回的地址始终为 0。但是当我尝试分配 1MB 的页面时,分配几乎是即时的。另外,有人可以告诉我如何找到 DRAM 的确切行大小吗?我必须搜索我的 RAM 的数据表才能弄明白。我想知道是否有一个命令可以确定 DRAM 的行大小。早些时候我认为系统页面大小也应该是 DRAM 行大小,但系统页面大小结果是 4kB,我计算出的行大小是 8kB。请帮忙。
代码:
static int __init hello_entry(void){
unsigned long i = 0;
unsigned long j = 0;
unsigned long counter;
int fault = 0;
char default_value = 0xff;
unsigned long size_of_memory_to_test_bytes = 10 * 1024 * 1024;//10MB chunk
unsigned long page_size = 8 * 1024;//8kB page size. From data sheet for elpida 4GB ddr3 ram
unsigned long number_of_pages = size_of_memory_to_test_bytes / page_size;
unsigned long number_of_hammer_access = 200000;
printk("Number Of Bytes to allocate: %ld\n", number_of_pages * page_size);
char* pages = (char *)alloc_pages_exact(number_of_pages * page_size, GFP_KERNEL);
while(pages == 0);//The Program must wait till enough pages have been allocated!
printk("Starting Address: %x", pages);
char *hammerRow0, *hammerRow1, *victimRow;
char hammerRow0_data, victimRow_data, hammerRow1_data, read_midvalue;
printk(KERN_ALERT "Memory Test Entry!\n");
printk(KERN_ALERT "Page Size: %ld\n", page_size);
printk(KERN_ALERT "Cache Line Size: %d\n", cache_line_size());
//The design consists of two hammer rows which will be repeatedly accessed one after another
//There will be a victim row in between the two hammer rows, kind of like a victim row sandwiched between two hammer rows
//This will server two purposes:
//1. Greater probability of inducing bitflip in the victim row due to repeated access of two adjacent rows.
//2. Clearing out the row buffer of DRAM chip so that it is guaranteed that the wordline will be accessed to access the data
printk(KERN_INFO "Rowhammer Test Starts\n");
for(counter = 0; counter < number_of_pages - 2; counter++){
//Doing the rowhammer test on every page of dram
hammerRow0 = pages + counter;
victimRow = hammerRow0 + page_size;
hammerRow1 = victimRow + page_size;
//Storing initial data into rows to check them later for errors
for(i = 0; i < page_size / sizeof(char); i++){
//Setting all bits of dram 1 to maximize the possibility of charge leak
hammerRow0[i] = default_value;
victimRow[i] = default_value;
hammerRow1[i] = default_value;
}
//Starting Hammer Test
//printk(KERN_INFO "Rowhammer Test Starts\n");
fault = 0;
for(j = 0; j < number_of_hammer_access; j++){
//hammerRow0 access
//This is an x86 specific funnction that executes CLFLUSH. Mre info on CLFLUSh: https://c9x.me/x86/html/file_module_x86_id_30.html
clflush_cache_range(hammerRow0, sizeof(char));
read_midvalue = hammerRow0[0]; //Reading the first value present in the page
//hammerRow1 access
clflush_cache_range(hammerRow1, sizeof(int));
read_midvalue = hammerRow1[0]; //Reading the first value present in the page
}
//Checking the victim row for errors
for(i = 0; i < page_size / sizeof(int); i++){
victimRow_data = victimRow[i];
if(victimRow_data != default_value){
printk(KERN_ALERT "victimRow Fault (After Hammering) at index %d: Present Value: %x \t Expected Value: %x:\tRow numer %d\n", i, victimRow_data, 0xff, counter);
fault = 1;
}
}
if(fault == 1){
printk(KERN_ALERT "Rowhammer Test Failed\n");
return 0;
}
else {
//printk(KERN_ALERT "Rowhammer Test Passed for Row %d\n", counter);
}
}
printk(KERN_ALERT "Rowhammer Test Passed\n");
return 0;
}
static void __exit hello_exit(void){
printk(KERN_INFO "Memory Test Exit!\n");
}
module_init(hello_entry);
module_exit(hello_exit);
//Licensing Info
MODULE_LICENSE("GPL");
MODULE_AUTHOR("jonvonton");
MODULE_DESCRIPTION("Rowhammer Testing");
alloc_pages
和系列支持的最大页面大小是 2 的 MAX_ORDER
次方。 MAX_ORDER
通常为 11,除非被 CONFIG_FORCE_MAX_ZONEORDER
内核配置覆盖(仅针对某些体系结构设置,并且可以手动配置)。
MAX_ORDER
值 11 允许分配 2048 个页面,对于最常见的页面大小 4096,允许的最大分配大小为 8388608 (8 MiB)。
我不知道如何确定 DRAM 行大小,但它可能与系统页面大小无关,因为后者由体系结构的 MMU 决定(大多数体系结构为 4096)。
我正在尝试使用 alloc_pages_exact 函数在 DRAM 中分配物理上连续的页面。当我尝试分配 10MB 的页面时,返回的地址始终为 0。但是当我尝试分配 1MB 的页面时,分配几乎是即时的。另外,有人可以告诉我如何找到 DRAM 的确切行大小吗?我必须搜索我的 RAM 的数据表才能弄明白。我想知道是否有一个命令可以确定 DRAM 的行大小。早些时候我认为系统页面大小也应该是 DRAM 行大小,但系统页面大小结果是 4kB,我计算出的行大小是 8kB。请帮忙。 代码:
static int __init hello_entry(void){
unsigned long i = 0;
unsigned long j = 0;
unsigned long counter;
int fault = 0;
char default_value = 0xff;
unsigned long size_of_memory_to_test_bytes = 10 * 1024 * 1024;//10MB chunk
unsigned long page_size = 8 * 1024;//8kB page size. From data sheet for elpida 4GB ddr3 ram
unsigned long number_of_pages = size_of_memory_to_test_bytes / page_size;
unsigned long number_of_hammer_access = 200000;
printk("Number Of Bytes to allocate: %ld\n", number_of_pages * page_size);
char* pages = (char *)alloc_pages_exact(number_of_pages * page_size, GFP_KERNEL);
while(pages == 0);//The Program must wait till enough pages have been allocated!
printk("Starting Address: %x", pages);
char *hammerRow0, *hammerRow1, *victimRow;
char hammerRow0_data, victimRow_data, hammerRow1_data, read_midvalue;
printk(KERN_ALERT "Memory Test Entry!\n");
printk(KERN_ALERT "Page Size: %ld\n", page_size);
printk(KERN_ALERT "Cache Line Size: %d\n", cache_line_size());
//The design consists of two hammer rows which will be repeatedly accessed one after another
//There will be a victim row in between the two hammer rows, kind of like a victim row sandwiched between two hammer rows
//This will server two purposes:
//1. Greater probability of inducing bitflip in the victim row due to repeated access of two adjacent rows.
//2. Clearing out the row buffer of DRAM chip so that it is guaranteed that the wordline will be accessed to access the data
printk(KERN_INFO "Rowhammer Test Starts\n");
for(counter = 0; counter < number_of_pages - 2; counter++){
//Doing the rowhammer test on every page of dram
hammerRow0 = pages + counter;
victimRow = hammerRow0 + page_size;
hammerRow1 = victimRow + page_size;
//Storing initial data into rows to check them later for errors
for(i = 0; i < page_size / sizeof(char); i++){
//Setting all bits of dram 1 to maximize the possibility of charge leak
hammerRow0[i] = default_value;
victimRow[i] = default_value;
hammerRow1[i] = default_value;
}
//Starting Hammer Test
//printk(KERN_INFO "Rowhammer Test Starts\n");
fault = 0;
for(j = 0; j < number_of_hammer_access; j++){
//hammerRow0 access
//This is an x86 specific funnction that executes CLFLUSH. Mre info on CLFLUSh: https://c9x.me/x86/html/file_module_x86_id_30.html
clflush_cache_range(hammerRow0, sizeof(char));
read_midvalue = hammerRow0[0]; //Reading the first value present in the page
//hammerRow1 access
clflush_cache_range(hammerRow1, sizeof(int));
read_midvalue = hammerRow1[0]; //Reading the first value present in the page
}
//Checking the victim row for errors
for(i = 0; i < page_size / sizeof(int); i++){
victimRow_data = victimRow[i];
if(victimRow_data != default_value){
printk(KERN_ALERT "victimRow Fault (After Hammering) at index %d: Present Value: %x \t Expected Value: %x:\tRow numer %d\n", i, victimRow_data, 0xff, counter);
fault = 1;
}
}
if(fault == 1){
printk(KERN_ALERT "Rowhammer Test Failed\n");
return 0;
}
else {
//printk(KERN_ALERT "Rowhammer Test Passed for Row %d\n", counter);
}
}
printk(KERN_ALERT "Rowhammer Test Passed\n");
return 0;
}
static void __exit hello_exit(void){
printk(KERN_INFO "Memory Test Exit!\n");
}
module_init(hello_entry);
module_exit(hello_exit);
//Licensing Info
MODULE_LICENSE("GPL");
MODULE_AUTHOR("jonvonton");
MODULE_DESCRIPTION("Rowhammer Testing");
alloc_pages
和系列支持的最大页面大小是 2 的 MAX_ORDER
次方。 MAX_ORDER
通常为 11,除非被 CONFIG_FORCE_MAX_ZONEORDER
内核配置覆盖(仅针对某些体系结构设置,并且可以手动配置)。
MAX_ORDER
值 11 允许分配 2048 个页面,对于最常见的页面大小 4096,允许的最大分配大小为 8388608 (8 MiB)。
我不知道如何确定 DRAM 行大小,但它可能与系统页面大小无关,因为后者由体系结构的 MMU 决定(大多数体系结构为 4096)。