Commit e400ebe4 authored by Daniel Krebs's avatar Daniel Krebs

vtp: add virt_to_phys lib

parent 69437338
Pipeline #52942 failed with stages
in 59 seconds
...@@ -9,6 +9,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror") ...@@ -9,6 +9,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror")
include_directories(thirdparty/spdlog/include) include_directories(thirdparty/spdlog/include)
add_subdirectory(vtp)
add_subdirectory(lib) add_subdirectory(lib)
add_subdirectory(tests) add_subdirectory(tests)
......
...@@ -34,7 +34,7 @@ find_package(Threads) ...@@ -34,7 +34,7 @@ find_package(Threads)
add_library(villas-fpga SHARED ${SOURCES}) add_library(villas-fpga SHARED ${SOURCES})
target_link_libraries(villas-fpga PUBLIC villas-common) target_link_libraries(villas-fpga PUBLIC villas-common vtp)
# GPU library is optional, check for CUDA presence # GPU library is optional, check for CUDA presence
include(CheckLanguage) include(CheckLanguage)
......
cmake_minimum_required(VERSION 3.7)
project(vtp C)
#add_library(vtp_objects OBJECT virt_to_phys.c)
#set_source_files_properties(virt_to_phys.c PROPERTIES COMPILE_FLAGS -fPIC)
add_library(vtp SHARED virt_to_phys.c) #$<TARGET_OBJECTS:vtp_objects>)
target_include_directories(vtp PUBLIC ${CMAKE_CURRENT_LIST_DIR})
#define _XOPEN_SOURCE 700
#include <fcntl.h> /* open */
#include <stdint.h> /* uint64_t */
#include <stdio.h> /* printf */
#include <stdlib.h> /* size_t */
#include <unistd.h> /* pread, sysconf */
typedef struct {
uint64_t pfn : 54;
unsigned int soft_dirty : 1;
unsigned int file_page : 1;
unsigned int swapped : 1;
unsigned int present : 1;
} PagemapEntry;
/* Parse the pagemap entry for the given virtual address.
*
* @param[out] entry the parsed entry
* @param[in] pagemap_fd file descriptor to an open /proc/pid/pagemap file
* @param[in] vaddr virtual address to get entry for
* @return 0 for success, 1 for failure
*/
int pagemap_get_entry(PagemapEntry *entry, int pagemap_fd, uintptr_t vaddr)
{
size_t nread;
ssize_t ret;
uint64_t data;
nread = 0;
while (nread < sizeof(data)) {
ret = pread(pagemap_fd, &data, sizeof(data),
(vaddr / sysconf(_SC_PAGE_SIZE)) * sizeof(data) + nread);
nread += ret;
if (ret <= 0) {
return 1;
}
}
entry->pfn = data & (((uint64_t)1 << 54) - 1);
entry->soft_dirty = (data >> 54) & 1;
entry->file_page = (data >> 61) & 1;
entry->swapped = (data >> 62) & 1;
entry->present = (data >> 63) & 1;
return 0;
}
/* Convert the given virtual address to physical using /proc/PID/pagemap.
*
* @param[out] paddr physical address
* @param[in] pid process to convert for
* @param[in] vaddr virtual address to get entry for
* @return 0 for success, 1 for failure
*/
int virt_to_phys_user(uintptr_t *paddr, pid_t pid, uintptr_t vaddr)
{
char pagemap_file[BUFSIZ];
int pagemap_fd;
snprintf(pagemap_file, sizeof(pagemap_file), "/proc/%ju/pagemap", (uintmax_t)pid);
pagemap_fd = open(pagemap_file, O_RDONLY);
if (pagemap_fd < 0) {
return 1;
}
PagemapEntry entry;
if (pagemap_get_entry(&entry, pagemap_fd, vaddr)) {
return 1;
}
close(pagemap_fd);
*paddr = (entry.pfn * sysconf(_SC_PAGE_SIZE)) + (vaddr % sysconf(_SC_PAGE_SIZE));
return 0;
}
int virt_to_phys(uintptr_t* paddr, uintptr_t vaddr)
{
return virt_to_phys_user(paddr, getpid(), vaddr);
}
#pragma once
#include <stdint.h>
#include <fcntl.h>
extern "C" {
int virt_to_phys_user(uintptr_t *paddr, pid_t pid, uintptr_t vaddr);
// for current process
int virt_to_phys(uintptr_t* paddr, uintptr_t vaddr);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment