diff mbox

[v10,2/4] x86: use new method to correct reset sequence

Message ID e46c5ecd19c78b2f0ecd5dbf9cb10c0b476c3812.1441008774.git.zhugh.fnst@cn.fujitsu.com
State New
Headers show

Commit Message

Zhu Guihua Aug. 31, 2015, 9:47 a.m. UTC
Something must be occur during reset of the X86 platform in a specific
order. For example, some devices (such as hpet, rtc) reset will send
irq to apic, this will update the apic register. In order to ensure
the apic register could be set to default values, apic reset must be
after those devices reset.

This patch uses the new QEMUMachine reset method to solve the above
problem, ensuring the various reset happen in the correct order.

Signed-off-by: Zhu Guihua <zhugh.fnst@cn.fujitsu.com>
---
 hw/i386/pc.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

Comments

Igor Mammedov Aug. 31, 2015, 1:40 p.m. UTC | #1
On Mon, 31 Aug 2015 17:47:45 +0800
Zhu Guihua <zhugh.fnst@cn.fujitsu.com> wrote:

> Something must be occur during reset of the X86 platform in a specific
> order. For example, some devices (such as hpet, rtc) reset will send
> irq to apic, this will update the apic register. In order to ensure
> the apic register could be set to default values, apic reset must be
> after those devices reset.
> 
May be:

During reset some devices (such as hpet, rtc) might send IRQ to APIC
which changes APIC's state from default one it's supposed to have
at machine startup time.
Fix this by resetting APIC after devices have been reset to cancel
any changes that qemu_devices_reset() might have done to its state.

> This patch uses the new QEMUMachine reset method to solve the above
> problem, ensuring the various reset happen in the correct order.
> 
> Signed-off-by: Zhu Guihua <zhugh.fnst@cn.fujitsu.com>
> ---
>  hw/i386/pc.c | 22 ++++++++++++++++++++++
>  1 file changed, 22 insertions(+)
> 
> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> index e15971c..875ada8 100644
> --- a/hw/i386/pc.c
> +++ b/hw/i386/pc.c
> @@ -1928,6 +1928,27 @@ static void pc_machine_initfn(Object *obj)
>                               NULL, &error_abort);
>  }
>  
> +static void pc_machine_reset(void)
> +{
> +    CPUState *cs;
> +    X86CPU *cpu;
> +
> +    qemu_devices_reset();
> +
> +    /* When some devices (such as hpet, rtc) do their reset, they will
> +     * send irq to APIC. This will modify the value of the APIC register.
> +     * In order to ensure the APIC register can be set to default value,
> +     * APIC reset must be after those devices reset.
> +     */
S/^^^/
Reset APIC after devices have been reset to cancel
any changes that qemu_devices_reset() might have done.

> +    CPU_FOREACH(cs) {
> +        cpu = X86_CPU(cs);
> +
> +        if (cpu->apic_state) {
> +            device_reset(cpu->apic_state);
> +        }
> +    }
> +}
> +
>  static unsigned pc_cpu_index_to_socket_id(unsigned cpu_index)
>  {
>      unsigned pkg_id, core_id, smt_id;
> @@ -1948,6 +1969,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
>      mc->default_boot_order = "cad";
>      mc->hot_add_cpu = pc_hot_add_cpu;
>      mc->max_cpus = 255;
> +    mc->reset = pc_machine_reset;
>      hc->plug = pc_machine_device_plug_cb;
>      hc->unplug_request = pc_machine_device_unplug_request_cb;
>      hc->unplug = pc_machine_device_unplug_cb;
diff mbox

Patch

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index e15971c..875ada8 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1928,6 +1928,27 @@  static void pc_machine_initfn(Object *obj)
                              NULL, &error_abort);
 }
 
+static void pc_machine_reset(void)
+{
+    CPUState *cs;
+    X86CPU *cpu;
+
+    qemu_devices_reset();
+
+    /* When some devices (such as hpet, rtc) do their reset, they will
+     * send irq to APIC. This will modify the value of the APIC register.
+     * In order to ensure the APIC register can be set to default value,
+     * APIC reset must be after those devices reset.
+     */
+    CPU_FOREACH(cs) {
+        cpu = X86_CPU(cs);
+
+        if (cpu->apic_state) {
+            device_reset(cpu->apic_state);
+        }
+    }
+}
+
 static unsigned pc_cpu_index_to_socket_id(unsigned cpu_index)
 {
     unsigned pkg_id, core_id, smt_id;
@@ -1948,6 +1969,7 @@  static void pc_machine_class_init(ObjectClass *oc, void *data)
     mc->default_boot_order = "cad";
     mc->hot_add_cpu = pc_hot_add_cpu;
     mc->max_cpus = 255;
+    mc->reset = pc_machine_reset;
     hc->plug = pc_machine_device_plug_cb;
     hc->unplug_request = pc_machine_device_unplug_request_cb;
     hc->unplug = pc_machine_device_unplug_cb;