Index: qemu/hw/apic.c
===================================================================
--- qemu.orig/hw/apic.c	2008-11-01 15:05:38.000000000 +0000
+++ qemu/hw/apic.c	2008-11-01 15:40:31.000000000 +0000
@@ -88,6 +88,10 @@
     int64_t initial_count_load_time, next_time;
     QEMUTimer *timer;
     qemu_irq *cpu_SIPI;
+    qemu_irq cpu_reset;
+    qemu_irq cpu_NMI;
+    qemu_irq cpu_SMI;
+    qemu_irq cpu_HWINT;
 } APICState;
 
 struct IOAPICState {
@@ -145,15 +149,15 @@
 
     switch ((lvt >> 8) & 7) {
     case APIC_DM_SMI:
-        cpu_interrupt(env, CPU_INTERRUPT_SMI);
+        qemu_irq_raise(s->cpu_SMI);
         break;
 
     case APIC_DM_NMI:
-        cpu_interrupt(env, CPU_INTERRUPT_NMI);
+        qemu_irq_raise(s->cpu_NMI);
         break;
 
     case APIC_DM_EXTINT:
-        cpu_interrupt(env, CPU_INTERRUPT_HARD);
+        qemu_irq_raise(s->cpu_HWINT);
         break;
 
     case APIC_DM_FIXED:
@@ -180,7 +184,7 @@
             reset_bit(s->irr, lvt & 0xff);
             /* fall through */
         case APIC_DM_EXTINT:
-            cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
+            qemu_irq_lower(s->cpu_HWINT);
             break;
         }
     }
@@ -237,12 +241,12 @@
 
         case APIC_DM_SMI:
             foreach_apic(apic_iter, deliver_bitmask,
-                cpu_interrupt(apic_iter->cpu_env, CPU_INTERRUPT_SMI) );
+                         qemu_irq_raise(apic_iter->cpu_SMI) );
             return;
 
         case APIC_DM_NMI:
             foreach_apic(apic_iter, deliver_bitmask,
-                cpu_interrupt(apic_iter->cpu_env, CPU_INTERRUPT_NMI) );
+                         qemu_irq_raise(apic_iter->cpu_NMI) );
             return;
 
         case APIC_DM_INIT:
@@ -347,7 +351,7 @@
     ppr = apic_get_ppr(s);
     if (ppr && (irrv & 0xf0) <= (ppr & 0xf0))
         return;
-    cpu_interrupt(s->cpu_env, CPU_INTERRUPT_HARD);
+    qemu_irq_raise(s->cpu_HWINT);
 }
 
 static void apic_set_irq(APICState *s, int vector_num, int trigger_mode)
@@ -427,7 +431,7 @@
     s->initial_count_load_time = 0;
     s->next_time = 0;
 
-    cpu_reset(s->cpu_env);
+    qemu_irq_raise(s->cpu_reset);
 
     if (!(s->apicbase & MSR_IA32_APICBASE_BSP))
         qemu_irq_lower(s->cpu_SIPI[0]);
@@ -858,7 +862,8 @@
     apic_mem_writel,
 };
 
-int apic_init(CPUState *env, qemu_irq *cpu_SIPI)
+int apic_init(CPUState *env, qemu_irq *cpu_SIPI, qemu_irq cpu_reset,
+              qemu_irq cpu_NMI, qemu_irq cpu_SMI, qemu_irq cpu_HWINT)
 {
     APICState *s;
 
@@ -873,6 +878,10 @@
     s->cpu_env = env;
 
     s->cpu_SIPI = cpu_SIPI;
+    s->cpu_reset = cpu_reset;
+    s->cpu_NMI = cpu_NMI;
+    s->cpu_SMI = cpu_SMI;
+    s->cpu_HWINT = cpu_HWINT;
     apic_reset(s);
 
     /* XXX: mapping more APICs at the same memory location */
Index: qemu/hw/pc.c
===================================================================
--- qemu.orig/hw/pc.c	2008-11-01 15:05:38.000000000 +0000
+++ qemu/hw/pc.c	2008-11-01 15:36:59.000000000 +0000
@@ -158,6 +158,36 @@
 {
 }
 
+static void cpu_set_NMI(void *opaque, int irq, int level)
+{
+    CPUState *env = opaque;
+
+    if (level)
+        cpu_interrupt(env, CPU_INTERRUPT_NMI);
+    else
+        cpu_reset_interrupt(env, CPU_INTERRUPT_NMI);
+}
+
+static void cpu_set_SMI(void *opaque, int irq, int level)
+{
+    CPUState *env = opaque;
+
+    if (level)
+        cpu_interrupt(env, CPU_INTERRUPT_SMI);
+    else
+        cpu_reset_interrupt(env, CPU_INTERRUPT_SMI);
+}
+
+static void cpu_set_HWINT(void *opaque, int irq, int level)
+{
+    CPUState *env = opaque;
+
+    if (level)
+        cpu_interrupt(env, CPU_INTERRUPT_HARD);
+    else
+        cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
+}
+
 /* PC cmos mappings */
 
 #define REG_EQUIPMENT_BYTE          0x14
@@ -691,6 +721,12 @@
     cpu_reset(env);
 }
 
+static void main_cpu_reset_signal(void *opaque, int irq, int level)
+{
+    if (level)
+        main_cpu_reset(opaque);
+}
+
 static const int ide_iobase[2] = { 0x1f0, 0x170 };
 static const int ide_iobase2[2] = { 0x3f6, 0x376 };
 static const int ide_irq[2] = { 14, 15 };
@@ -769,7 +805,8 @@
     int index;
     BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
     BlockDriverState *fd[MAX_FD];
-    qemu_irq *cpu_SIPI[MAX_CPUS];
+    qemu_irq *cpu_SIPI[MAX_CPUS], *cpu_resets[MAX_CPUS], *cpu_NMIs[MAX_CPUS],
+        *cpu_SMIs[MAX_CPUS], *cpu_HWINTs[MAX_CPUS];
 
     if (ram_size >= 0xe0000000 ) {
         above_4g_mem_size = ram_size - 0xe0000000;
@@ -802,9 +839,14 @@
             env->cpuid_features |= CPUID_APIC;
         }
         qemu_register_reset(main_cpu_reset, env);
+        cpu_resets[i] = qemu_allocate_irqs(main_cpu_reset_signal, env, 1);
         cpu_SIPI[i] = qemu_allocate_irqs(cpu_set_SIPI, env, MAX_SIPIS);
+        cpu_NMIs[i] = qemu_allocate_irqs(cpu_set_NMI, env, 1);
+        cpu_SMIs[i] = qemu_allocate_irqs(cpu_set_SMI, env, 1);
+        cpu_HWINTs[i] = qemu_allocate_irqs(cpu_set_HWINT, env, 1);
         if (pci_enabled) {
-            apic_init(env, cpu_SIPI[i]);
+            apic_init(env, cpu_SIPI[i], cpu_resets[i][0], cpu_NMIs[i][0],
+                      cpu_SMIs[i][0], cpu_HWINTs[i][0]);
         }
     }
 
Index: qemu/hw/pc.h
===================================================================
--- qemu.orig/hw/pc.h	2008-11-01 15:05:38.000000000 +0000
+++ qemu/hw/pc.h	2008-11-01 15:38:38.000000000 +0000
@@ -40,7 +40,8 @@
 /* APIC */
 typedef struct IOAPICState IOAPICState;
 
-int apic_init(CPUState *env, qemu_irq *cpu_SIPI);
+int apic_init(CPUState *env, qemu_irq *cpu_SIPI, qemu_irq cpu_reset,
+              qemu_irq cpu_NMI, qemu_irq cpu_SMI, qemu_irq cpu_HWINT);
 int apic_accept_pic_intr(CPUState *env);
 void apic_deliver_pic_intr(CPUState *env, int level);
 int apic_get_interrupt(CPUState *env);
