How to mmap a file in linux kernel space? - linux-kernel

I try to mmap a file in a linux kernel module. I have tried to use the function do_mmap_pgoff. But the address returned is memory virtual address in current process' user space, i.e., below the kernel boundary. Instead, I want to map the file in the kernel space and get the kernel virtual address of the mapped region. Is there any kernel API in Linux support this operation? Thanks

Related

Accessing a page from device memory in userspace using linux

I have a device memory mapped to kernel virtual address via ioremap. Userspace needs to access a page at offset x from this device memory.
The way i can achieve it rightnow is via using mmap in userspace and writing a small memory mapping at driver side.
Is there any way to use offset ( lets assume kernel passes the offset to userspae )and achieve samething without making any mapping at driver side.
Can ioremapped kernel virtual addresses be used here ?

QEMU-KVM: Is Guest Physical Address(GBA) same as QEMU-KVM's Virtual Address on the host?

For example, if a process on the guest has data allocated on 0x8000(as in Guest Virtual Memory), and that has been mapped into 0x4000 in Guest Physical Memory Address Space, is the data located on 0x4000 in the virtual memory address space of host-side QEMU-KVM's (sub)process(per VM)? In other words, if I write new code within QEMU's source(so I can use the QEMU-KVM's page table), compile, and run it, then can I access to the data of guest process directly just with the guest's physical memory address matching to the guest virtual memory address?
No, the page table mapping used for the user-space QEMU process is unrelated to either the page tables used by the guest itself for guest virtual -> guest physical address mapping, or to the page tables used by the KVM kernel code for guest physical address -> host physical address mapping for RAM.
When you're writing code in QEMU that needs to access guest memory, you should do so using the APIs that QEMU provides for that, which deal with converting the guest address to a host virtual address for RAM and also with handling the case when that guest address has an emulated device rather than RAM. The QEMU developer internals docs have a section on APIs for loads and stores, and the functions are also documented in doc comments in the header files.
Usually the best advice is "find some existing code in QEMU which is doing something basically the same as what you're trying to do, and follow that as an example".
I'm assuming your question is about x86 platform.
QEMU+KVM use extended page table (EPT) to map host virtual addresses (HVA) to guest physical addresses (GPA). To find HVA corresponding to GPA, you should traverse EPT of your guest.
When you need to read a virtual address from your guest, you can use GDB functions in QEMU source. This snippet will read 4 bytes at virtualAddress in the current executing process in your guest:
uint8_t instr[4];
if( cpu_memory_rw_debug( cpu, virtualAddress, (uint8_t *)instr, sizeof( instr ), 0 ) )
{
printf( "Failed to read instr!\n" );
return;
}
cpu is an CPUState* of a cpu of your guest.
When you want to read an address of a concrete process in your guest, you should set env->cr[3] to CR3 value of this process (env is an CPUX86State*). Dont forget to restore the original value after you finish reading. And of course read memory only when your guest is not executing, otherwise there can be races.

linux kernel preallocated non mapped virtual memory

I have the following scenario:
qemu-kvm(guest) ---has virtual memory, get physical--->
virtio (send physical address to host) ---map physical to host virtual memory--->
host
The physical memory is preallocated. Is there a method to preallocate non mapped virtual memory on the host so that it won't have to search for free virtual address spaces?
Would this be a justifiable design concern if the buffers are pretty big?
The end result that I want is a pool of virtual address spaces to map received buffers.
After every job I want to unmap them and send them back the virtual address space to the pool.
To reserve a virtual memory range without actually committing any physical pages to it, pass PROT_NONE as protection parameter to mmap(). Later on, you can use mprotect() on that range to make it readable/writable when necessary - the kernel will commit the physical pages on first access. When you're done, you can use mprotect() again to reset the protection status of the address range back to PROT_NONE.

Is device address is virtual address? what is functionality of mmap in this case?

Is device address is virtual address? what is functionality of mmap in this case?or device address mapped to physical address
Usally, device address are allocated by specific system/host bus. It can identify devices on the bus.
Virtual address and physical address are used in memory system.
For mmap, the system allocate an I/O address for specific device in physical address space, application can access device in the way of memory access.
Usually devices comes with resources like registers, internal memory, etc that can be accessed from the CPU.
In order to be able to access a specific device register for example from the CPU you need to know the physical address of this device registers and then map this physical address to either kernel or user depending on your use case.
mmap maps resources to be accessed from user space. The result of mmap is a user space cpu address that is mapped to this resource.
This resource can be anything. It can be:
a file
anonymous memory
some external device resource ( memory, registers, etc )
mmap can't directly map device registers for example simply because it doesn't know how to do that. In this case you will probably need add some kernel space support for your mmap operation.

ARM platform, how to convert virtual address to physical address in kernel module?

As we know, on ARM platform, 16MB space is reserved for kernel modules below PAGE_OFFSET.
If I write a module and define a global variable, then how I get its phisical address?
It is obvious that I get a wrong physical address using virt_to_phys function.
If virt_to_phys won't work for you, you can use the MMU to do a V=>P mapping, see Find the physical address of exception vector table from kernel module

Resources