kvm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] Support for GB pages in KVM - userspace part
@ 2009-03-27 14:34 Joerg Roedel
  2009-03-27 14:34 ` [PATCH 1/2] kvm/qemu: use statfs to determine size of huge pages Joerg Roedel
  2009-03-27 14:34 ` [PATCH 2/2] kvm/qemu: set gbpages cpuid bit if kvm supports it Joerg Roedel
  0 siblings, 2 replies; 4+ messages in thread
From: Joerg Roedel @ 2009-03-27 14:34 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: kvm

Hi,

this patchset includes the changes necessary to KVM-Userspace to be able
to use the in-kernel support for GB pages I posted earlier.

Joerg

git diff --stat avi/master..

 libkvm/libkvm.c           |    9 ++++++++
 libkvm/libkvm.h           |    1 +
 qemu/qemu-kvm.c           |    6 +++++
 qemu/qemu-kvm.h           |    3 ++
 qemu/sysemu.h             |    2 +-
 qemu/target-i386/helper.c |    4 +++
 qemu/vl.c                 |   49 +++++++++++++++++++++++---------------------




^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/2] kvm/qemu: use statfs to determine size of huge pages
  2009-03-27 14:34 [PATCH 0/2] Support for GB pages in KVM - userspace part Joerg Roedel
@ 2009-03-27 14:34 ` Joerg Roedel
  2009-03-29 11:56   ` Avi Kivity
  2009-03-27 14:34 ` [PATCH 2/2] kvm/qemu: set gbpages cpuid bit if kvm supports it Joerg Roedel
  1 sibling, 1 reply; 4+ messages in thread
From: Joerg Roedel @ 2009-03-27 14:34 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, Joerg Roedel

The current method of finding out the size of huge pages does not work
reliable anymore. Current Linux supports more than one huge page size
but /proc/meminfo only show one of the supported sizes.
To find out the real page size used can be found by calling statfs. This
patch changes kvm/qemu to use statfs instead of parsing /proc/meminfo.

Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
 qemu/sysemu.h |    2 +-
 qemu/vl.c     |   42 +++++++++++++++++++-----------------------
 2 files changed, 20 insertions(+), 24 deletions(-)

diff --git a/qemu/sysemu.h b/qemu/sysemu.h
index 4457a40..d765465 100644
--- a/qemu/sysemu.h
+++ b/qemu/sysemu.h
@@ -105,7 +105,7 @@ extern int graphic_rotate;
 extern int no_quit;
 extern int semihosting_enabled;
 extern int old_param;
-extern int hpagesize;
+extern long hpagesize;
 extern const char *bootp_filename;
 
 #ifdef USE_KQEMU
diff --git a/qemu/vl.c b/qemu/vl.c
index c52d2d7..f820d3a 100644
--- a/qemu/vl.c
+++ b/qemu/vl.c
@@ -42,6 +42,7 @@
 #include <sys/ioctl.h>
 #include <sys/resource.h>
 #include <sys/socket.h>
+#include <sys/vfs.h>
 #include <netinet/in.h>
 #include <net/if.h>
 #if defined(__NetBSD__)
@@ -261,7 +262,7 @@ const char *mem_path = NULL;
 #ifdef MAP_POPULATE
 int mem_prealloc = 1;	/* force preallocation of physical target memory */
 #endif
-int hpagesize = 0;
+long hpagesize = 0;
 const char *cpu_vendor_string;
 #ifdef TARGET_ARM
 int old_param = 0;
@@ -4747,32 +4748,27 @@ void qemu_get_launch_info(int *argc, char ***argv, int *opt_daemonize, const cha
 }
 
 #ifdef USE_KVM
-static int gethugepagesize(void)
+
+#define HUGETLBFS_MAGIC       0x958458f6
+
+static long gethugepagesize(const char *path)
 {
-    int ret, fd;
-    char buf[4096];
-    const char *needle = "Hugepagesize:";
-    char *size;
-    unsigned long hugepagesize;
+    struct statfs fs;
+    int ret;
 
-    fd = open("/proc/meminfo", O_RDONLY);
-    if (fd < 0) {
-	perror("open");
-	exit(0);
-    }
+    do {
+	    ret = statfs(path, &fs);
+    } while (ret != 0 && errno == EINTR);
 
-    ret = read(fd, buf, sizeof(buf));
-    if (ret < 0) {
-	perror("read");
-	exit(0);
+    if (ret != 0) {
+	    perror("statfs");
+	    return 0;
     }
 
-    size = strstr(buf, needle);
-    if (!size)
-	return 0;
-    size += strlen(needle);
-    hugepagesize = strtol(size, NULL, 0);
-    return hugepagesize;
+    if (fs.f_type != HUGETLBFS_MAGIC)
+	    fprintf(stderr, "Warning: path not on HugeTLBFS: %s\n", path);
+
+    return fs.f_bsize;
 }
 
 static void *alloc_mem_area(size_t memory, unsigned long *len, const char *path)
@@ -4792,7 +4788,7 @@ static void *alloc_mem_area(size_t memory, unsigned long *len, const char *path)
     if (asprintf(&filename, "%s/kvm.XXXXXX", path) == -1)
 	return NULL;
 
-    hpagesize = gethugepagesize() * 1024;
+    hpagesize = gethugepagesize(path);
     if (!hpagesize)
 	return NULL;
 
-- 
1.5.6.4



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/2] kvm/qemu: set gbpages cpuid bit if kvm supports it
  2009-03-27 14:34 [PATCH 0/2] Support for GB pages in KVM - userspace part Joerg Roedel
  2009-03-27 14:34 ` [PATCH 1/2] kvm/qemu: use statfs to determine size of huge pages Joerg Roedel
