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