Revision c902760f

b/cpu-all.h
847 847
extern ram_addr_t ram_size;
848 848
extern ram_addr_t last_ram_offset;
849 849

  
850
extern const char *mem_path;
851
extern int mem_prealloc;
852

  
850 853
/* physical memory access */
851 854

  
852 855
/* MMIO pages are identified by a combination of an IO device index and
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

  
b/qemu-options.hx
314 314
gigabytes respectively.
315 315
ETEXI
316 316

  
317
DEF("mem-path", HAS_ARG, QEMU_OPTION_mempath,
318
    "-mem-path FILE  provide backing storage for guest RAM\n")
319
STEXI
320
@item -mem-path @var{path}
321
Allocate guest RAM from a temporarily created file in @var{path}.
322
ETEXI
323

  
324
#ifdef MAP_POPULATE
325
DEF("mem-prealloc", 0, QEMU_OPTION_mem_prealloc,
326
    "-mem-prealloc   preallocate guest memory (use with -mem-path)\n")
327
STEXI
328
@item -mem-prealloc
329
Preallocate memory when using -mem-path.
330
ETEXI
331
#endif
332

  
317 333
DEF("k", HAS_ARG, QEMU_OPTION_k,
318 334
    "-k language     use keyboard layout (for example 'fr' for French)\n")
319 335
STEXI
b/vl.c
185 185
DisplayType display_type = DT_DEFAULT;
186 186
const char* keyboard_layout = NULL;
187 187
ram_addr_t ram_size;
188
const char *mem_path = NULL;
189
#ifdef MAP_POPULATE
190
int mem_prealloc = 0; /* force preallocation of physical target memory */
191
#endif
188 192
int nb_nics;
189 193
NICInfo nd_table[MAX_NICS];
190 194
int vm_running;
......
5216 5220
                ram_size = value;
5217 5221
                break;
5218 5222
            }
5223
            case QEMU_OPTION_mempath:
5224
                mem_path = optarg;
5225
                break;
5226
#ifdef MAP_POPULATE
5227
            case QEMU_OPTION_mem_prealloc:
5228
                mem_prealloc = 1;
5229
                break;
5230
#endif
5219 5231
            case QEMU_OPTION_d:
5220 5232
                {
5221 5233
                    int mask;

Also available in: Unified diff