powerpc, KVM: Split HVMODE_206 cpu feature bit into separate HV and architecture...
authorPaul Mackerras <paulus@samba.org>
Wed, 29 Jun 2011 00:26:11 +0000 (00:26 +0000)
committerAvi Kivity <avi@redhat.com>
Tue, 12 Jul 2011 10:16:58 +0000 (13:16 +0300)
This replaces the single CPU_FTR_HVMODE_206 bit with two bits, one to
indicate that we have a usable hypervisor mode, and another to indicate
that the processor conforms to PowerISA version 2.06.  We also add
another bit to indicate that the processor conforms to ISA version 2.01
and set that for PPC970 and derivatives.

Some PPC970 chips (specifically those in Apple machines) have a
hypervisor mode in that MSR[HV] is always 1, but the hypervisor mode
is not useful in the sense that there is no way to run any code in
supervisor mode (HV=0 PR=0).  On these processors, the LPES0 and LPES1
bits in HID4 are always 0, and we use that as a way of detecting that
hypervisor mode is not useful.

Where we have a feature section in assembly code around code that
only applies on POWER7 in hypervisor mode, we use a construct like

END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)

The definition of END_FTR_SECTION_IFSET is such that the code will
be enabled (not overwritten with nops) only if all bits in the
provided mask are set.

Note that the CPU feature check in __tlbie() only needs to check the
ARCH_206 bit, not the HVMODE bit, because __tlbie() can only get called
if we are running bare-metal, i.e. in hypervisor mode.

Signed-off-by: Paul Mackerras <paulus@samba.org>
Signed-off-by: Alexander Graf <agraf@suse.de>
arch/powerpc/include/asm/cputable.h
arch/powerpc/include/asm/reg.h
arch/powerpc/kernel/cpu_setup_power7.S
arch/powerpc/kernel/cpu_setup_ppc970.S
arch/powerpc/kernel/exceptions-64s.S
arch/powerpc/kernel/paca.c
arch/powerpc/kvm/book3s_64_mmu_hv.c
arch/powerpc/kvm/book3s_hv.c
arch/powerpc/kvm/book3s_hv_builtin.c
arch/powerpc/kvm/book3s_segment.S
arch/powerpc/mm/hash_native_64.c

index c0d842cfd012c7cf8f2469c2548ee6dca22e3469..e30442c539ce4b809bbbed925faac847a817554a 100644 (file)
@@ -179,8 +179,9 @@ extern const char *powerpc_base_platform;
 #define LONG_ASM_CONST(x)              0
 #endif
 
-
-#define CPU_FTR_HVMODE_206             LONG_ASM_CONST(0x0000000800000000)
+#define CPU_FTR_HVMODE                 LONG_ASM_CONST(0x0000000200000000)
+#define CPU_FTR_ARCH_201               LONG_ASM_CONST(0x0000000400000000)
+#define CPU_FTR_ARCH_206               LONG_ASM_CONST(0x0000000800000000)
 #define CPU_FTR_CFAR                   LONG_ASM_CONST(0x0000001000000000)
 #define CPU_FTR_IABR                   LONG_ASM_CONST(0x0000002000000000)
 #define CPU_FTR_MMCRA                  LONG_ASM_CONST(0x0000004000000000)
@@ -401,9 +402,10 @@ extern const char *powerpc_base_platform;
            CPU_FTR_MMCRA | CPU_FTR_CP_USE_DCBTZ | \
            CPU_FTR_STCX_CHECKS_ADDRESS)
 #define CPU_FTRS_PPC970        (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
-           CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
+           CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | CPU_FTR_ARCH_201 | \
            CPU_FTR_ALTIVEC_COMP | CPU_FTR_CAN_NAP | CPU_FTR_MMCRA | \
-           CPU_FTR_CP_USE_DCBTZ | CPU_FTR_STCX_CHECKS_ADDRESS)
+           CPU_FTR_CP_USE_DCBTZ | CPU_FTR_STCX_CHECKS_ADDRESS | \
+           CPU_FTR_HVMODE)
 #define CPU_FTRS_POWER5        (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
            CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
            CPU_FTR_MMCRA | CPU_FTR_SMT | \
@@ -417,13 +419,13 @@ extern const char *powerpc_base_platform;
            CPU_FTR_DSCR | CPU_FTR_UNALIGNED_LD_STD | \
            CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_CFAR)
 #define CPU_FTRS_POWER7 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
