]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/commitdiff
powerpc: Base support for exceptions using HSRR0/1
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>
Tue, 5 Apr 2011 04:20:31 +0000 (14:20 +1000)
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>
Wed, 20 Apr 2011 01:03:22 +0000 (11:03 +1000)
Pass the register type to the prolog, also provides alternate "HV"
version of hardware interrupt (0x500) and adjust LPES accordingly

We tag those interrupts by setting bit 0x2 in the trap number

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
arch/powerpc/include/asm/exception-64s.h
arch/powerpc/include/asm/kvm_asm.h
arch/powerpc/include/asm/kvm_book3s_asm.h
arch/powerpc/kernel/cpu_setup_power7.S
arch/powerpc/kernel/exceptions-64s.S
arch/powerpc/kvm/book3s_rmhandlers.S
arch/powerpc/kvm/book3s_segment.S
arch/powerpc/platforms/iseries/exception.S
arch/powerpc/platforms/iseries/exception.h

index 337b6fa2f8cd6db48a6b72115d860e09cd532f33..1d98e05be51151ea0530e5b05cfb357c2fdfadba 100644 (file)
 #define LOAD_HANDLER(reg, label)                                       \
        addi    reg,reg,(label)-_stext; /* virt addr of handler ... */
 
-#define EXCEPTION_PROLOG_1(area)                                       \
+/* Exception register prefixes */
+#define EXC_HV H
+#define EXC_STD
+
+#define __EXCEPTION_PROLOG_1(area, h)                                  \
        GET_PACA(r13);                                                  \
        std     r9,area+EX_R9(r13);     /* save r9 - r12 */             \
        std     r10,area+EX_R10(r13);                                   \
        std     r11,area+EX_R11(r13);                                   \
        std     r12,area+EX_R12(r13);                                   \
-       mfspr   r9,SPRN_SPRG_SCRATCH0;                                  \
+       mfspr   r9,SPRN_SPRG_##h##SCRATCH0;                             \
        std     r9,area+EX_R13(r13);                                    \
        mfcr    r9
+#define EXCEPTION_PROLOG_1(area, h) __EXCEPTION_PROLOG_1(area, h)
 
-#define EXCEPTION_PROLOG_PSERIES_1(label)                              \
+#define __EXCEPTION_PROLOG_PSERIES_1(label, h)                         \
        ld      r12,PACAKBASE(r13);     /* get high part of &label */   \
        ld      r10,PACAKMSR(r13);      /* get MSR value for kernel */  \
-       mfspr   r11,SPRN_SRR0;          /* save SRR0 */                 \
+       mfspr   r11,SPRN_##h##SRR0;     /* save SRR0 */                 \
        LOAD_HANDLER(r12,label)                                         \
-       mtspr   SPRN_SRR0,r12;                                          \
-       mfspr   r12,SPRN_SRR1;          /* and SRR1 */                  \
-       mtspr   SPRN_SRR1,r10;                                          \
-       rfid;                                                           \
+       mtspr   SPRN_##h##SRR0,r12;                                     \
+       mfspr   r12,SPRN_##h##SRR1;     /* and SRR1 */                  \
+       mtspr   SPRN_##h##SRR1,r10;                                     \
+       h##rfid;                                                        \
        b       .       /* prevent speculative execution */
+#define EXCEPTION_PROLOG_PSERIES_1(label, h) \
+       __EXCEPTION_PROLOG_PSERIES_1(label, h)
 
-#define EXCEPTION_PROLOG_PSERIES(area, label)                          \
-       EXCEPTION_PROLOG_1(area);                                       \
-       EXCEPTION_PROLOG_PSERIES_1(label);
+#define EXCEPTION_PROLOG_PSERIES(area, label, h)                       \
+       EXCEPTION_PROLOG_1(area, h);                                    \
+       EXCEPTION_PROLOG_PSERIES_1(label, h);
 
 /*
  * The common exception prolog is used for all except a few exceptions
@@ -150,50 +157,44 @@ label##_pSeries:                                  \
        HMT_MEDIUM;                                     \
        DO_KVM  n;                                      \
        mtspr   SPRN_SPRG_SCRATCH0,r13;         /* save r13 */  \
