aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/apic.c
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@novell.com>2011-06-15 20:24:41 +0100
committerJan Beulich <jbeulich@novell.com>2011-06-15 20:24:41 +0100
commit1d4a5602fc8829350b9bd8d12870d44c3c342c61 (patch)
treeacf73fca9043fd816df3da8bc60ac5c828ff6941 /xen/arch/x86/apic.c
parented6229185f3a47d14e35d8f767aab0d01f7ffcaa (diff)
downloadxen-1d4a5602fc8829350b9bd8d12870d44c3c342c61.tar.gz
xen-1d4a5602fc8829350b9bd8d12870d44c3c342c61.tar.bz2
xen-1d4a5602fc8829350b9bd8d12870d44c3c342c61.zip
x86/apic: check maxlvt before accessing certain LVT fields
This follows Linux, including in not checking maxlvt for certain accesses to APIC_LVTERR. Signed-off-by: Jan Beulich <jbeulich@novell.com>
Diffstat (limited to 'xen/arch/x86/apic.c')
-rw-r--r--xen/arch/x86/apic.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/xen/arch/x86/apic.c b/xen/arch/x86/apic.c
index 31b8c0af84..3d4d5ccc5f 100644
--- a/xen/arch/x86/apic.c
+++ b/xen/arch/x86/apic.c
@@ -753,7 +753,8 @@ int lapic_suspend(void)
apic_pm_state.apic_dfr = apic_read(APIC_DFR);
apic_pm_state.apic_spiv = apic_read(APIC_SPIV);
apic_pm_state.apic_lvtt = apic_read(APIC_LVTT);
- apic_pm_state.apic_lvtpc = apic_read(APIC_LVTPC);
+ if (maxlvt >= 4)
+ apic_pm_state.apic_lvtpc = apic_read(APIC_LVTPC);
if (maxlvt >= 6) {
apic_pm_state.apic_lvtcmci = apic_read(APIC_CMCI);
@@ -764,7 +765,8 @@ int lapic_suspend(void)
apic_pm_state.apic_lvterr = apic_read(APIC_LVTERR);
apic_pm_state.apic_tmict = apic_read(APIC_TMICT);
apic_pm_state.apic_tdcr = apic_read(APIC_TDCR);
- apic_pm_state.apic_thmr = apic_read(APIC_LVTTHMR);
+ if (maxlvt >= 5)
+ apic_pm_state.apic_thmr = apic_read(APIC_LVTTHMR);
local_irq_save(flags);
disable_local_APIC();
@@ -800,6 +802,7 @@ int lapic_resume(void)
else
resume_x2apic();
+ maxlvt = get_maxlvt();
apic_write(APIC_LVTERR, ERROR_APIC_VECTOR | APIC_LVT_MASKED);
apic_write(APIC_ID, apic_pm_state.apic_id);
apic_write(APIC_DFR, apic_pm_state.apic_dfr);
@@ -808,14 +811,15 @@ int lapic_resume(void)
apic_write(APIC_SPIV, apic_pm_state.apic_spiv);
apic_write(APIC_LVT0, apic_pm_state.apic_lvt0);
apic_write(APIC_LVT1, apic_pm_state.apic_lvt1);
- apic_write(APIC_LVTTHMR, apic_pm_state.apic_thmr);
+ if (maxlvt >= 5)
+ apic_write(APIC_LVTTHMR, apic_pm_state.apic_thmr);
- maxlvt = get_maxlvt();
if (maxlvt >= 6) {
apic_write(APIC_CMCI, apic_pm_state.apic_lvtcmci);
}
- apic_write(APIC_LVTPC, apic_pm_state.apic_lvtpc);
+ if (maxlvt >= 4)
+ apic_write(APIC_LVTPC, apic_pm_state.apic_lvtpc);
apic_write(APIC_LVTT, apic_pm_state.apic_lvtt);
apic_write(APIC_TDCR, apic_pm_state.apic_tdcr);
apic_write(APIC_TMICT, apic_pm_state.apic_tmict);