2529 |
2529 |
kvm_flush_coalesced_mmio_buffer();
|
2530 |
2530 |
}
|
2531 |
2531 |
|
|
2532 |
#if defined(__linux__) && !defined(TARGET_S390X)
|
|
2533 |
|
|
2534 |
#include <sys/vfs.h>
|
|
2535 |
|
|
2536 |
#define HUGETLBFS_MAGIC 0x958458f6
|
|
2537 |
|
|
2538 |
static long gethugepagesize(const char *path)
|
|
2539 |
{
|
|
2540 |
struct statfs fs;
|
|
2541 |
int ret;
|
|
2542 |
|
|
2543 |
do {
|
|
2544 |
ret = statfs(path, &fs);
|
|
2545 |
} while (ret != 0 && errno == EINTR);
|
|
2546 |
|
|
2547 |
if (ret != 0) {
|
|
2548 |
perror("statfs");
|
|
2549 |
return 0;
|
|
2550 |
}
|
|
2551 |
|
|
2552 |
if (fs.f_type != HUGETLBFS_MAGIC)
|
|
2553 |
fprintf(stderr, "Warning: path not on HugeTLBFS: %s\n", path);
|
|
2554 |
|
|
2555 |
return fs.f_bsize;
|
|
2556 |
}
|
|
2557 |
|
|
2558 |
static void *file_ram_alloc(ram_addr_t memory, const char *path)
|
|
2559 |
{
|
|
2560 |
char *filename;
|
|
2561 |
void *area;
|
|
2562 |
int fd;
|
|
2563 |
#ifdef MAP_POPULATE
|
|
2564 |
int flags;
|
|
2565 |
#endif
|
|
2566 |
unsigned long hpagesize;
|
|
2567 |
|
|
2568 |
hpagesize = gethugepagesize(path);
|
|
2569 |
if (!hpagesize) {
|
|
2570 |
return NULL;
|
|
2571 |
}
|
|
2572 |
|
|
2573 |
if (memory < hpagesize) {
|
|
2574 |
return NULL;
|
|
2575 |
}
|
|
2576 |
|
|
2577 |
if (kvm_enabled() && !kvm_has_sync_mmu()) {
|
|
2578 |
fprintf(stderr, "host lacks kvm mmu notifiers, -mem-path unsupported\n");
|
|
2579 |
return NULL;
|
|
2580 |
}
|
|
2581 |
|
|
2582 |
if (asprintf(&filename, "%s/qemu_back_mem.XXXXXX", path) == -1) {
|
|
2583 |
return NULL;
|
|
2584 |
}
|
|
2585 |
|
|
2586 |
fd = mkstemp(filename);
|
|
2587 |
if (fd < 0) {
|
|
2588 |
perror("mkstemp");
|
|
2589 |
free(filename);
|
|
2590 |
return NULL;
|
|
2591 |
}
|
|
2592 |
unlink(filename);
|
|
2593 |
free(filename);
|
|
2594 |
|
|
2595 |
memory = (memory+hpagesize-1) & ~(hpagesize-1);
|
|
2596 |
|
|
2597 |
/*
|
|
2598 |
* ftruncate is not supported by hugetlbfs in older
|
|
2599 |
* hosts, so don't bother bailing out on errors.
|
|
2600 |
* If anything goes wrong with it under other filesystems,
|
|
2601 |
* mmap will fail.
|
|
2602 |
*/
|
|
2603 |
if (ftruncate(fd, memory))
|
|
2604 |
perror("ftruncate");
|
|
2605 |
|
|
2606 |
#ifdef MAP_POPULATE
|
|
2607 |
/* NB: MAP_POPULATE won't exhaustively alloc all phys pages in the case
|
|
2608 |
* MAP_PRIVATE is requested. For mem_prealloc we mmap as MAP_SHARED
|
|
2609 |
* to sidestep this quirk.
|
|
2610 |
*/
|
|
2611 |
flags = mem_prealloc ? MAP_POPULATE | MAP_SHARED : MAP_PRIVATE;
|
|
2612 |
area = mmap(0, memory, PROT_READ | PROT_WRITE, flags, fd, 0);
|
|
2613 |
#else
|
|
2614 |
area = mmap(0, memory, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
|
|
2615 |
#endif
|
|
2616 |
if (area == MAP_FAILED) {
|
|
2617 |
perror("file_ram_alloc: can't mmap RAM pages");
|
|
2618 |
close(fd);
|
|
2619 |
return (NULL);
|
|
2620 |
}
|
|
2621 |
return area;
|
|
2622 |
}
|
|
2623 |
#endif
|
|
2624 |
|
2532 |
2625 |
ram_addr_t qemu_ram_alloc(ram_addr_t size)
|
2533 |
2626 |
{
|
2534 |
2627 |
RAMBlock *new_block;
|
... | ... | |
2536 |
2629 |
size = TARGET_PAGE_ALIGN(size);
|
2537 |
2630 |
new_block = qemu_malloc(sizeof(*new_block));
|
2538 |
2631 |
|
|
2632 |
if (mem_path) {
|
|
2633 |
#if defined (__linux__) && !defined(TARGET_S390X)
|
|
2634 |
new_block->host = file_ram_alloc(size, mem_path);
|
|
2635 |
if (!new_block->host)
|
|
2636 |
exit(1);
|
|
2637 |
#else
|
|
2638 |
fprintf(stderr, "-mem-path option unsupported\n");
|
|
2639 |
exit(1);
|
|
2640 |
#endif
|
|
2641 |
} else {
|
2539 |
2642 |
#if defined(TARGET_S390X) && defined(CONFIG_KVM)
|
2540 |
|
/* XXX S390 KVM requires the topmost vma of the RAM to be < 256GB */
|
2541 |
|
new_block->host = mmap((void*)0x1000000, size, PROT_EXEC|PROT_READ|PROT_WRITE,
|
2542 |
|
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
|
|
2643 |
/* XXX S390 KVM requires the topmost vma of the RAM to be < 256GB */
|
|
2644 |
new_block->host = mmap((void*)0x1000000, size,
|
|
2645 |
PROT_EXEC|PROT_READ|PROT_WRITE,
|
|
2646 |
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
|
2543 |
2647 |
#else
|
2544 |
|
new_block->host = qemu_vmalloc(size);
|
|
2648 |
new_block->host = qemu_vmalloc(size);
|
2545 |
2649 |
#endif
|
2546 |
2650 |
#ifdef MADV_MERGEABLE
|
2547 |
|
madvise(new_block->host, size, MADV_MERGEABLE);
|
|
2651 |
madvise(new_block->host, size, MADV_MERGEABLE);
|
2548 |
2652 |
#endif
|
|
2653 |
}
|
2549 |
2654 |
new_block->offset = last_ram_offset;
|
2550 |
2655 |
new_block->length = size;
|
2551 |
2656 |
|