31

Briefly, I have a physical address inside kernel (9,932,111,872 or 0x250000000), which is apparently aligned to 4KiB (page size). When I use the kernel __va() function to get the kernel virtual address, I got something like 0xf570660f (different on each boot), which is not aligned to 4KiB.

I'm on a 64bit system so there's no HIGHMEM, and I thought that due to the liner memory model, a virtual address of an 4KiB-aligned physical address should also be 4KiB-aligned. Did I miss something? Shouldn't the virtual address be phys_addr + PAGE_OFFSET? Or is it the influence of the sparsemem? But maybe it should also be 4KiB-aligned?

Here are more details:

My workground is on a x86 64bit QEMU VM. I'm trying to use a PMEM in DEV-DAX mode as a normal memory. I can get the physical start address of it (0x250000000), which has been confirmed to be right. Then I need to transfer it to the virtual address in kernel space so that I can use it as I need. Here's some code:

static long nvpc_map_whole_dev(struct dax_device *dax_dev, void **kaddr, pfn_t *pfn)
{
    // get the device
    struct dev_dax_nvpc *dax_nvpc = (struct dev_dax_nvpc *)dax_get_private(dax_dev);
    
    // get the virtual address and the pfn_t
    *kaddr = __va(dax_nvpc->phys_start);
    *pfn = phys_to_pfn_t(dax_nvpc->phys_start, PFN_MAP);
    
    pr_info("[NVPC DEBUG]: paddr %#llx kaddr %p pfn %lu\n", dax_nvpc->phys_start, *kaddr, pfn_t_to_pfn(*pfn));
    pr_info("[NVPC DEBUG]: kaddr-paddr %#llx\n", __pa(*kaddr));
    return PHYS_PFN(dax_nvpc->size);
}

And here's the result I got:

enter image description here

Shown in the marked line, the paddr dax_nvpc->phys_start, and the pfn, are both right. But the kaddr (virtual address) is confusing to me. Then when I transfer the kaddr back to physical address (the next output line), the result turns to be right.

What's more, I can do any operation on the memory from kaddr to kaddr + dax_nvpc->size, there's no page fault.

Could anyone tell me why is the virtual address is not 4KiB-aligned? Am I being a fool on somewhere? Further, can I do something to make sure that the virtual address is also aligned to a page?

0

1 Answer 1

46

The reason is the %p in printk. When I change %p to %#llx for a quick check, the output of kernel address becomes 4KB-aligned as expected.

The reason can be found here: Kernel Doc: printk-formats pointer-types. %p inside printk will print a hashed pointer address to prevent leaking kernel information. That's why the pointer seems weird. If you want to check the real virtual address just use %px, or add no_hash_pointers to the boot parameter. Refer to the link for more usage.

0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .