Revision 68a1c816 linux-user/main.c

b/linux-user/main.c
44 44
#if defined(CONFIG_USE_GUEST_BASE)
45 45
unsigned long guest_base;
46 46
int have_guest_base;
47
unsigned long reserved_va;
47 48
#endif
48 49

  
49 50
static const char *interp_prefix = CONFIG_QEMU_PREFIX;
......
2610 2611
           "-0 argv0          forces target process argv[0] to be argv0\n"
2611 2612
#if defined(CONFIG_USE_GUEST_BASE)
2612 2613
           "-B address        set guest_base address to address\n"
2614
           "-R size           reserve size bytes for guest virtual address space\n"
2613 2615
#endif
2614 2616
           "\n"
2615 2617
           "Debug options:\n"
......
2805 2807
        } else if (!strcmp(r, "B")) {
2806 2808
           guest_base = strtol(argv[optind++], NULL, 0);
2807 2809
           have_guest_base = 1;
2810
        } else if (!strcmp(r, "R")) {
2811
            char *p;
2812
            int shift = 0;
2813
            reserved_va = strtoul(argv[optind++], &p, 0);
2814
            switch (*p) {
2815
            case 'k':
2816
            case 'K':
2817
                shift = 10;
2818
                break;
2819
            case 'M':
2820
                shift = 20;
2821
                break;
2822
            case 'G':
2823
                shift = 30;
2824
                break;
2825
            }
2826
            if (shift) {
2827
                unsigned long unshifted = reserved_va;
2828
                p++;
2829
                reserved_va <<= shift;
2830
                if (((reserved_va >> shift) != unshifted)
2831
#if HOST_LONG_BITS > TARGET_VIRT_ADDR_SPACE_BITS
2832
                    || (reserved_va > (1ul << TARGET_VIRT_ADDR_SPACE_BITS))
2833
#endif
2834
                    ) {
2835
                    fprintf(stderr, "Reserved virtual address too big\n");
2836
                    exit(1);
2837
                }
2838
            }
2839
            if (*p) {
2840
                fprintf(stderr, "Unrecognised -R size suffix '%s'\n", p);
2841
                exit(1);
2842
            }
2808 2843
#endif
2809 2844
        } else if (!strcmp(r, "drop-ld-preload")) {
2810 2845
            (void) envlist_unsetenv(envlist, "LD_PRELOAD");
......
2893 2928
     * proper page alignment for guest_base.
2894 2929
     */
2895 2930
    guest_base = HOST_PAGE_ALIGN(guest_base);
2931

  
2932
    if (reserved_va) {
2933
        void *p;
2934
        int flags;
2935

  
2936
        flags = MAP_ANONYMOUS | MAP_PRIVATE | MAP_NORESERVE;
2937
        if (have_guest_base) {
2938
            flags |= MAP_FIXED;
2939
        }
2940
        p = mmap((void *)guest_base, reserved_va, PROT_NONE, flags, -1, 0);
2941
        if (p == MAP_FAILED) {
2942
            fprintf(stderr, "Unable to reserve guest address space\n");
2943
            exit(1);
2944
        }
2945
        guest_base = (unsigned long)p;
2946
        /* Make sure the address is properly aligned.  */
2947
        if (guest_base & ~qemu_host_page_mask) {
2948
            munmap(p, reserved_va);
2949
            p = mmap((void *)guest_base, reserved_va + qemu_host_page_size,
2950
                     PROT_NONE, flags, -1, 0);
2951
            if (p == MAP_FAILED) {
2952
                fprintf(stderr, "Unable to reserve guest address space\n");
2953
                exit(1);
2954
            }
2955
            guest_base = HOST_PAGE_ALIGN((unsigned long)p);
2956
        }
2957
        qemu_log("Reserved 0x%lx bytes of guest address space\n", reserved_va);
2958
    }
2896 2959
#endif /* CONFIG_USE_GUEST_BASE */
2897 2960

  
2898 2961
    /*

Also available in: Unified diff