-       EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
+       EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, EXC_STD)
 
 #define HSTD_EXCEPTION_PSERIES(n, label)               \
        . = n;                                          \
        .globl label##_pSeries;                         \
 label##_pSeries:                                       \
        HMT_MEDIUM;                                     \
-       mtspr   SPRN_SPRG_SCRATCH0,r20; /* save r20 */  \
-       mfspr   r20,SPRN_HSRR0;         /* copy HSRR0 to SRR0 */ \
-       mtspr   SPRN_SRR0,r20;                          \
-       mfspr   r20,SPRN_HSRR1;         /* copy HSRR0 to SRR0 */ \
-       mtspr   SPRN_SRR1,r20;                          \
-       mfspr   r20,SPRN_SPRG_SCRATCH0; /* restore r20 */ \
-       mtspr   SPRN_SPRG_SCRATCH0,r13;         /* save r13 */  \
-       EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
+       DO_KVM  n;                                      \
+       mtspr   SPRN_SPRG_HSCRATCH0,r13;/* save r13 */  \
+       EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, EXC_HV)
 
 
-#define MASKABLE_EXCEPTION_PSERIES(n, label)                           \
-       . = n;                                                          \
-       .globl label##_pSeries;                                         \
-label##_pSeries:                                                       \
+#define __MASKABLE_EXCEPTION_PSERIES(n, label, h)                      \
        HMT_MEDIUM;                                                     \
        DO_KVM  n;                                                      \
-       mtspr   SPRN_SPRG_SCRATCH0,r13; /* save r13 */                  \
+       mtspr   SPRN_SPRG_##h##SCRATCH0,r13;    /* save r13 */          \
        GET_PACA(r13);                                                  \
        std     r9,PACA_EXGEN+EX_R9(r13);       /* save r9, r10 */      \
        std     r10,PACA_EXGEN+EX_R10(r13);                             \
        lbz     r10,PACASOFTIRQEN(r13);                                 \
        mfcr    r9;                                                     \
        cmpwi   r10,0;                                                  \
-       beq     masked_interrupt;                                       \
-       mfspr   r10,SPRN_SPRG_SCRATCH0;                                 \
+       beq     masked_##h##interrupt;                                  \
+       mfspr   r10,SPRN_SPRG_##h##SCRATCH0;                            \
        std     r10,PACA_EXGEN+EX_R13(r13);                             \
        std     r11,PACA_EXGEN+EX_R11(r13);                             \
        std     r12,PACA_EXGEN+EX_R12(r13);                             \
        ld      r12,PACAKBASE(r13);     /* get high part of &label */   \
        ld      r10,PACAKMSR(r13);      /* get MSR value for kernel */  \