-           CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | CPU_FTR_HVMODE_206 |\
+           CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | CPU_FTR_ARCH_206 |\
            CPU_FTR_MMCRA | CPU_FTR_SMT | \
            CPU_FTR_COHERENT_ICACHE | \
            CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \
            CPU_FTR_DSCR | CPU_FTR_SAO  | CPU_FTR_ASYM_SMT | \
            CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
-           CPU_FTR_ICSWX | CPU_FTR_CFAR)
+           CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE)
 #define CPU_FTRS_CELL  (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
            CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
            CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
index 20a053c14270b123ca74d2a0c3951c053c4de8ea..ddbe57ae858420c47bfd9c13f687e2ec166de851 100644 (file)
 #define SPRN_HASH1     0x3D2           /* Primary Hash Address Register */
 #define SPRN_HASH2     0x3D3           /* Secondary Hash Address Resgister */
 #define SPRN_HID0      0x3F0           /* Hardware Implementation Register 0 */
+#define HID0_HDICE_SH  (63 - 23)       /* 970 HDEC interrupt enable */
 #define HID0_EMCP      (1<<31)         /* Enable Machine Check pin */
 #define HID0_EBA       (1<<29)         /* Enable Bus Address Parity */
 #define HID0_EBD       (1<<28)         /* Enable Bus Data Parity */
 #define SPRN_IABR2     0x3FA           /* 83xx */
 #define SPRN_IBCR      0x135           /* 83xx Insn Breakpoint Control Reg */
 #define SPRN_HID4      0x3F4           /* 970 HID4 */
+#define  HID4_LPES0     (1ul << (63-0)) /* LPAR env. sel. bit 0 */
+#define         HID4_RMLS2_SH   (63 - 2)       /* Real mode limit bottom 2 bits */
+#define         HID4_LPID5_SH   (63 - 6)       /* partition ID bottom 4 bits */
+#define         HID4_RMOR_SH    (63 - 22)      /* real mode offset (16 bits) */
+#define  HID4_LPES1     (1 << (63-57)) /* LPAR env. sel. bit 1 */
+#define  HID4_RMLS0_SH  (63 - 58)      /* Real mode limit top bit */
+#define         HID4_LPID1_SH   0              /* partition ID top 2 bits */
 #define SPRN_HID4_GEKKO        0x3F3           /* Gekko HID4 */
 #define SPRN_HID5      0x3F6           /* 970 HID5 */
 #define SPRN_HID6      0x3F9   /* BE HID 6 */
        mfspr   rX,SPRN_SPRG_PACA;                      \
        FTR_SECTION_ELSE_NESTED(66);                    \
        mfspr   rX,SPRN_SPRG_HPACA;                     \
-       ALT_FTR_SECTION_END_NESTED_IFCLR(CPU_FTR_HVMODE_206, 66)
+       ALT_FTR_SECTION_END_NESTED_IFCLR(CPU_FTR_HVMODE, 66)
 
 #define SET_PACA(rX)                                   \
        BEGIN_FTR_SECTION_NESTED(66);                   \
        mtspr   SPRN_SPRG_PACA,rX;                      \
        FTR_SECTION_ELSE_NESTED(66);                    \
        mtspr   SPRN_SPRG_HPACA,rX;                     \
-       ALT_FTR_SECTION_END_NESTED_IFCLR(CPU_FTR_HVMODE_206, 66)
+       ALT_FTR_SECTION_END_NESTED_IFCLR(CPU_FTR_HVMODE, 66)
 
 #define GET_SCRATCH0(rX)                               \
        BEGIN_FTR_SECTION_NESTED(66);                   \
        mfspr   rX,SPRN_SPRG_SCRATCH0;                  \
        FTR_SECTION_ELSE_NESTED(66);                    \
        mfspr   rX,SPRN_SPRG_HSCRATCH0;                 \
-       ALT_FTR_SECTION_END_NESTED_IFCLR(CPU_FTR_HVMODE_206, 66)
+       ALT_FTR_SECTION_END_NESTED_IFCLR(CPU_FTR_HVMODE, 66)
 
 #define SET_SCRATCH0(rX)                               \
        BEGIN_FTR_SECTION_NESTED(66);                   \
        mtspr   SPRN_SPRG_SCRATCH0,rX;                  \
        FTR_SECTION_ELSE_NESTED(66);                    \
        mtspr   SPRN_SPRG_HSCRATCH0,rX;                 \
