Package: kqemu
Severity: normal

When kqemu runs in a 32-bit host, on a CPU that is capable of long mode
(64-bit), it should remove CPUID_LM flag to prevent the guest from detecting
a capability that can't really be provided.

The attached patch is my attempt at archieving this, but it doesn't seem to
work.  I'm providing it anyway, since it might be of some use (maybe it just
needs a small correction, or maybe it's completely flawed).

-- System Information:
Debian Release: 4.0
  APT prefers testing
  APT policy: (500, 'testing')
Architecture: amd64 (x86_64)
Shell:  /bin/sh linked to /bin/bash
Kernel: Linux 2.6.18-3-amd64
Locale: LANG=ca_AD.UTF-8, LC_CTYPE=ca_AD.UTF-8 (charmap=UTF-8)
diff -ur qemu-0.8.2.old/kqemu.c qemu-0.8.2/kqemu.c
--- qemu-0.8.2.old/kqemu.c	2006-07-22 19:23:34.000000000 +0200
+++ qemu-0.8.2/kqemu.c	2007-02-12 22:10:34.000000000 +0100
@@ -119,7 +119,7 @@
 
 static void kqemu_update_cpuid(CPUState *env)
 {
-    int critical_features_mask, features, ext_features, ext_features_mask;
+    int critical_features_mask, features, ext_features, ext_features_mask, ext2_features, ext2_features_mask;
     uint32_t eax, ebx, ecx, edx;
 
     /* the following features are kept identical on the host and
@@ -131,24 +131,32 @@
         CPUID_FXSR | CPUID_MMX | CPUID_SSE | 
         CPUID_SSE2 | CPUID_SEP;
     ext_features_mask = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR;
+    ext2_features_mask = CPUID_EXT2_LM;
     if (!is_cpuid_supported()) {
         features = 0;
         ext_features = 0;
+        ext2_features = 0;
     } else {
         cpuid(1, eax, ebx, ecx, edx);
         features = edx;
         ext_features = ecx;
+        cpuid(0x80000001, eax, ebx, ecx, edx);
+        ext2_features = edx;
     }
 #ifdef __x86_64__
     /* NOTE: on x86_64 CPUs, SYSENTER is not supported in
        compatibility mode, so in order to have the best performances
        it is better not to use it */
     features &= ~CPUID_SEP;
+#else
+    ext2_features &= ~CPUID_EXT2_LM;
 #endif
     env->cpuid_features = (env->cpuid_features & ~critical_features_mask) |
         (features & critical_features_mask);
     env->cpuid_ext_features = (env->cpuid_ext_features & ~ext_features_mask) |
         (ext_features & ext_features_mask);
+    env->cpuid_ext2_features = (env->cpuid_ext2_features & ~ext2_features_mask) |
+        (ext2_features & ext2_features_mask);
     /* XXX: we could update more of the target CPUID state so that the
        non accelerated code sees exactly the same CPU features as the
        accelerated code */

Reply via email to