'Does virt_to_pfn checks whether the page table exists or not

Does virt_to_pfn checks whether the page table is present or not. Below is the code which is failing with page fault.

#include <linux/module.h>

#define address 0xf0000000
int init_module(void)
{
    struct page *page;
    int32_t reserved;
    int32_t private;
    uint32_t test  = 0xAAAAAAAA;
    uint32_t saveValue;
    unsigned long pfn = 0;
    static uint32_t *testAddr = (uint *)address;

    pfn = virt_to_pfn(address);
    printk("Test!:%x, page frame number:%lu\n", address, pfn);
    if ( !pfn_valid(pfn) ) {
           printk("Page frame number not valid\n");
    } else {
           printk("Page Frame Number valid\n");
    }

     page = ( struct page * )virt_to_page(address);
         if ( page == NULL )
     {
         printk("NO page exist\n");
         return -1;
     }
     reserved = PageReserved( page );
     private = PagePrivate( page );
     if (reserved)
         printk("Page reserved\n");
     if (private)
         printk("Page Private\n");

     saveValue = ( uint32_t )*testAddr;
     printk("Save value:%u\n", saveValue);
    return 0;
}

void cleanup_module(void)
{
    printk("Goodbye Cruel World!\n");
}

MODULE_LICENSE("GPL");

Fails with the below error:

root@qemuarm:~# modprobe hello
[   33.283359] hello: loading out-of-tree module taints kernel.
[   33.290515] Test!:f0000000, page frame number:458752
[   33.290708] Page Frame Number valid
[   33.291169] 8<--- cut here ---
[   33.291280] Unable to handle kernel paging request at virtual address f0000000
[   33.291704] pgd = afcbaf1a
[   33.291832] [f0000000] *pgd=80000040007003, *pmd=00000000
[   33.292313] Internal error: Oops: 206 [#1] PREEMPT SMP ARM
[   33.292589] Modules linked in: hello(O+)
[   33.293078] CPU: 0 PID: 323 Comm: modprobe Tainted: G           O      5.4.172-yocto-standard #1
[   33.293368] Hardware name: Generic DT based system
[   33.293926] PC is at init_module+0x94/0xc8 [hello]
[   33.294078] LR is at init_module+0x40/0xc8 [hello]
[   33.294243] pc : [<bf000094>]    lr : [<bf000040>]    psr: 600f0013
[   33.294549] sp : ed879dd0  ip : 2e85d000  fp : bf002000
[   33.294712] r10: ed879f40  r9 : f0815df0  r8 : 00000002
[   33.294838] r7 : 00000000  r6 : c10a78c0  r5 : bf000000  r4 : 00000000
[   33.295019] r3 : f0000000  r2 : 40000000  r1 : 00000007  r0 : bf0010c3
[   33.295255] Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
[   33.295510] Control: 30c5387d  Table: 6e13d300  DAC: fffffffd
[   33.295656] Process modprobe (pid: 323, stack limit = 0x04adcafd)

RAM Size is 1024MB, the below code works with kernel virtual addresses from 0xc000 0000 - 0xefff ffff. 0xffff 0000 is where the high mem region starts.

Will the logic changes for high mem region access



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source