qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH] don't expose lm bit if kernel is not 64-bit capable


From: Glauber Costa
Subject: [Qemu-devel] [PATCH] don't expose lm bit if kernel is not 64-bit capable.
Date: Tue, 3 Feb 2009 15:15:55 -0500

If the kernel is not 64-bit capable (even if the host
machine is) do not expose the lm bit in guest cpuid.

This patch do the verification inside the host_cpuid
function, for clarity. This way we can encapsulate all
forms of masking in there, and replace with other approaches
if they seem suitable in the future.

Cons are we're calling a syscall multiple times, but this
is hardly the hot path of anything.

Signed-off-by: Glauber Costa <address@hidden>
---
 target-i386/helper.c |   13 ++++++++++---
 1 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/target-i386/helper.c b/target-i386/helper.c
index a28ab93..327d8fc 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -24,6 +24,7 @@
 #include <inttypes.h>
 #include <signal.h>
 #include <assert.h>
+#include <sys/utsname.h>
 
 #include "cpu.h"
 #include "exec-all.h"
@@ -1375,6 +1376,7 @@ static void host_cpuid(uint32_t function, uint32_t *eax, 
uint32_t *ebx,
 {
 #if defined(CONFIG_KVM)
     uint32_t vec[4];
+    struct utsname utsname;
 
 #ifdef __x86_64__
     asm volatile("cpuid"
@@ -1399,11 +1401,16 @@ static void host_cpuid(uint32_t function, uint32_t 
*eax, uint32_t *ebx,
        *ebx = vec[1];
     if (ecx)
        *ecx = vec[2];
-    if (edx)
-       *edx = vec[3];
+    if (edx) {
+        uname(&utsname);
+        if (strcmp(utsname.machine, "x86_64"))
+            vec[3] &= ~0x20000000;
+       *edx = vec[3];
+    }
 #endif
 }
 
+
 void cpu_x86_cpuid(CPUX86State *env, uint32_t index,
                    uint32_t *eax, uint32_t *ebx,
                    uint32_t *ecx, uint32_t *edx)
@@ -1526,7 +1533,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index,
             /* disable CPU features that the host does not support */
 
             /* long mode */
-            if ((h_edx & 0x20000000) == 0 /* || !lm_capable_kernel */)
+            if ((h_edx & 0x20000000) == 0) 
                 *edx &= ~0x20000000;
             /* syscall */
             if ((h_edx & 0x00000800) == 0)
-- 
1.5.6.5





reply via email to

[Prev in Thread] Current Thread [Next in Thread]