From 3cbac1746027213a637ff48b617d766819ab7495 Mon Sep 17 00:00:00 2001
From: Markus Armbruster <armbru@redhat.com>
Date: Mon, 13 Feb 2012 09:41:41 +0100
Subject: [PATCH] Support running QEMU on Valgrind

RH-Author: Markus Armbruster <armbru@redhat.com>
Message-id: <1329126101-5590-2-git-send-email-armbru@redhat.com>
Patchwork-id: 37178
O-Subject: [RHEL-6.3 PATCH qemu-kvm 1/1] Support running QEMU on Valgrind
Bugzilla: 750739
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
RH-Acked-by: Alex Williamson <alex.williamson@redhat.com>

From: Stefan Weil <sw@weilnetz.de>

Valgrind is a tool which can automatically detect many kinds of bugs.

Running QEMU on Valgrind with x86_64 hosts was not possible because
Valgrind aborts when memalign is called with an alignment larger than
1 MiB. QEMU normally uses 2 MiB on Linux x86_64.

Now the alignment is reduced to the page size when QEMU is running on
Valgrind.

v2:
Instead of using the macro RUNNING_ON_VALGRIND from valgrind.h,
the patch now uses a hack from libvirt which tests for the pre-loaded
vgpreload_*.so shared libraries. This avoids the need for valgrind.h.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
(cherry picked from commit c2a8238a2c1e37a2ae6d628a2b7bd95d1b5f1a89)

Conflicts:

	oslib-posix.c
Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 exec.c |   19 +++++++++++++++++++
 1 files changed, 19 insertions(+), 0 deletions(-)

Signed-off-by: Michal Novotny <minovotn@redhat.com>
---
 exec.c |   19 +++++++++++++++++++
 1 files changed, 19 insertions(+), 0 deletions(-)

diff --git a/exec.c b/exec.c
index 7e139b7..a16f8ca 100644
--- a/exec.c
+++ b/exec.c
@@ -2649,6 +2649,13 @@ extern int disable_KSM;
  * it even without NPT/EPT).
  */
 #define PREFERRED_RAM_ALIGN (2*1024*1024)
+#define CONFIG_VALGRIND
+#endif
+
+#if defined(CONFIG_VALGRIND)
+static int running_on_valgrind = -1;
+#else
+#  define running_on_valgrind 0
 #endif
 
 static ram_addr_t find_ram_offset(ram_addr_t size)
@@ -2700,6 +2707,15 @@ ram_addr_t qemu_ram_alloc_from_ptr(DeviceState *dev, const char *name,
 {
     RAMBlock *new_block, *block;
 
+#if defined(CONFIG_VALGRIND)
+    if (running_on_valgrind < 0) {
+        /* First call, test whether we are running on Valgrind.
+           This is a substitute for RUNNING_ON_VALGRIND from valgrind.h. */
+        const char *ld = getenv("LD_PRELOAD");
+        running_on_valgrind = (ld != NULL && strstr(ld, "vgpreload"));
+    }
+#endif
+
     size = TARGET_PAGE_ALIGN(size);
     new_block = qemu_mallocz(sizeof(*new_block));
 
@@ -2734,6 +2750,9 @@ ram_addr_t qemu_ram_alloc_from_ptr(DeviceState *dev, const char *name,
 #else
 #ifdef PREFERRED_RAM_ALIGN
 	    if (size >= PREFERRED_RAM_ALIGN)
+                if (running_on_valgrind)
+		    new_block->host = qemu_vmalloc(size);
+                else
 		    new_block->host = qemu_memalign(PREFERRED_RAM_ALIGN, size);
 	    else
 #endif 
-- 
1.7.7.5