@ 2009-03-27 14:34 ` Joerg Roedel
  1 sibling, 0 replies; 4+ messages in thread
From: Joerg Roedel @ 2009-03-27 14:34 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, Joerg Roedel

Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
 libkvm/libkvm.c           |    9 +++++++++
 libkvm/libkvm.h           |    1 +
 qemu/qemu-kvm.c           |    6 ++++++
 qemu/qemu-kvm.h           |    3 +++
 qemu/target-i386/helper.c |    4 ++++
 qemu/vl.c                 |    7 +++++++
 6 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/libkvm/libkvm.c b/libkvm/libkvm.c
index 0610e3f..a699fe9 100644
--- a/libkvm/libkvm.c
+++ b/libkvm/libkvm.c
@@ -1065,6 +1065,15 @@ int kvm_has_sync_mmu(kvm_context_t kvm)
         return r;
 }
 
+int kvm_has_gbpages(kvm_context_t kvm)
+{
+	int r = 0;
+#ifdef KVM_CAP_1GB_PAGES
+	r = ioctl(kvm->fd, KVM_CHECK_EXTENSION, KVM_CAP_1GB_PAGES);
+#endif
+	return r;
+}
+
 int kvm_inject_nmi(kvm_context_t kvm, int vcpu)
 {
 #ifdef KVM_CAP_USER_NMI
diff --git a/libkvm/libkvm.h b/libkvm/libkvm.h
index d3e431a..efbc23e 100644
--- a/libkvm/libkvm.h
+++ b/libkvm/libkvm.h
@@ -558,6 +558,7 @@ int kvm_dirty_pages_log_reset(kvm_context_t kvm);
 int kvm_irqchip_in_kernel(kvm_context_t kvm);
 
 int kvm_has_sync_mmu(kvm_context_t kvm);
+int kvm_has_gbpages(kvm_context_t kvm);
 
 #ifdef KVM_CAP_IRQCHIP
 /*!
diff --git a/qemu/qemu-kvm.c b/qemu/qemu-kvm.c
index 4164368..0a5c6c8 100644
--- a/qemu/qemu-kvm.c
+++ b/qemu/qemu-kvm.c
@@ -33,6 +33,7 @@ int kvm_irqchip = 1;
 int kvm_pit = 1;
 int kvm_pit_reinject = 1;
 int kvm_nested = 0;
+int kvm_gb_pages = 0;
 kvm_context_t kvm_context;
 
 pthread_mutex_t qemu_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -1395,6 +1396,11 @@ int qemu_kvm_has_sync_mmu(void)
     return kvm_has_sync_mmu(kvm_context);
 }
 
+int qemu_kvm_has_gbpages()
+{
+	return kvm_has_gbpages(kvm_context);
+}
+
 void qemu_kvm_cpu_stop(CPUState *env)
 {
     if (kvm_enabled())
diff --git a/qemu/qemu-kvm.h b/qemu/qemu-kvm.h
index ca59af8..6f2d99f 100644
--- a/qemu/qemu-kvm.h
+++ b/qemu/qemu-kvm.h
@@ -151,6 +151,7 @@ extern int kvm_irqchip;
 extern int kvm_pit;
 extern int kvm_pit_reinject;
 extern int kvm_nested;
+extern int kvm_gb_pages;
 extern kvm_context_t kvm_context;
 
 struct ioperm_data {
@@ -161,6 +162,7 @@ struct ioperm_data {
 };
 
 int qemu_kvm_has_sync_mmu(void);
+int qemu_kvm_has_gbpages(void);
 void qemu_kvm_cpu_stop(CPUState *env);
 
 #define kvm_enabled() (kvm_allowed)
@@ -172,6 +174,7 @@ void kvm_load_tsc(CPUState *env);
 #else
 #define kvm_enabled() (0)
 #define kvm_nested 0
+#define kvm_gb_pages 0
 #define qemu_kvm_irqchip_in_kernel() (0)
 #define qemu_kvm_pit_in_kernel() (0)
 #define kvm_has_sync_mmu() (0)
diff --git a/qemu/target-i386/helper.c b/qemu/target-i386/helper.c
index be7b021..78a5db5 100644
--- a/qemu/target-i386/helper.c
+++ b/qemu/target-i386/helper.c
@@ -1585,6 +1585,10 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
                 *ecx &= ~4UL;
             /* 3dnow */
             *edx &= ~0xc0000000;
+#ifdef USE_KVM
+            if (qemu_kvm_has_gbpages() && kvm_gb_pages)
+                *edx |= CPUID_EXT2_PDPE1GB;
+#endif
         }
         break;
     case 0x80000002:
diff --git a/qemu/vl.c b/qemu/vl.c
index f820d3a..651ef02 100644
--- a/qemu/vl.c
+++ b/qemu/vl.c
@@ -4189,6 +4189,7 @@ static void help(int exitcode)
 	   "-no-kvm-pit	    disable KVM kernel mode PIT\n"
 	   "-no-kvm-pit-reinjection disable KVM kernel mode PIT interrupt reinjection\n"
 	   "-enable-nesting enable support for running a VM inside the VM (AMD only)\n"
+	   "-enable-gb-pages enable GB pages in the guest (if host supports it)\n"
 #if defined(TARGET_I386) || defined(TARGET_X86_64) || defined(TARGET_IA64) || defined(__linux__)
            "-pcidevice host=bus:dev.func[,dma=none][,name=string]\n"
            "                expose a PCI device to the guest OS.\n"
@@ -4339,6 +4340,7 @@ enum {
     QEMU_OPTION_no_kqemu,
     QEMU_OPTION_enable_kvm,
     QEMU_OPTION_enable_nesting,
+    QEMU_OPTION_enable_gb_pages,
     QEMU_OPTION_no_kvm,
     QEMU_OPTION_no_kvm_irqchip,
     QEMU_OPTION_no_kvm_pit,
@@ -4488,6 +4490,7 @@ static const QEMUOption qemu_options[] = {
     { "no-kvm-pit", 0, QEMU_OPTION_no_kvm_pit },
     { "no-kvm-pit-reinjection", 0, QEMU_OPTION_no_kvm_pit_reinjection },
     { "enable-nesting", 0, QEMU_OPTION_enable_nesting },
+    { "enable-gb-pages", 0, QEMU_OPTION_enable_gb_pages },
 #if defined(TARGET_I386) || defined(TARGET_X86_64) || defined(TARGET_IA64) || defined(__linux__)
     { "pcidevice", HAS_ARG, QEMU_OPTION_pcidevice },
 #endif
@@ -5456,6 +5459,10 @@ int main(int argc, char **argv, char **envp)
 		kvm_nested = 1;
 		break;
 	    }
+            case QEMU_OPTION_enable_gb_pages: {
+                kvm_gb_pages = 1;
+		break;
+            }
 #if defined(TARGET_I386) || defined(TARGET_X86_64) || defined(TARGET_IA64) || defined(__linux__)
             case QEMU_OPTION_pcidevice:
 		if (assigned_devices_index >= MAX_DEV_ASSIGN_CMDLINE) {
-- 
1.5.6.4



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH 1/2] kvm/qemu: use statfs to determine size of huge pages
  2009-03-27 14:34 ` [PATCH 1/2] kvm/qemu: use statfs to determine size of huge pages Joerg Roedel
@ 2009-03-29 11:56   ` Avi Kivity
  0 siblings, 0 replies; 4+ messages in thread
From: Avi Kivity @ 2009-03-29 11:56 UTC (permalink / raw)
  To: Joerg Roedel; +Cc: Marcelo Tosatti, kvm

Joerg Roedel wrote:
> The current method of finding out the size of huge pages does not work
> reliable anymore. Current Linux supports more than one huge page size
> but /proc/meminfo only show one of the supported sizes.
> To find out the real page size used can be found by calling statfs. This
> patch changes kvm/qemu to use statfs instead of parsing /proc/meminfo.
>   

Applied, thanks.

-- 
error compiling committee.c: too many arguments to function


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2009-03-29 11:56 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-03-27 14:34 [PATCH 0/2] Support for GB pages in KVM - userspace part Joerg Roedel
2009-03-27 14:34 ` [PATCH 1/2] kvm/qemu: use statfs to determine size of huge pages Joerg Roedel
2009-03-29 11:56   ` Avi Kivity
2009-03-27 14:34 ` [PATCH 2/2] kvm/qemu: set gbpages cpuid bit if kvm supports it Joerg Roedel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).