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

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.

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.

Can I specify what dma physical address to use in Linux kernel instead of requesting one using DMA APIs?

Instead of using dma_map_single() or kmalloc() and dma_map_sg() to allocate a CPU accessible buffer then obtain IOMMU mapped dma address, can I specify a specific dma_addr_t type dma address and pass it to kernel to use?
The reason I have to do this is my customized hardware provides a way to calculate IOMMU mapped dma address that is available for device driver to use, but I am not sure if I can correlate this to CPU virtual memory. dma_map_sg() and dma_map_single() work in my case but I have no control over the dma address it returns (I would like to check a specific bit in dma address, and only use the address when the bit is set).
I have checked several APIs looks like dma_map_sg() might be able to do so... any idea is well appreciated.

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.

Convert DMA mapping to virtual address

I have a somewhat unusual situation where I'm developing a simulation module for an Ethernet device. Ideally, the simulation layer would just be identical to the real hardware with regard to the register set. The issue I've run into is that the DMA registers in the hardware are loaded with the DMA mapping (physical) address of the data. I need to use those physical addresses to copy the data from the Tx buffer on the source device to the Rx buffer on the destination device. To do that in module code, I need pointers to virtual memory. I looked at phys_to_virt() and I didn't understand this comment in the man page:
This function does not handle bus mappings for DMA transfers.
Does this mean that a physical address that is retrieved via dma_map_single cannot be converted back to a virtual address using phys_to_virt()? Is there another way to accomplish this conversion?
There is not any general way to map a DMA address to a virtual address. The dma_map_single() function might be programming an IOMMU (eg VT-d on an Intel x86 system), which results in a DMA address that is completely unrelated to the original physical or virtual address. However this presentation and the linked slides gives one approach to hooking an emulated hardware model up to a real driver (basically, use virtualization).
I am not too clear about this question but if you are using "phys_to_virt()" may be the reason that address available on the bus can not be coverted to virtual by this function. I am not sure just try bus_to_virt(bus_addr); function
Try dma_virt = virt_to_phys(bus_to_virt(dma_handle))
it worked for me. It gives the same virtual address that was mapped by dma_coherent_alloc().

Resources