diff options
author | Michael Ellerman <michael@ellerman.id.au> | 2013-06-25 03:47:57 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-07-25 17:07:21 -0400 |
commit | d24966cf890f3b22e379654ba70a38ad9a67d9db (patch) | |
tree | 43da9c4a5d536298c9434153b8f30b5f306fb0bd /arch/powerpc/kernel | |
parent | 8e0af91a12c135f6c22e472660f3400d46ed78ac (diff) |
powerpc: Wire up the HV facility unavailable exception
commit b14b6260efeee6eb8942c6e6420e31281892acb6 upstream.
Similar to the facility unavailble exception, except the facilities are
controlled by HFSCR.
Adapt the facility_unavailable_exception() so it can be called for
either the regular or Hypervisor facility unavailable exceptions.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r-- | arch/powerpc/kernel/exceptions-64s.S | 15 | ||||
-rw-r--r-- | arch/powerpc/kernel/traps.c | 16 |
2 files changed, 27 insertions, 4 deletions
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index d55a63c3559a..4e00d223b2e3 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S | |||
@@ -347,6 +347,12 @@ facility_unavailable_trampoline: | |||
347 | EXCEPTION_PROLOG_0(PACA_EXGEN) | 347 | EXCEPTION_PROLOG_0(PACA_EXGEN) |
348 | b facility_unavailable_pSeries | 348 | b facility_unavailable_pSeries |
349 | 349 | ||
350 | hv_facility_unavailable_trampoline: | ||
351 | . = 0xf80 | ||
352 | SET_SCRATCH0(r13) | ||
353 | EXCEPTION_PROLOG_0(PACA_EXGEN) | ||
354 | b facility_unavailable_hv | ||
355 | |||
350 | #ifdef CONFIG_CBE_RAS | 356 | #ifdef CONFIG_CBE_RAS |
351 | STD_EXCEPTION_HV(0x1200, 0x1202, cbe_system_error) | 357 | STD_EXCEPTION_HV(0x1200, 0x1202, cbe_system_error) |
352 | KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0x1202) | 358 | KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0x1202) |
@@ -525,6 +531,8 @@ denorm_done: | |||
525 | KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xf40) | 531 | KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xf40) |
526 | STD_EXCEPTION_PSERIES_OOL(0xf60, facility_unavailable) | 532 | STD_EXCEPTION_PSERIES_OOL(0xf60, facility_unavailable) |
527 | KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xf60) | 533 | KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0xf60) |
534 | STD_EXCEPTION_HV_OOL(0xf82, facility_unavailable) | ||
535 | KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xf82) | ||
528 | 536 | ||
529 | /* | 537 | /* |
530 | * An interrupt came in while soft-disabled. We set paca->irq_happened, then: | 538 | * An interrupt came in while soft-disabled. We set paca->irq_happened, then: |
@@ -836,6 +844,12 @@ facility_unavailable_relon_trampoline: | |||
836 | EXCEPTION_PROLOG_0(PACA_EXGEN) | 844 | EXCEPTION_PROLOG_0(PACA_EXGEN) |
837 | b facility_unavailable_relon_pSeries | 845 | b facility_unavailable_relon_pSeries |
838 | 846 | ||
847 | hv_facility_unavailable_relon_trampoline: | ||
848 | . = 0x4f80 | ||
849 | SET_SCRATCH0(r13) | ||
850 | EXCEPTION_PROLOG_0(PACA_EXGEN) | ||
851 | b facility_unavailable_relon_hv | ||
852 | |||
839 | STD_RELON_EXCEPTION_PSERIES(0x5300, 0x1300, instruction_breakpoint) | 853 | STD_RELON_EXCEPTION_PSERIES(0x5300, 0x1300, instruction_breakpoint) |
840 | #ifdef CONFIG_PPC_DENORMALISATION | 854 | #ifdef CONFIG_PPC_DENORMALISATION |
841 | . = 0x5500 | 855 | . = 0x5500 |
@@ -1174,6 +1188,7 @@ __end_handlers: | |||
1174 | STD_RELON_EXCEPTION_PSERIES_OOL(0xf20, altivec_unavailable) | 1188 | STD_RELON_EXCEPTION_PSERIES_OOL(0xf20, altivec_unavailable) |
1175 | STD_RELON_EXCEPTION_PSERIES_OOL(0xf40, vsx_unavailable) | 1189 | STD_RELON_EXCEPTION_PSERIES_OOL(0xf40, vsx_unavailable) |
1176 | STD_RELON_EXCEPTION_PSERIES_OOL(0xf60, facility_unavailable) | 1190 | STD_RELON_EXCEPTION_PSERIES_OOL(0xf60, facility_unavailable) |
1191 | STD_RELON_EXCEPTION_HV_OOL(0xf80, facility_unavailable) | ||
1177 | 1192 | ||
1178 | #if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV) | 1193 | #if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV) |
1179 | /* | 1194 | /* |
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 2053bbd26a06..e4f205a209d2 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c | |||
@@ -1295,10 +1295,18 @@ void facility_unavailable_exception(struct pt_regs *regs) | |||
1295 | "EBB", | 1295 | "EBB", |
1296 | "TAR", | 1296 | "TAR", |
1297 | }; | 1297 | }; |
1298 | char *facility; | 1298 | char *facility, *prefix; |
1299 | u64 value; | 1299 | u64 value; |
1300 | 1300 | ||
1301 | value = mfspr(SPRN_FSCR) >> 56; | 1301 | if (regs->trap == 0xf60) { |
1302 | value = mfspr(SPRN_FSCR); | ||
1303 | prefix = ""; | ||
1304 | } else { | ||
1305 | value = mfspr(SPRN_HFSCR); | ||
1306 | prefix = "Hypervisor "; | ||
1307 | } | ||
1308 | |||
1309 | value = value >> 56; | ||
1302 | 1310 | ||
1303 | /* We restore the interrupt state now */ | 1311 | /* We restore the interrupt state now */ |
1304 | if (!arch_irq_disabled_regs(regs)) | 1312 | if (!arch_irq_disabled_regs(regs)) |
@@ -1309,8 +1317,8 @@ void facility_unavailable_exception(struct pt_regs *regs) | |||
1309 | else | 1317 | else |
1310 | facility = "unknown"; | 1318 | facility = "unknown"; |
1311 | 1319 | ||
1312 | pr_err("Facility '%s' unavailable, exception at 0x%lx, MSR=%lx\n", | 1320 | pr_err("%sFacility '%s' unavailable, exception at 0x%lx, MSR=%lx\n", |
1313 | facility, regs->nip, regs->msr); | 1321 | prefix, facility, regs->nip, regs->msr); |
1314 | 1322 | ||
1315 | if (user_mode(regs)) { | 1323 | if (user_mode(regs)) { |
1316 | _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); | 1324 | _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); |