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 */