-       ALT_FTR_SECTION_END_NESTED_IFCLR(CPU_FTR_HVMODE_206, 66)
+       ALT_FTR_SECTION_END_NESTED_IFCLR(CPU_FTR_HVMODE, 66)
 
 #else /* CONFIG_PPC_BOOK3S_64 */
 #define GET_SCRATCH0(rX)       mfspr   rX,SPRN_SPRG_SCRATCH0
index 2ef6749688e9299d4304b06b16ee77b00f4321e6..76797c5105d6f2e930da0fe6c639e26247d40515 100644 (file)
@@ -45,12 +45,12 @@ _GLOBAL(__restore_cpu_power7)
        blr
 
 __init_hvmode_206:
-       /* Disable CPU_FTR_HVMODE_206 and exit if MSR:HV is not set */
+       /* Disable CPU_FTR_HVMODE and exit if MSR:HV is not set */
        mfmsr   r3
        rldicl. r0,r3,4,63
        bnelr
        ld      r5,CPU_SPEC_FEATURES(r4)
-       LOAD_REG_IMMEDIATE(r6,CPU_FTR_HVMODE_206)
+       LOAD_REG_IMMEDIATE(r6,CPU_FTR_HVMODE)
        xor     r5,r5,r6
        std     r5,CPU_SPEC_FEATURES(r4)
        blr
index 27f2507279d830571fcecd0aa4e13c8a41d81062..12fac8df01c53172c6a8251845c83ed9c16f163a 100644 (file)
@@ -76,7 +76,7 @@ _GLOBAL(__setup_cpu_ppc970)
        /* Do nothing if not running in HV mode */
        mfmsr   r0
        rldicl. r0,r0,4,63
-       beqlr
+       beq     no_hv_mode
 
        mfspr   r0,SPRN_HID0
        li      r11,5                   /* clear DOZE and SLEEP */
@@ -90,7 +90,7 @@ _GLOBAL(__setup_cpu_ppc970MP)
        /* Do nothing if not running in HV mode */
        mfmsr   r0
        rldicl. r0,r0,4,63
-       beqlr
+       beq     no_hv_mode
 
        mfspr   r0,SPRN_HID0
        li      r11,0x15                /* clear DOZE and SLEEP */
@@ -109,6 +109,14 @@ load_hids:
        sync
        isync
 
+       /* Try to set LPES = 01 in HID4 */
+       mfspr   r0,SPRN_HID4
+       clrldi  r0,r0,1                 /* clear LPES0 */
+       ori     r0,r0,HID4_LPES1        /* set LPES1 */
+       sync
+       mtspr   SPRN_HID4,r0
+       isync
+
        /* Save away cpu state */
        LOAD_REG_ADDR(r5,cpu_state_storage)
 
@@ -117,11 +125,21 @@ load_hids:
        std     r3,CS_HID0(r5)
        mfspr   r3,SPRN_HID1
        std     r3,CS_HID1(r5)
-       mfspr   r3,SPRN_HID4
-       std     r3,CS_HID4(r5)
+       mfspr   r4,SPRN_HID4
+       std     r4,CS_HID4(r5)
        mfspr   r3,SPRN_HID5
        std     r3,CS_HID5(r5)
 
+       /* See if we successfully set LPES1 to 1; if not we are in Apple mode */
+       andi.   r4,r4,HID4_LPES1
+       bnelr
+
+no_hv_mode:
+       /* Disable CPU_FTR_HVMODE and exit, since we don't have HV mode */
+       ld      r5,CPU_SPEC_FEATURES(r4)
+       LOAD_REG_IMMEDIATE(r6,CPU_FTR_HVMODE)
+       andc    r5,r5,r6
+       std     r5,CPU_SPEC_FEATURES(r4)
        blr
 
 /* Called with no MMU context (typically MSR:IR/DR off) to
index 5bc06fdfa6c0436f1093fbbbdcc88d9849534c28..a5345380bef390e19c3015a6a8f8a4c7952074d6 100644 (file)
@@ -75,7 +75,7 @@ BEGIN_FTR_SECTION
        b       .power7_wakeup_noloss
 2:     b       .power7_wakeup_loss
 9:
-END_FTR_SECTION_IFSET(CPU_FTR_HVMODE_206)
+END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
 #endif /* CONFIG_PPC_P7_NAP */
        EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common, EXC_STD,
                                 NOTEST, 0x100)
@@ -173,7 +173,7 @@ hardware_interrupt_hv:
                _MASKABLE_EXCEPTION_PSERIES(0x500, hardware_interrupt,
                                            EXC_STD, SOFTEN_TEST_PR)
                KVM_HANDLER(PACA_EXGEN, EXC_STD, 0x500)
