aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/apic.c
diff options
context:
space:
mode:
authorAndrew Cooper <andrew.cooper3@citrix.com>2011-06-15 16:16:41 +0100
committerAndrew Cooper <andrew.cooper3@citrix.com>2011-06-15 16:16:41 +0100
commit2de77fa3cdbc08f76942db9bcf38dc6885cb4786 (patch)
tree4fe9cb641aa95fe477c2ec5a9b1cc4f7d0edc559 /xen/arch/x86/apic.c
parentf6239c2a1e56e2795effe44fcf88467c501ca9d0 (diff)
downloadxen-2de77fa3cdbc08f76942db9bcf38dc6885cb4786.tar.gz
xen-2de77fa3cdbc08f76942db9bcf38dc6885cb4786.tar.bz2
xen-2de77fa3cdbc08f76942db9bcf38dc6885cb4786.zip
KEXEC: correctly revert x2apic state when kexecing
Introduce the boolean variable 'kexecing' which indicates to functions whether we are on the kexec path or not. This is used by disable_local_APIC() to try and revert the APIC mode back to how it was found on boot. We also need some fudging of the x2apic_enabled variable. It is used in multiple places over the codebase to mean multiple things, including: What did the user specifify on the command line? Did the BIOS boot me in x2apic mode? Is the BSP Local APIC in x2apic mode? What mode is my Local APIC in? Therefore, set it up to prevent a protection fault when disabling the IOAPICs. (In this case, it is used in the "What mode is my Local APIC in?" case, so the processor doesnt suffer a protection fault because of trying to use x2apic MSRs when it should be using xapic MMIO) Finally, make sure that interrupts are disabled when jumping into the purgatory code. It would be bad to service interrupts in the Xen context when the next kernel is booting. Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Diffstat (limited to 'xen/arch/x86/apic.c')
-rw-r--r--xen/arch/x86/apic.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/xen/arch/x86/apic.c b/xen/arch/x86/apic.c
index 78b3595119..31b8c0af84 100644
--- a/xen/arch/x86/apic.c
+++ b/xen/arch/x86/apic.c
@@ -37,6 +37,7 @@
#include <asm/asm_defns.h> /* for BUILD_SMP_INTERRUPT */
#include <mach_apic.h>
#include <io_ports.h>
+#include <xen/kexec.h>
static bool_t tdt_enabled __read_mostly;
static bool_t tdt_enable __initdata = 1;
@@ -349,6 +350,33 @@ void disable_local_APIC(void)
wrmsrl(MSR_IA32_APICBASE, msr_content &
~(MSR_IA32_APICBASE_ENABLE|MSR_IA32_APICBASE_EXTD));
}
+
+ if ( kexecing )
+ {
+ uint64_t msr_content;
+ rdmsrl(MSR_IA32_APICBASE, msr_content);
+ msr_content &= ~(MSR_IA32_APICBASE_ENABLE|MSR_IA32_APICBASE_EXTD);
+ wrmsrl(MSR_IA32_APICBASE, msr_content);
+
+ switch ( apic_boot_mode )
+ {
+ case APIC_MODE_DISABLED:
+ break; /* Nothing to do - we did this above */
+ case APIC_MODE_XAPIC:
+ msr_content |= MSR_IA32_APICBASE_ENABLE;
+ wrmsrl(MSR_IA32_APICBASE, msr_content);
+ break;
+ case APIC_MODE_X2APIC:
+ msr_content |= (MSR_IA32_APICBASE_ENABLE|MSR_IA32_APICBASE_EXTD);
+ wrmsrl(MSR_IA32_APICBASE, msr_content);
+ break;
+ default:
+ printk("Default case when reverting #%d lapic to boot state\n",
+ smp_processor_id());
+ break;
+ }
+ }
+
}
/*