From: Marcelo Tosatti <[EMAIL PROTECTED]>

Add an option so the user can specify the hugetlbfs mounted path, with
fallback to 4k pages on error.

Align the 4GB+ memslot on large page boundary.

Signed-off-by: Marcelo Tosatti <[EMAIL PROTECTED]>
Signed-off-by: Avi Kivity <[EMAIL PROTECTED]>

diff --git a/qemu/hw/pc.c b/qemu/hw/pc.c
index efcad53..ef180ec 100644
--- a/qemu/hw/pc.c
+++ b/qemu/hw/pc.c
@@ -854,6 +854,15 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size,
     /* above 4giga memory allocation */
     if (above_4g_mem_size > 0) {
         ram_addr = qemu_ram_alloc(above_4g_mem_size);
+       if (hpagesize) {
+               if (ram_addr & (hpagesize-1)) {
+                       unsigned long aligned_addr;
+                       aligned_addr = (ram_addr + hpagesize - 1) &
+                                        ~(hpagesize-1);
+                       qemu_ram_alloc(aligned_addr - ram_addr);
+                       ram_addr = aligned_addr;
+               }
+       }
         cpu_register_physical_memory(0x100000000, above_4g_mem_size, ram_addr);
 
        if (kvm_enabled())
diff --git a/qemu/sysemu.h b/qemu/sysemu.h
index ffc468a..1599867 100644
--- a/qemu/sysemu.h
+++ b/qemu/sysemu.h
@@ -99,6 +99,7 @@ extern int no_quit;
 extern int semihosting_enabled;
 extern int autostart;
 extern int old_param;
+extern int hpagesize;
 extern const char *bootp_filename;
 
 
diff --git a/qemu/vl.c b/qemu/vl.c
index faa72fc..c9ed3f0 100644
--- a/qemu/vl.c
+++ b/qemu/vl.c
@@ -237,6 +237,9 @@ int semihosting_enabled = 0;
 int autostart = 1;
 int time_drift_fix = 0;
 unsigned int kvm_shadow_memory = 0;
+const char *hugetlbpath = NULL;
+const char *hugetlbfile = NULL;
+int hpagesize = 0;
 const char *cpu_vendor_string;
 #ifdef TARGET_ARM
 int old_param = 0;
@@ -8071,6 +8074,7 @@ static void help(int exitcode)
 #endif
            "-tdf            inject timer interrupts that got lost\n"
            "-kvm-shadow-memory megs set the amount of shadow pages to be 
allocated\n"
+           "-hugetlb-path   set the path to hugetlbfs mounted directory, also 
enables allocation of guest memory with huge pages\n"
           "-option-rom rom load a file, rom, into the option ROM space\n"
 #ifdef TARGET_SPARC
            "-prom-env variable=value  set OpenBIOS nvram variables\n"
@@ -8189,6 +8193,7 @@ enum {
     QEMU_OPTION_incoming,
     QEMU_OPTION_tdf,
     QEMU_OPTION_kvm_shadow_memory,
+    QEMU_OPTION_hugetlbpath,
 };
 
 typedef struct QEMUOption {
@@ -8310,6 +8315,7 @@ const QEMUOption qemu_options[] = {
 #endif
     { "clock", HAS_ARG, QEMU_OPTION_clock },
     { "startdate", HAS_ARG, QEMU_OPTION_startdate },
+    { "hugetlb-path", HAS_ARG, QEMU_OPTION_hugetlbpath },
     { NULL },
 };
 
@@ -8561,6 +8567,94 @@ void qemu_get_launch_info(int *argc, char ***argv, int 
*opt_daemonize, const cha
     *opt_incoming = incoming;
 }
 
+
+static int gethugepagesize(void)
+{
+       int ret, fd;
+       char buf[4096];
+       char *needle = "Hugepagesize:";
+       char *size;
+       unsigned long hugepagesize;
+
+       fd = open("/proc/meminfo", O_RDONLY);
+       if (fd < 0) {
+               perror("open");
+               exit(0);
+       }
+
+       ret = read(fd, buf, sizeof(buf));
+       if (ret < 0) {
+               perror("read");
+               exit(0);
+       }
+
+       size = strstr(buf, needle);
+       if (!size)
+               return 0;
+       size += strlen(needle);
+       hugepagesize = strtol(size, NULL, 0);
+       return hugepagesize;
+}
+
+void cleanup_hugetlb(void)
+{
+       if (hugetlbfile)
+               unlink(hugetlbfile);
+}
+
+void *alloc_huge_area(unsigned long memory, const char *path)
+{
+       void *area;
+       int fd;
+       char *filename;
+       char *tmpfile = "/kvm.XXXXXX";
+
+       filename = qemu_malloc(4096);
+       if (!filename)
+               return NULL;
+
+       memset(filename, 0, 4096);
+       strncpy(filename, path, 4096 - strlen(tmpfile) - 1);
+       strcat(filename, tmpfile);
+
+       hpagesize = gethugepagesize() * 1024;
+       if (!hpagesize)
+               return NULL;
+
+       mkstemp(filename);
+       fd = open(filename, O_RDWR);
+       if (fd < 0) {
+               perror("open");
+               hpagesize = 0;
+               exit(0);
+       }
+       memory = (memory+hpagesize-1) & ~(hpagesize-1);
+
+       area = mmap(0, memory, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
+       if (area == MAP_FAILED) {
+               perror("mmap");
+               hpagesize = 0;
+               exit(0);
+       }
+
+       hugetlbfile = filename;
+       atexit(cleanup_hugetlb);
+
+       return area;
+}
+
+void *qemu_alloc_physram(unsigned long memory)
+{
+       void *area = NULL;
+
+       if (hugetlbpath)
+               area = alloc_huge_area(memory, hugetlbpath);
+       if (!area)
+               area = qemu_vmalloc(memory);
+
+       return area;
+}
+
 int main(int argc, char **argv)
 {
 #ifdef CONFIG_GDBSTUB
@@ -9159,6 +9253,9 @@ int main(int argc, char **argv)
             case QEMU_OPTION_kvm_shadow_memory:
                 kvm_shadow_memory = (int64_t)atoi(optarg) * 1024 * 1024 / 4096;
                 break;
+            case QEMU_OPTION_hugetlbpath:
+               hugetlbpath = optarg;
+               break;
             case QEMU_OPTION_name:
                 qemu_name = optarg;
                 break;
@@ -9394,7 +9491,7 @@ int main(int argc, char **argv)
 
             ret = kvm_qemu_check_extension(KVM_CAP_USER_MEMORY);
             if (ret) {
-                phys_ram_base = qemu_vmalloc(phys_ram_size);
+                phys_ram_base = qemu_alloc_physram(phys_ram_size);
                if (!phys_ram_base) {
                        fprintf(stderr, "Could not allocate physical memory\n");
                        exit(1);

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
kvm-commits mailing list
kvm-commits@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kvm-commits

Reply via email to