target-i386: clear bsp bit when designating bsp
authorNadav Amit <namit@cs.technion.ac.il>
Wed, 1 Apr 2015 23:58:36 +0000 (02:58 +0300)
committerPaolo Bonzini <pbonzini@redhat.com>
Thu, 2 Apr 2015 13:57:27 +0000 (15:57 +0200)
Since the BSP bit is writable on real hardware, during reset all the CPUs which
were not chosen to be the BSP should have their BSP bit cleared. This fix is
required for KVM to work correctly when it changes the BSP bit.

An additional fix is required for QEMU tcg to allow software to change the BSP
bit.

Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
Message-Id: <1427932716-11800-1-git-send-email-namit@cs.technion.ac.il>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
hw/intc/apic_common.c
include/hw/i386/apic.h
target-i386/cpu.c

index 0858b459433a750eb9746324a5389192db1343fc..042e960f426afe43f58ca3f19d94408deb3336c2 100644 (file)
@@ -215,14 +215,18 @@ void apic_init_reset(DeviceState *dev)
     }
 }
 
-void apic_designate_bsp(DeviceState *dev)
+void apic_designate_bsp(DeviceState *dev, bool bsp)
 {
     if (dev == NULL) {
         return;
     }
 
     APICCommonState *s = APIC_COMMON(dev);
-    s->apicbase |= MSR_IA32_APICBASE_BSP;
+    if (bsp) {
+        s->apicbase |= MSR_IA32_APICBASE_BSP;
+    } else {
+        s->apicbase &= ~MSR_IA32_APICBASE_BSP;
+    }
 }
 
 static void apic_reset_common(DeviceState *dev)
index 1d48e027c3c17c88f1c9e4f894ef72f78d903f59..51eb6d388457caff2706c59df1ef0821622d241e 100644 (file)
@@ -21,7 +21,7 @@ void apic_sipi(DeviceState *s);
 void apic_handle_tpr_access_report(DeviceState *d, target_ulong ip,
                                    TPRAccess access);
 void apic_poll_irq(DeviceState *d);
-void apic_designate_bsp(DeviceState *d);
+void apic_designate_bsp(DeviceState *d, bool bsp);
 
 /* pc.c */
 DeviceState *cpu_get_current_apic(void);
index b2d1c95df45280eee8070d15590d0978ca91af64..03b33cf3bd9d028a2734d49eb841d6962c4426d1 100644 (file)
@@ -2714,9 +2714,7 @@ static void x86_cpu_reset(CPUState *s)
 
 #if !defined(CONFIG_USER_ONLY)
     /* We hard-wire the BSP to the first CPU. */
-    if (s->cpu_index == 0) {
-        apic_designate_bsp(cpu->apic_state);
-    }
+    apic_designate_bsp(cpu->apic_state, s->cpu_index == 0);
 
     s->halted = !cpu_is_bsp(cpu);