Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 5 additions & 40 deletions lib/system/linux/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ static int metal_pagesize_compare(const void *_a, const void *_b)
return metal_sign(diff);
}

static int metal_add_page_size(const char *path, int shift, int mmap_flags)
static int metal_add_page_size(int shift, int mmap_flags)
{
int index = _metal.num_page_sizes;
unsigned long size = 1UL << shift;
Expand All @@ -39,7 +39,7 @@ static int metal_add_page_size(const char *path, int shift, int mmap_flags)
return -EOVERFLOW;
}

if (!path || shift <= 0) {
if (shift <= 0) {
metal_log(METAL_LOG_WARNING, "skipped page size %ld - invalid args\n",
size);
return -EINVAL;
Expand All @@ -48,10 +48,9 @@ static int metal_add_page_size(const char *path, int shift, int mmap_flags)
_metal.page_sizes[index].page_shift = shift;
_metal.page_sizes[index].page_size = size;
_metal.page_sizes[index].mmap_flags = mmap_flags;
strncpy(_metal.page_sizes[index].path, path, PATH_MAX);
_metal.num_page_sizes++;

metal_log(METAL_LOG_DEBUG, "added page size %ld @%s\n", size, path);
metal_log(METAL_LOG_DEBUG, "added page size %ld\n", size);

return 0;
}
Expand All @@ -69,15 +68,14 @@ static int metal_init_page_sizes(void)
}
_metal.page_size = sizes[0];
_metal.page_shift = metal_log2(sizes[0]);
metal_add_page_size(_metal.tmp_path, _metal.page_shift, 0);
metal_add_page_size(_metal.page_shift, 0);

#ifdef HAVE_HUGETLBFS_H
#ifndef MAP_HUGE_SHIFT
/* System does not support multiple huge page sizes. */
sizes[0] = gethugepagesize();
if (sizes[0] > 0) {
metal_add_page_size(hugetlbfs_find_path(),
metal_log2(sizes[0]),
metal_add_page_size(metal_log2(sizes[0]),
MAP_HUGETLB);
}
#else
Expand All @@ -92,7 +90,6 @@ static int metal_init_page_sizes(void)
if ((shift & MAP_HUGE_MASK) != shift)
continue;
metal_add_page_size(
hugetlbfs_find_path_for_size(sizes[i]),
shift, (MAP_HUGETLB |
(shift << MAP_HUGE_SHIFT)));
}
Expand All @@ -109,30 +106,8 @@ static int metal_init_page_sizes(void)

int metal_sys_init(const struct metal_init_params *params)
{
const char *tmp_path;
unsigned int seed;
FILE *urandom;
int result;

/* Find the temporary directory location. */
tmp_path = getenv("TMPDIR");
if (!tmp_path)
tmp_path = "/tmp";
_metal.tmp_path = tmp_path;

/* Initialize the pseudo-random number generator. */
urandom = fopen("/dev/urandom", "r");
if (!urandom) {
metal_log(METAL_LOG_ERROR, "failed to open /dev/urandom (%s)\n",
strerror(errno));
return -errno;
}
if (fread(&seed, 1, sizeof(seed), urandom) <= 0) {
metal_log(METAL_LOG_DEBUG, "Failed fread /dev/urandom\n");
}
fclose(urandom);
srand(seed);

result = metal_init_page_sizes();
if (result < 0)
return result;
Expand All @@ -141,13 +116,6 @@ int metal_sys_init(const struct metal_init_params *params)
if (result < 0)
return result;

result = open("/proc/self/pagemap", O_RDONLY | O_CLOEXEC);
if (result < 0) {
metal_log(METAL_LOG_DEBUG, "Failed pagemap open - %s\n",
strerror(errno));
}
_metal.pagemap_fd = result;

metal_unused(params);

/* Initialize IRQ handling */
Expand All @@ -157,10 +125,7 @@ int metal_sys_init(const struct metal_init_params *params)

void metal_sys_finish(void)
{

/* Shutdown IRQ handling */
metal_linux_irq_shutdown();
metal_linux_bus_finish();
close(_metal.pagemap_fd);

}
17 changes: 11 additions & 6 deletions lib/system/linux/shmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,17 @@ static const struct metal_io_ops metal_shmem_io_ops = {
NULL, NULL, NULL, NULL, NULL, metal_shmem_io_close, NULL, NULL
};

static int metal_virt2phys(void *addr, unsigned long *phys)
static int metal_virt2phys(void *addr, unsigned long *phys, int pagemap_fd)
{
off_t offset;
uint64_t entry;
int error;

if (_metal.pagemap_fd < 0)
if (pagemap_fd < 0)
return -EINVAL;

offset = ((uintptr_t)addr >> _metal.page_shift) * sizeof(entry);
error = pread(_metal.pagemap_fd, &entry, sizeof(entry), offset);
error = pread(pagemap_fd, &entry, sizeof(entry), offset);
if (error < 0) {
metal_log(METAL_LOG_ERROR, "failed pagemap pread (offset %llx) - %s\n",
(unsigned long long)offset, strerror(errno));
Expand All @@ -62,6 +62,7 @@ static int metal_shmem_try_map(struct metal_page_size *ps, int fd, size_t size,
size_t pages, page, phys_size;
struct metal_io_region *io;
metal_phys_addr_t *phys;
int pagemap_fd;
uint8_t *virt;
void *mem;
int error;
Expand Down Expand Up @@ -97,21 +98,25 @@ static int metal_shmem_try_map(struct metal_page_size *ps, int fd, size_t size,
return -ENOMEM;
}

if (_metal.pagemap_fd < 0) {
pagemap_fd = open("/proc/self/pagemap", O_RDONLY | O_CLOEXEC);
if (pagemap_fd < 0) {
phys[0] = 0;
metal_log(METAL_LOG_WARNING,
"shmem - failed to get va2pa mapping. use offset as pa.\n");
"shmem - failed to get pagemap for va2pa mapping (%s). Using offset as pa.\n",
strerror(errno));
metal_io_init(io, mem, phys, size, -1, 0, &metal_shmem_io_ops);
} else {
for (virt = mem, page = 0; page < pages; page++) {
size_t offset = page * ps->page_size;

error = metal_virt2phys(virt + offset, &phys[page]);
error = metal_virt2phys(virt + offset, &phys[page],
pagemap_fd);
if (error < 0)
phys[page] = METAL_BAD_OFFSET;
}
metal_io_init(io, mem, phys, size, ps->page_shift, 0,
&metal_shmem_io_ops);
close(pagemap_fd);
}
*result = io;

Expand Down
9 changes: 0 additions & 9 deletions lib/system/linux/sys.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,6 @@ struct metal_page_size {
/** Page shift. */
unsigned long page_shift;

/** Path to hugetlbfs (or tmpfs) mount point. */
char path[PATH_MAX];

/** Flags to use for mmap. */
int mmap_flags;
};
Expand All @@ -81,17 +78,11 @@ struct metal_state {
/** system page shift. */
unsigned long page_shift;

/** sysfs mount point. */
const char *tmp_path;

/** available page sizes. */
struct metal_page_size page_sizes[MAX_PAGE_SIZES];

/** number of available page sizes. */
int num_page_sizes;

/** File descriptor for /proc/self/pagemap (or -1). */
int pagemap_fd;
};

#ifdef METAL_INTERNAL
Expand Down
Loading