-       mfspr   r11,SPRN_SRR0;          /* save SRR0 */                 \
+       mfspr   r11,SPRN_##h##SRR0;     /* save SRR0 */                 \
        LOAD_HANDLER(r12,label##_common)                                \
-       mtspr   SPRN_SRR0,r12;                                          \
-       mfspr   r12,SPRN_SRR1;          /* and SRR1 */                  \
-       mtspr   SPRN_SRR1,r10;                                          \
-       rfid;                                                           \
+       mtspr   SPRN_##h##SRR0,r12;                                     \
+       mfspr   r12,SPRN_##h##SRR1;     /* and SRR1 */                  \
+       mtspr   SPRN_##h##SRR1,r10;                                     \
+       h##rfid;                                                        \
        b       .       /* prevent speculative execution */
+#define MASKABLE_EXCEPTION_PSERIES(n, label, h)                                \
+       __MASKABLE_EXCEPTION_PSERIES(n, label, h)
 
 #ifdef CONFIG_PPC_ISERIES
 #define DISABLE_INTS                           \
index 5b75046743975704a01f6e612b80867d64796c84..0951b17f4eb57dfc22b3afa5101da671dea0d0c5 100644 (file)
@@ -59,6 +59,7 @@
 #define BOOK3S_INTERRUPT_INST_SEGMENT  0x480
 #define BOOK3S_INTERRUPT_EXTERNAL      0x500
 #define BOOK3S_INTERRUPT_EXTERNAL_LEVEL        0x501
+#define BOOK3S_INTERRUPT_EXTERNAL_HV   0x502
 #define BOOK3S_INTERRUPT_ALIGNMENT     0x600
 #define BOOK3S_INTERRUPT_PROGRAM       0x700
 #define BOOK3S_INTERRUPT_FP_UNAVAIL    0x800
index 36fdb3aff30ba938a4288b774e087af456d60313..d5a8a3861635c3add04a50644a8161d558b455ac 100644 (file)
@@ -34,6 +34,7 @@
            (\intno == BOOK3S_INTERRUPT_DATA_SEGMENT) || \
            (\intno == BOOK3S_INTERRUPT_INST_SEGMENT) || \
            (\intno == BOOK3S_INTERRUPT_EXTERNAL) || \
+           (\intno == BOOK3S_INTERRUPT_EXTERNAL_HV) || \
            (\intno == BOOK3S_INTERRUPT_ALIGNMENT) || \
            (\intno == BOOK3S_INTERRUPT_PROGRAM) || \
            (\intno == BOOK3S_INTERRUPT_FP_UNAVAIL) || \
index f2b317817c4ea844d2d93a2e3110dd6588f2bec4..e801ef15d6d0a8ad3004aba7d57d46f1d292b4f3 100644 (file)
@@ -52,13 +52,14 @@ __init_hvmode_206:
 __init_LPCR:
        /* Setup a sane LPCR:
         *
-        *   LPES = 0b11 (SRR0/1 used for 0x500)
+        *   LPES = 0b01 (HSRR0/1 used for 0x500)
         *   PECE = 0b111
         *
         * Other bits untouched for now
         */
        mfspr   r3,SPRN_LPCR
        ori     r3,r3,(LPCR_LPES0|LPCR_LPES1)
+       xori    r3,r3, LPCR_LPES0
        ori     r3,r3,(LPCR_PECE0|LPCR_PECE1|LPCR_PECE2)
        mtspr   SPRN_LPCR,r3
        isync
index 6784bf7090f6cbe0f4d72162fa7c9b4f461c520c..17f1d6670635013a74f0359eefe297b878c8236b 100644 (file)
@@ -44,7 +44,7 @@ _machine_check_pSeries:
        HMT_MEDIUM
        DO_KVM  0x200
        mtspr   SPRN_SPRG_SCRATCH0,r13          /* save r13 */
-       EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
+       EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common, EXC_STD)
 
        . = 0x300
        .globl data_access_pSeries
@@ -71,9 +71,9 @@ BEGIN_FTR_SECTION
        std     r10,PACA_EXGEN+EX_R10(r13)
        std     r11,PACA_EXGEN+EX_R9(r13)
        std     r12,PACA_EXGEN+EX_R13(r13)
-       EXCEPTION_PROLOG_PSERIES_1(data_access_common)
+       EXCEPTION_PROLOG_PSERIES_1(data_access_common, EXC_STD)
 FTR_SECTION_ELSE
-       EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, data_access_common)
+       EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, data_access_common, EXC_STD)
 ALT_FTR_SECTION_END_IFCLR(CPU_FTR_SLB)
 
        . = 0x380
@@ -147,11 +147,24 @@ instruction_access_slb_pSeries:
        bctr
 #endif
 
