From: Andre Przywara <andre.przywara@amd.com>
To: avi@redhat.com, anthony@codemonkey.ws
Cc: qemu-devel@nongnu.org, kvm@vger.kernel.org,
Andre Przywara <andre.przywara@amd.com>
Subject: [RFC] allow multi-core guests: introduce cores= option to -cpu
Date: Fri, 3 Jul 2009 16:41:56 +0200 [thread overview]
Message-ID: <1246632116-31366-1-git-send-email-andre.przywara@amd.com> (raw)
Hi,
currently SMP guests happen to see <n> vCPUs as <n> different sockets.
Some guests (Windows comes to mind) have license restrictions and refuse
to run on multi-socket machines.
So lets introduce a "cores=" parameter to the -cpu option to let the user
specify the number of _cores_ the guest should see.
This patch has not been tested with all corner cases, so I just want to
hear your comments whether
a) we need such an option and
b) you like this particular approach.
Applying this qemu.git patch to qemu-kvm.git fixes Windows SMP boot on
some versions, I successfully tried up to -smp 16 -cpu host,cores=8 with
WindowsXP Pro.
Regards,
Andre.
Signed-off-by: Andre Przywara <andre.przywara@amd.com>
---
target-i386/cpu.h | 1 +
target-i386/helper.c | 26 ++++++++++++++++++++++++--
2 files changed, 25 insertions(+), 2 deletions(-)
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 4a8608e..96fa471 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -657,6 +657,7 @@ typedef struct CPUX86State {
uint32_t cpuid_ext3_features;
uint32_t cpuid_apic_id;
int cpuid_vendor_override;
+ int cpuid_cores;
/* MTRRs */
uint64_t mtrr_fixed[11];
diff --git a/target-i386/helper.c b/target-i386/helper.c
index 82e1ff1..9c54fb9 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -103,6 +103,7 @@ typedef struct x86_def_t {
uint32_t xlevel;
char model_id[48];
int vendor_override;
+ int cores;
} x86_def_t;
#define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
@@ -351,7 +352,7 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
char *featurestr, *name = strtok(s, ",");
uint32_t plus_features = 0, plus_ext_features = 0, plus_ext2_features = 0, plus_ext3_features = 0;
uint32_t minus_features = 0, minus_ext_features = 0, minus_ext2_features = 0, minus_ext3_features = 0;
- int family = -1, model = -1, stepping = -1;
+ int family = -1, model = -1, stepping = -1, cores = 1;
def = NULL;
for (i = 0; i < ARRAY_SIZE(x86_defs); i++) {
@@ -406,6 +407,14 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
goto error;
}
x86_cpu_def->stepping = stepping;
+ } else if (!strcmp(featurestr, "cores")) {
+ char *err;
+ cores = strtol(val, &err, 10);
+ if (!*val || *err || cores < 1 || cores > 0xff) {
+ fprintf(stderr, "bad numerical value %s\n", val);
+ goto error;
+ }
+ x86_cpu_def->cores = cores;
} else if (!strcmp(featurestr, "vendor")) {
if (strlen(val) != 12) {
fprintf(stderr, "vendor string must be 12 chars long\n");
@@ -473,6 +482,7 @@ static int cpu_x86_register (CPUX86State *env, const char *cpu_model)
env->cpuid_vendor3 = CPUID_VENDOR_INTEL_3;
}
env->cpuid_vendor_override = def->vendor_override;
+ env->cpuid_cores = def->cores;
env->cpuid_level = def->level;
if (def->family > 0x0f)
env->cpuid_version = 0xf00 | ((def->family - 0x0f) << 20);
@@ -1562,9 +1572,14 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
break;
case 1:
*eax = env->cpuid_version;
- *ebx = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
+ /* CLFLUSH size in quad words, Linux wants it. */
+ *ebx = (env->cpuid_apic_id << 24) | 8 << 8;
*ecx = env->cpuid_ext_features;
*edx = env->cpuid_features;
+ if (env->cpuid_cores > 1) {
+ *ebx |= env->cpuid_cores << 16; /* LogicalProcessorCount */
+ *edx |= 1 << 28; /* HTT bit */
+ }
break;
case 2:
/* cache info: needed for Pentium Pro compatibility */
@@ -1642,6 +1657,10 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
*ecx = env->cpuid_ext3_features;
*edx = env->cpuid_ext2_features;
+ if (env->cpuid_cores > 1) {
+ *ecx |= 1 << 1; /* CmpLegacy bit */
+ }
+
if (kvm_enabled()) {
/* Nested SVM not yet supported in KVM */
*ecx &= ~CPUID_EXT3_SVM;
@@ -1696,6 +1715,9 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
*ebx = 0;
*ecx = 0;
*edx = 0;
+ if (env->cpuid_cores > 1) {
+ *ecx |= env->cpuid_cores - 1; /* NC: Number of CPU cores */
+ }
break;
case 0x8000000A:
*eax = 0x00000001; /* SVM Revision */
--
1.6.1.3
next reply other threads:[~2009-07-03 14:43 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-07-03 14:41 Andre Przywara [this message]
2009-07-03 14:52 ` [RFC] allow multi-core guests: introduce cores= option to -cpu Samuel Thibault
2009-07-03 23:28 ` [Qemu-devel] " Andre Przywara
2009-07-03 23:53 ` Samuel Thibault
2009-07-03 15:16 ` Brian Jackson
2009-07-03 22:52 ` Andre Przywara
2009-07-04 0:04 ` [Qemu-devel] " Jamie Lokier
2009-07-04 7:18 ` Gleb Natapov
2009-07-03 15:46 ` [Qemu-devel] " Paul Brook
2009-07-03 23:45 ` Andre Przywara
2009-07-04 5:58 ` Paul Brook
2009-07-04 15:25 ` Avi Kivity
2009-07-05 13:23 ` Alexander Graf
2009-07-05 14:53 ` Avi Kivity
2009-07-05 15:04 ` Gleb Natapov
2009-07-05 15:11 ` Avi Kivity
2009-07-05 15:11 ` Alexander Graf
2009-07-05 15:17 ` Avi Kivity
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1246632116-31366-1-git-send-email-andre.przywara@amd.com \
--to=andre.przywara@amd.com \
--cc=anthony@codemonkey.ws \
--cc=avi@redhat.com \
--cc=kvm@vger.kernel.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox