Index: qemu/hw/apic.c
===================================================================
--- qemu.orig/hw/apic.c	2008-11-01 15:42:06.000000000 +0000
+++ qemu/hw/apic.c	2008-11-01 16:00:37.000000000 +0000
@@ -138,9 +138,8 @@
     tab[i] &= ~mask;
 }
 
-static void apic_local_deliver(CPUState *env, int vector)
+static void apic_local_deliver(APICState *s, int vector)
 {
-    APICState *s = env->apic_state;
     uint32_t lvt = s->lvt[vector];
     int trigger_mode;
 
@@ -169,12 +168,13 @@
     }
 }
 
-void apic_deliver_pic_intr(CPUState *env, int level)
+void apic_deliver_pic_intr(void *opaque, int level)
 {
+    APICState *s = opaque;
+
     if (level)
-        apic_local_deliver(env, APIC_LVT_LINT0);
+        apic_local_deliver(s, APIC_LVT_LINT0);
     else {
-        APICState *s = env->apic_state;
         uint32_t lvt = s->lvt[APIC_LVT_LINT0];
 
         switch ((lvt >> 8) & 7) {
@@ -267,9 +267,9 @@
                  apic_set_irq(apic_iter, vector_num, trigger_mode) );
 }
 
-void cpu_set_apic_base(CPUState *env, uint64_t val)
+void cpu_set_apic_base(void *opaque, uint64_t val)
 {
-    APICState *s = env->apic_state;
+    APICState *s = opaque;
 #ifdef DEBUG_APIC
     printf("cpu_set_apic_base: %016" PRIx64 "\n", val);
 #endif
@@ -278,30 +278,29 @@
     /* if disabled, cannot be enabled again */
     if (!(val & MSR_IA32_APICBASE_ENABLE)) {
         s->apicbase &= ~MSR_IA32_APICBASE_ENABLE;
-        env->cpuid_features &= ~CPUID_APIC;
         s->spurious_vec &= ~APIC_SV_ENABLE;
     }
 }
 
-uint64_t cpu_get_apic_base(CPUState *env)
+uint64_t cpu_get_apic_base(void *opaque)
 {
-    APICState *s = env->apic_state;
+    APICState *s = opaque;
 #ifdef DEBUG_APIC
     printf("cpu_get_apic_base: %016" PRIx64 "\n", (uint64_t)s->apicbase);
 #endif
     return s->apicbase;
 }
 
-void cpu_set_apic_tpr(CPUX86State *env, uint8_t val)
+void cpu_set_apic_tpr(void *opaque, uint8_t val)
 {
-    APICState *s = env->apic_state;
+    APICState *s = opaque;
     s->tpr = (val & 0x0f) << 4;
     apic_update_irq(s);
 }
 
-uint8_t cpu_get_apic_tpr(CPUX86State *env)
+uint8_t cpu_get_apic_tpr(void *opaque)
 {
-    APICState *s = env->apic_state;
+    APICState *s = opaque;
     return s->tpr >> 4;
 }
 
@@ -485,9 +484,9 @@
                      trigger_mode);
 }
 
-int apic_get_interrupt(CPUState *env)
+int apic_get_interrupt(void *opaque)
 {
-    APICState *s = env->apic_state;
+    APICState *s = opaque;
     int intno;
 
     /* if the APIC is installed or enabled, we let the 8259 handle the
@@ -509,9 +508,9 @@
     return intno;
 }
 
-int apic_accept_pic_intr(CPUState *env)
+int apic_accept_pic_intr(void *opaque)
 {
-    APICState *s = env->apic_state;
+    APICState *s = opaque;
     uint32_t lvt0;
 
     if (!s)
@@ -573,7 +572,7 @@
 {
     APICState *s = opaque;
 
-    apic_local_deliver(s->cpu_env, APIC_LVT_TIMER);
+    apic_local_deliver(s, APIC_LVT_TIMER);
     apic_timer_update(s, s->next_time);
 }
 
Index: qemu/hw/pc.c
===================================================================
--- qemu.orig/hw/pc.c	2008-11-01 15:42:06.000000000 +0000
+++ qemu/hw/pc.c	2008-11-01 15:51:58.000000000 +0000
@@ -104,7 +104,7 @@
 {
     int intno;
 
-    intno = apic_get_interrupt(env);
+    intno = apic_get_interrupt(env->apic_state);
     if (intno >= 0) {
         /* set irq request if a PIC irq is still pending */
         /* XXX: improve that */
@@ -112,7 +112,7 @@
         return intno;
     }
     /* read the irq from the PIC */