-       MASKABLE_EXCEPTION_PSERIES(0x500, hardware_interrupt)
+       . = 0x500;
+       .globl hardware_interrupt_pSeries
+hardware_interrupt_pSeries:
+       BEGIN_FTR_SECTION
+       MASKABLE_EXCEPTION_PSERIES(0x500, hardware_interrupt, EXC_STD)
+       FTR_SECTION_ELSE
+       MASKABLE_EXCEPTION_PSERIES(0x502, hardware_interrupt, EXC_HV)
+       ALT_FTR_SECTION_END_IFCLR(CPU_FTR_HVMODE_206)
+
        STD_EXCEPTION_PSERIES(0x600, alignment)
        STD_EXCEPTION_PSERIES(0x700, program_check)
        STD_EXCEPTION_PSERIES(0x800, fp_unavailable)
-       MASKABLE_EXCEPTION_PSERIES(0x900, decrementer)
+
+       . = 0x900;
+       .globl decrementer_pSeries
+decrementer_pSeries:
+       MASKABLE_EXCEPTION_PSERIES(0x900, decrementer, EXC_STD)
+
        STD_EXCEPTION_PSERIES(0xa00, trap_0a)
        STD_EXCEPTION_PSERIES(0xb00, trap_0b)
 
@@ -207,15 +220,15 @@ vsx_unavailable_pSeries_1:
        b       vsx_unavailable_pSeries
 
 #ifdef CONFIG_CBE_RAS
-       HSTD_EXCEPTION_PSERIES(0x1200, cbe_system_error)
+       HSTD_EXCEPTION_PSERIES(0x1202, cbe_system_error)
 #endif /* CONFIG_CBE_RAS */
        STD_EXCEPTION_PSERIES(0x1300, instruction_breakpoint)
 #ifdef CONFIG_CBE_RAS
-       HSTD_EXCEPTION_PSERIES(0x1600, cbe_maintenance)
+       HSTD_EXCEPTION_PSERIES(0x1602, cbe_maintenance)
 #endif /* CONFIG_CBE_RAS */
        STD_EXCEPTION_PSERIES(0x1700, altivec_assist)
 #ifdef CONFIG_CBE_RAS
-       HSTD_EXCEPTION_PSERIES(0x1800, cbe_thermal)
+       HSTD_EXCEPTION_PSERIES(0x1802, cbe_thermal)
 #endif /* CONFIG_CBE_RAS */
 
        . = 0x3000
@@ -244,13 +257,26 @@ masked_interrupt:
        rfid
        b       .
 
+masked_Hinterrupt:
+       stb     r10,PACAHARDIRQEN(r13)
+       mtcrf   0x80,r9
+       ld      r9,PACA_EXGEN+EX_R9(r13)
+       mfspr   r10,SPRN_HSRR1
+       rldicl  r10,r10,48,1            /* clear MSR_EE */
+       rotldi  r10,r10,16
+       mtspr   SPRN_HSRR1,r10
+       ld      r10,PACA_EXGEN+EX_R10(r13)
+       mfspr   r13,SPRN_SPRG_HSCRATCH0
+       hrfid
+       b       .
+
        .align  7
 do_stab_bolted_pSeries:
        std     r11,PACA_EXSLB+EX_R11(r13)
        std     r12,PACA_EXSLB+EX_R12(r13)
        mfspr   r10,SPRN_SPRG_SCRATCH0
        std     r10,PACA_EXSLB+EX_R13(r13)
-       EXCEPTION_PROLOG_PSERIES_1(.do_stab_bolted)
+       EXCEPTION_PROLOG_PSERIES_1(.do_stab_bolted, EXC_STD)
 
 #ifdef CONFIG_PPC_PSERIES
 /*
@@ -261,14 +287,14 @@ do_stab_bolted_pSeries:
 system_reset_fwnmi:
        HMT_MEDIUM
        mtspr   SPRN_SPRG_SCRATCH0,r13          /* save r13 */
-       EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common)
+       EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common, EXC_STD)
 
        .globl machine_check_fwnmi
       .align 7
 machine_check_fwnmi:
        HMT_MEDIUM
        mtspr   SPRN_SPRG_SCRATCH0,r13          /* save r13 */
-       EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
+       EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common, EXC_STD)
 
 #endif /* CONFIG_PPC_PSERIES */
 
