首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在内核模块中分配物理上连续的页面

在内核模块中分配物理上连续的页面
EN

Stack Overflow用户
提问于 2021-06-28 13:13:41
回答 1查看 69关注 0票数 0

我正在尝试使用alloc_pages_exact函数在内存中分配物理上连续的页面。当我尝试分配10MB的页面时,返回的地址始终为0。但是当我尝试分配1MB的页面时,分配几乎是立即进行的。另外,谁能告诉我如何找到DRAM的确切行大小?我不得不搜索我的RAM的数据表才能弄清楚。我想知道是否有一个命令来确定DRAM的行大小。早些时候,我认为系统页大小也应该是DRAM行大小,但是系统页大小原来是4kB,而我计算的行大小是8kB。请帮帮忙。代码:

代码语言:javascript
复制
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");
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-06-28 17:50:22

alloc_pages和家族支持的最大页面大小是MAX_ORDER的2次方。除非被CONFIG_FORCE_MAX_ZONEORDER内核配置覆盖,否则MAX_ORDER通常为11 (这只是为某些体系结构设置的,并且可以手动配置)。

MAX_ORDER值为11允许分配2048个页面,对于最常见的页面大小4096,它允许的最大分配大小为8388608 (8 MiB)。

我不知道如何确定DRAM行大小,但它可能与系统页大小无关,因为系统页大小是由体系结构的MMU决定的(大多数体系结构的MMU是4096 )。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68157887

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档