Revision c902760f exec.c
b/exec.c | ||
---|---|---|
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 |
|
Also available in: Unified diff