index b0ff5ff76e25ba2495e516d8652b074904f1e727..046e1f3d44327ac00adeebbd2dae31ff5b60db26 100644 (file)
@@ -112,6 +112,7 @@ INTERRUPT_TRAMPOLINE        BOOK3S_INTERRUPT_MACHINE_CHECK
 INTERRUPT_TRAMPOLINE   BOOK3S_INTERRUPT_DATA_STORAGE
 INTERRUPT_TRAMPOLINE   BOOK3S_INTERRUPT_INST_STORAGE
 INTERRUPT_TRAMPOLINE   BOOK3S_INTERRUPT_EXTERNAL
+INTERRUPT_TRAMPOLINE   BOOK3S_INTERRUPT_EXTERNAL_HV
 INTERRUPT_TRAMPOLINE   BOOK3S_INTERRUPT_ALIGNMENT
 INTERRUPT_TRAMPOLINE   BOOK3S_INTERRUPT_PROGRAM
 INTERRUPT_TRAMPOLINE   BOOK3S_INTERRUPT_FP_UNAVAIL
index 7c52ed0b7051b5748fe3c943c60de5ff18b616b2..d842795d0f23d0753d0b3946ade749be8409020e 100644 (file)
@@ -155,9 +155,15 @@ kvmppc_handler_trampoline_exit:
        PPC_LL  r2, (SHADOW_VCPU_OFF + SVCPU_HOST_R2)(r13)
 
        /* Save guest PC and MSR */
-       mfsrr0  r3
+       andi.   r0,r12,0x2
+       beq     1f
+       mfspr   r3,SPRN_HSRR0
+       mfspr   r4,SPRN_HSRR1
+       andi.   r12,r12,0x3ffd
+       b       2f
+1:     mfsrr0  r3
        mfsrr1  r4
-
+2:
        PPC_STL r3, (SHADOW_VCPU_OFF + SVCPU_PC)(r13)
        PPC_STL r4, (SHADOW_VCPU_OFF + SVCPU_SHADOW_SRR1)(r13)
 
index 32a56c6dfa72b03c1e5c51b3b5680e92f1315c6d..f7a487231a11206ae0cb39ba18449fd16bec5867 100644 (file)
@@ -155,7 +155,7 @@ BEGIN_FTR_SECTION
        std     r12,PACA_EXGEN+EX_R13(r13)
        EXCEPTION_PROLOG_ISERIES_1
 FTR_SECTION_ELSE
-       EXCEPTION_PROLOG_1(PACA_EXGEN)
+       EXCEPTION_PROLOG_1(PACA_EXGEN, EXC_STD)
        EXCEPTION_PROLOG_ISERIES_1
 ALT_FTR_SECTION_END_IFCLR(CPU_FTR_SLB)
        b       data_access_common
index bae3fba5ad8efdedd24bd7613ad45fe3cd47fc36..57127d805fe3a218fc274cbf6c0afcaea54e59bd 100644 (file)
@@ -39,7 +39,7 @@
 label##_iSeries:                                                       \
        HMT_MEDIUM;                                                     \
        mtspr   SPRN_SPRG_SCRATCH0,r13; /* save r13 */                  \
-       EXCEPTION_PROLOG_1(area);                                       \
+       EXCEPTION_PROLOG_1(area, EXC_STD);                              \
        EXCEPTION_PROLOG_ISERIES_1;                                     \
        b       label##_common
 
@@ -48,7 +48,7 @@ label##_iSeries:                                                      \
 label##_iSeries:                                                       \
        HMT_MEDIUM;                                                     \
        mtspr   SPRN_SPRG_SCRATCH0,r13; /* save r13 */                  \
-       EXCEPTION_PROLOG_1(PACA_EXGEN);                                 \
+       EXCEPTION_PROLOG_1(PACA_EXGEN, EXC_STD);                        \
        lbz     r10,PACASOFTIRQEN(r13);                                 \
        cmpwi   0,r10,0;                                                \
        beq-    label##_iSeries_masked;                                 \