-       ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE_206)
+       ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
 
        STD_EXCEPTION_PSERIES(0x600, 0x600, alignment)
        KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0x600)
index efeb88184182c478699dda6ffc68755dcaa86b36..0a5a899846bb283d8632f82ca0648045828ed43e 100644 (file)
@@ -167,7 +167,7 @@ void setup_paca(struct paca_struct *new_paca)
         * if we do a GET_PACA() before the feature fixups have been
         * applied
         */
-       if (cpu_has_feature(CPU_FTR_HVMODE_206))
+       if (cpu_has_feature(CPU_FTR_HVMODE))
                mtspr(SPRN_SPRG_HPACA, local_paca);
 #endif
        mtspr(SPRN_SPRG_PACA, local_paca);
index 96ba96a16abfda27ed55e854c64e924675f7473c..212dcd8fc50b302836644f83550e57f3abf3c33e 100644 (file)
@@ -128,7 +128,8 @@ void kvmppc_map_vrma(struct kvm *kvm, struct kvm_userspace_memory_region *mem)
 
 int kvmppc_mmu_hv_init(void)
 {
-       if (!cpu_has_feature(CPU_FTR_HVMODE_206))
+       if (!cpu_has_feature(CPU_FTR_HVMODE) ||
+           !cpu_has_feature(CPU_FTR_ARCH_206))
                return -EINVAL;
        memset(lpid_inuse, 0, sizeof(lpid_inuse));
        set_bit(mfspr(SPRN_LPID), lpid_inuse);
index 04da135cae61d861055f3a350f20332ad94f213f..dc70e7745ab3ce238e94b2aab95896f29994018c 100644 (file)
@@ -443,7 +443,8 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
 
 int kvmppc_core_check_processor_compat(void)
 {
-       if (cpu_has_feature(CPU_FTR_HVMODE_206))
+       if (cpu_has_feature(CPU_FTR_HVMODE) &&
+           cpu_has_feature(CPU_FTR_ARCH_206))
                return 0;
        return -EIO;
 }
index 736df3cbbc55238fb4bcce6a9efbee59f884ad17..7315ec6e817798fc5f06bf0138112b241547aa93 100644 (file)
@@ -90,8 +90,8 @@ void kvm_rma_init(void)
        void *rma;
        struct page *pg;
 
-       /* Only do this on POWER7 in HV mode */
-       if (!cpu_has_feature(CPU_FTR_HVMODE_206))
+       /* Only do this in HV mode */
+       if (!cpu_has_feature(CPU_FTR_HVMODE))
                return;
 
        if (!kvm_rma_size || !kvm_rma_count)
index 134501691ad0ceb53e167c3c73a5d37c5f19df69..aed32e51721254823b8a9e38170774f1b9e8a202 100644 (file)
@@ -170,7 +170,7 @@ BEGIN_FTR_SECTION
        mfspr   r4,SPRN_HSRR1
        andi.   r12,r12,0x3ffd
        b       2f
-END_FTR_SECTION_IFSET(CPU_FTR_HVMODE_206)
+END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
 #endif
 1:     mfsrr0  r3
        mfsrr1  r4
index dfd764896db07bd26255648ec60a465006061ad2..b44f5f803052e6db19ad74a3e2c5222f5eca0ec4 100644 (file)
@@ -51,7 +51,7 @@ static inline void __tlbie(unsigned long va, int psize, int ssize)
                va &= ~0xffful;
                va |= ssize << 8;
                asm volatile(ASM_FTR_IFCLR("tlbie %0,0", PPC_TLBIE(%1,%0), %2)
-                            : : "r" (va), "r"(0), "i" (CPU_FTR_HVMODE_206)
+                            : : "r" (va), "r"(0), "i" (CPU_FTR_ARCH_206)
                             : "memory");
                break;
        default:
@@ -61,7 +61,7 @@ static inline void __tlbie(unsigned long va, int psize, int ssize)
                va |= ssize << 8;
                va |= 1; /* L */
                asm volatile(ASM_FTR_IFCLR("tlbie %0,1", PPC_TLBIE(%1,%0), %2)
-                            : : "r" (va), "r"(0), "i" (CPU_FTR_HVMODE_206)
+                            : : "r" (va), "r"(0), "i" (CPU_FTR_ARCH_206)
                             : "memory");
                break;
        }