aboutsummaryrefslogtreecommitdiff
path: root/target-i386
diff options
context:
space:
mode:
authorEduardo Habkost <ehabkost@redhat.com>2013-01-22 18:25:09 -0200
committerAndreas Färber <afaerber@suse.de>2013-01-27 14:34:27 +0100
commit8932cfdf7b95734c9b4a114b8ed0b4527af77ce7 (patch)
treeea92b07d04ffd7d3dfe7771e63fa343b44e32304 /target-i386
parent247c9de13f9d54a94734875000a9faea8168c8ca (diff)
pc: Generate APIC IDs according to CPU topology
This keeps compatibility on machine-types pc-1.2 and older, and prints a warning in case the requested configuration won't get the correct topology. I couldn't think of a better way to warn about broken topology when in compat mode other than using error_report(). The warning message will probably be buried in a log file somewhere, but it's better than nothing. Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> Signed-off-by: Andreas Färber <afaerber@suse.de>
Diffstat (limited to 'target-i386')
-rw-r--r--target-i386/cpu.c28
-rw-r--r--target-i386/cpu.h1
2 files changed, 25 insertions, 4 deletions
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 75dc973e3b..c5acaa7523 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -23,6 +23,8 @@
#include "cpu.h"
#include "sysemu/kvm.h"
+#include "sysemu/cpus.h"
+#include "topology.h"
#include "qemu/option.h"
#include "qemu/config-file.h"
@@ -2194,6 +2196,14 @@ void x86_cpu_realize(Object *obj, Error **errp)
cpu_reset(CPU(cpu));
}
+/* Enables contiguous-apic-ID mode, for compatibility */
+static bool compat_apic_id_mode;
+
+void enable_compat_apic_id_mode(void)
+{
+ compat_apic_id_mode = true;
+}
+
/* Calculates initial APIC ID for a specific CPU index
*
* Currently we need to be able to calculate the APIC ID from the CPU index
@@ -2203,10 +2213,20 @@ void x86_cpu_realize(Object *obj, Error **errp)
*/
uint32_t x86_cpu_apic_id_from_index(unsigned int cpu_index)
{
- /* right now APIC ID == CPU index. this will eventually change to use
- * the CPU topology configuration properly
- */
- return cpu_index;
+ uint32_t correct_id;
+ static bool warned;
+
+ correct_id = x86_apicid_from_cpu_idx(smp_cores, smp_threads, cpu_index);
+ if (compat_apic_id_mode) {
+ if (cpu_index != correct_id && !warned) {
+ error_report("APIC IDs set in compatibility mode, "
+ "CPU topology won't match the configuration");
+ warned = true;
+ }
+ return cpu_index;
+ } else {
+ return correct_id;
+ }
}
static void x86_cpu_initfn(Object *obj)
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 9442f08305..27efe59488 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -1256,5 +1256,6 @@ void disable_kvm_pv_eoi(void);
const char *get_register_name_32(unsigned int reg);
uint32_t x86_cpu_apic_id_from_index(unsigned int cpu_index);
+void enable_compat_apic_id_mode(void);
#endif /* CPU_I386_H */