summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2013-08-12 16:12:06 +1000
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2013-08-14 15:00:09 +1000
commit630573c1da54925290cf7a4f45752f3e9876d7e0 (patch)
treebd571325f769cc30f1a4e111e837ddf934bfadcf
parentd82fbf305c63d309d122d86a0714d1e8c572ec1b (diff)
downloadlinux-630573c1da54925290cf7a4f45752f3e9876d7e0.tar.bz2
powerpc: Fix denormalized exception handler
The denormalized exception handler (denorm_exception_hv) has a couple of bugs. If the CONFIG_PPC_DENORMALISATION option is not selected, or the HSRR1_DENORM bit is not set in HSRR1, we don't test whether the interrupt occurred within a KVM guest. On the other hand, if the HSRR1_DENORM bit is set and CONFIG_PPC_DENORMALISATION is enabled, we corrupt the CFAR and PPR. To correct these problems, this replaces the open-coded version of EXCEPTION_PROLOG_1 that is there currently, and that is missing the saving of PPR and CFAR values to the PACA, with an instance of EXCEPTION_PROLOG_1. This adds an explicit KVMTEST after testing whether the exception is one we can handle, and adds code to restore the CFAR on exit. Signed-off-by: Paul Mackerras <paulus@samba.org> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r--arch/powerpc/kernel/exceptions-64s.S11
1 files changed, 6 insertions, 5 deletions
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 4e00d223b2e3..2e00b268cfb7 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -367,11 +367,7 @@ denorm_exception_hv:
HMT_MEDIUM_PPR_DISCARD
mtspr SPRN_SPRG_HSCRATCH0,r13
EXCEPTION_PROLOG_0(PACA_EXGEN)
- std r11,PACA_EXGEN+EX_R11(r13)
- std r12,PACA_EXGEN+EX_R12(r13)
- mfspr r9,SPRN_SPRG_HSCRATCH0
- std r9,PACA_EXGEN+EX_R13(r13)
- mfcr r9
+ EXCEPTION_PROLOG_1(PACA_EXGEN, NOTEST, 0x1500)
#ifdef CONFIG_PPC_DENORMALISATION
mfspr r10,SPRN_HSRR1
@@ -381,6 +377,7 @@ denorm_exception_hv:
bne+ denorm_assist
#endif
+ KVMTEST(0x1500)
EXCEPTION_PROLOG_PSERIES_1(denorm_common, EXC_HV)
KVM_HANDLER_SKIP(PACA_EXGEN, EXC_STD, 0x1500)
@@ -501,6 +498,10 @@ denorm_done:
mtcrf 0x80,r9
ld r9,PACA_EXGEN+EX_R9(r13)
RESTORE_PPR_PACA(PACA_EXGEN, r10)
+BEGIN_FTR_SECTION
+ ld r10,PACA_EXGEN+EX_CFAR(r13)
+ mtspr SPRN_CFAR,r10
+END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
ld r10,PACA_EXGEN+EX_R10(r13)
ld r11,PACA_EXGEN+EX_R11(r13)
ld r12,PACA_EXGEN+EX_R12(r13)