How to get the physical address of the associated data from a struct page?
c, linux, linux-kernel, memory-management
Solution
You need to map a `page` into the kernel memory as follows:
void * mapping = kmap_atomic(page, KM_USER0);
// work with mapping...
kunmap_atomic(mapping, KM_USER0);
This trick is required as there is a `HighMemory` concept in Linux (see this link for ex.).
UPD: You can use `kmap` instead of `kmap_atomic` in non-atomic contexts.
Problem
Let's say we've got a `struct page` from the address space of a page cached file. How could we get the starting physical address of the 4KB data from this `struct page`? I suppose there should be something like the `data` pointer inside `struct sk_buff`, but I didn't find it. EDIT Thanks Mat and llya for the answers. After looking at the answers, I think the first problem is to identify whether the `struct page` is located in `ZONE_NORMAL` or `ZONE_HIGHMEM`. During a file I/O, when we don't find the cached page, we will at first allocate a new page using `page_cache_alloc_cold()`. `page_cache_alloc_cold()` will finally calls `alloc_pages()` which looks like it will use the `ZONE_HIGHMEM` (which in x86, is the kernel memory area starting at `PAGE_OFFSET`+896M) for its job. So - I think Mat's answer is suitable for pages in `ZONE_NORMAL` - Suppose we use `kmap()` to find the starting physical address of the 4KB data associated with the struct page, is it correct that we should use `(unsigned long)(&page)-PAGE_OFFSET` to find the physical address where stores the structure itself? Please correct.