-    if (!apic_accept_pic_intr(env))
+    if (!apic_accept_pic_intr(env->apic_state))
         return -1;
 
     intno = pic_read_irq(isa_pic);
@@ -125,8 +125,8 @@
 
     if (env->apic_state) {
         while (env) {
-            if (apic_accept_pic_intr(env))
-                apic_deliver_pic_intr(env, level);
+            if (apic_accept_pic_intr(env->apic_state))
+                apic_deliver_pic_intr(env->apic_state, level);
             env = env->next_cpu;
         }
     } else {
Index: qemu/hw/pc.h
===================================================================
--- qemu.orig/hw/pc.h	2008-11-01 15:42:06.000000000 +0000
+++ qemu/hw/pc.h	2008-11-01 15:51:43.000000000 +0000
@@ -42,9 +42,9 @@
 
 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);
+int apic_accept_pic_intr(void *opaque);
+void apic_deliver_pic_intr(void *opaque, int level);
+int apic_get_interrupt(void *opaque);
 IOAPICState *ioapic_init(void);
 void ioapic_set_irq(void *opaque, int vector, int level);
 
Index: qemu/target-i386/cpu.h
===================================================================
--- qemu.orig/target-i386/cpu.h	2008-11-01 15:42:17.000000000 +0000
+++ qemu/target-i386/cpu.h	2008-11-01 16:00:00.000000000 +0000
@@ -612,7 +612,7 @@
 #endif
     /* in order to simplify APIC support, we leave this pointer to the
        user */
-    struct APICState *apic_state;
+    void *apic_state;
 } CPUX86State;
 
 CPUX86State *cpu_x86_init(const char *cpu_model);
@@ -712,11 +712,11 @@
 
 uint64_t cpu_get_tsc(CPUX86State *env);
 
-void cpu_set_apic_base(CPUX86State *env, uint64_t val);
-uint64_t cpu_get_apic_base(CPUX86State *env);
-void cpu_set_apic_tpr(CPUX86State *env, uint8_t val);
+void cpu_set_apic_base(void *opaque, uint64_t val);
+uint64_t cpu_get_apic_base(void *opaque);
+void cpu_set_apic_tpr(void *opaque, uint8_t val);
 #ifndef NO_CPU_IO_DEFS
-uint8_t cpu_get_apic_tpr(CPUX86State *env);
+uint8_t cpu_get_apic_tpr(void *opaque);
 #endif
 void cpu_smm_update(CPUX86State *env);
 
Index: qemu/target-i386/op_helper.c
===================================================================
--- qemu.orig/target-i386/op_helper.c	2008-11-01 15:54:47.000000000 +0000
+++ qemu/target-i386/op_helper.c	2008-11-01 16:01:14.000000000 +0000
@@ -3036,7 +3036,7 @@
         break;
     case 8:
         if (!(env->hflags2 & HF2_VINTR_MASK)) {
-            val = cpu_get_apic_tpr(env);
+            val = cpu_get_apic_tpr(env->apic_state);
         } else {
             val = env->v_tpr;
         }
@@ -3060,7 +3060,7 @@
         break;
     case 8:
         if (!(env->hflags2 & HF2_VINTR_MASK)) {
-            cpu_set_apic_tpr(env, t0);
+            cpu_set_apic_tpr(env->apic_state, t0);
         }
         env->v_tpr = t0 & 0x0f;
         break;
@@ -3150,7 +3150,9 @@
         env->sysenter_eip = val;
         break;
     case MSR_IA32_APICBASE:
-        cpu_set_apic_base(env, val);
+        cpu_set_apic_base(env->apic_state, val);
+        if (!(val & MSR_IA32_APICBASE_ENABLE))
+            env->cpuid_features &= ~CPUID_APIC;
         break;
     case MSR_EFER:
         {
@@ -3222,7 +3224,7 @@
         val = env->sysenter_eip;
         break;
     case MSR_IA32_APICBASE:
-        val = cpu_get_apic_base(env);
+        val = cpu_get_apic_base(env->apic_state);
         break;
     case MSR_EFER:
         val = env->efer;
