diff options
author | Paul Mackerras <paulus@ozlabs.org> | 2016-11-23 17:22:28 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@ozlabs.org> | 2016-11-23 17:22:28 -0500 |
commit | bc33b1fc83c0ecfcfcbb3c36fbaf7aec8bba6518 (patch) | |
tree | 783097be3a1853ce1a1a8b056e9400837b4f4b22 | |
parent | 68b8b72bb221f6d3d14b7fcc9c6991121b6a06ba (diff) | |
parent | 02ed21aeda0e02d84af493f92b1b6b6b13ddd6e8 (diff) |
Merge remote-tracking branch 'remotes/powerpc/topic/ppc-kvm' into kvm-ppc-next
This merges in the ppc-kvm topic branch to get changes to
arch/powerpc code that are necessary for adding POWER9 KVM support.
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
-rw-r--r-- | arch/powerpc/include/asm/book3s/64/mmu-hash.h | 47 | ||||
-rw-r--r-- | arch/powerpc/include/asm/mmu.h | 5 | ||||
-rw-r--r-- | arch/powerpc/include/asm/opal.h | 3 | ||||
-rw-r--r-- | arch/powerpc/include/asm/reg.h | 15 | ||||
-rw-r--r-- | arch/powerpc/kernel/cpu_setup_power.S | 2 | ||||
-rw-r--r-- | arch/powerpc/mm/hash_native_64.c | 30 | ||||
-rw-r--r-- | arch/powerpc/mm/hash_utils_64.c | 28 | ||||
-rw-r--r-- | arch/powerpc/mm/pgtable-radix.c | 18 | ||||
-rw-r--r-- | arch/powerpc/mm/pgtable_64.c | 34 | ||||
-rw-r--r-- | arch/powerpc/platforms/powernv/opal-wrappers.S | 3 | ||||
-rw-r--r-- | arch/powerpc/platforms/powernv/opal.c | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/ps3/htab.c | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/lpar.c | 2 |
13 files changed, 138 insertions, 53 deletions
diff --git a/arch/powerpc/include/asm/book3s/64/mmu-hash.h b/arch/powerpc/include/asm/book3s/64/mmu-hash.h index e407af2b7333..2e6a823fa502 100644 --- a/arch/powerpc/include/asm/book3s/64/mmu-hash.h +++ b/arch/powerpc/include/asm/book3s/64/mmu-hash.h | |||
@@ -70,7 +70,9 @@ | |||
70 | 70 | ||
71 | #define HPTE_V_SSIZE_SHIFT 62 | 71 | #define HPTE_V_SSIZE_SHIFT 62 |
72 | #define HPTE_V_AVPN_SHIFT 7 | 72 | #define HPTE_V_AVPN_SHIFT 7 |
73 | #define HPTE_V_COMMON_BITS ASM_CONST(0x000fffffffffffff) | ||
73 | #define HPTE_V_AVPN ASM_CONST(0x3fffffffffffff80) | 74 | #define HPTE_V_AVPN ASM_CONST(0x3fffffffffffff80) |
75 | #define HPTE_V_AVPN_3_0 ASM_CONST(0x000fffffffffff80) | ||
74 | #define HPTE_V_AVPN_VAL(x) (((x) & HPTE_V_AVPN) >> HPTE_V_AVPN_SHIFT) | 76 | #define HPTE_V_AVPN_VAL(x) (((x) & HPTE_V_AVPN) >> HPTE_V_AVPN_SHIFT) |
75 | #define HPTE_V_COMPARE(x,y) (!(((x) ^ (y)) & 0xffffffffffffff80UL)) | 77 | #define HPTE_V_COMPARE(x,y) (!(((x) ^ (y)) & 0xffffffffffffff80UL)) |
76 | #define HPTE_V_BOLTED ASM_CONST(0x0000000000000010) | 78 | #define HPTE_V_BOLTED ASM_CONST(0x0000000000000010) |
@@ -80,14 +82,16 @@ | |||
80 | #define HPTE_V_VALID ASM_CONST(0x0000000000000001) | 82 | #define HPTE_V_VALID ASM_CONST(0x0000000000000001) |
81 | 83 | ||
82 | /* | 84 | /* |
83 | * ISA 3.0 have a different HPTE format. | 85 | * ISA 3.0 has a different HPTE format. |
84 | */ | 86 | */ |
85 | #define HPTE_R_3_0_SSIZE_SHIFT 58 | 87 | #define HPTE_R_3_0_SSIZE_SHIFT 58 |
88 | #define HPTE_R_3_0_SSIZE_MASK (3ull << HPTE_R_3_0_SSIZE_SHIFT) | ||
86 | #define HPTE_R_PP0 ASM_CONST(0x8000000000000000) | 89 | #define HPTE_R_PP0 ASM_CONST(0x8000000000000000) |
87 | #define HPTE_R_TS ASM_CONST(0x4000000000000000) | 90 | #define HPTE_R_TS ASM_CONST(0x4000000000000000) |
88 | #define HPTE_R_KEY_HI ASM_CONST(0x3000000000000000) | 91 | #define HPTE_R_KEY_HI ASM_CONST(0x3000000000000000) |
89 | #define HPTE_R_RPN_SHIFT 12 | 92 | #define HPTE_R_RPN_SHIFT 12 |
90 | #define HPTE_R_RPN ASM_CONST(0x0ffffffffffff000) | 93 | #define HPTE_R_RPN ASM_CONST(0x0ffffffffffff000) |
94 | #define HPTE_R_RPN_3_0 ASM_CONST(0x01fffffffffff000) | ||
91 | #define HPTE_R_PP ASM_CONST(0x0000000000000003) | 95 | #define HPTE_R_PP ASM_CONST(0x0000000000000003) |
92 | #define HPTE_R_PPP ASM_CONST(0x8000000000000003) | 96 | #define HPTE_R_PPP ASM_CONST(0x8000000000000003) |
93 | #define HPTE_R_N ASM_CONST(0x0000000000000004) | 97 | #define HPTE_R_N ASM_CONST(0x0000000000000004) |
@@ -316,12 +320,43 @@ static inline unsigned long hpte_encode_avpn(unsigned long vpn, int psize, | |||
316 | */ | 320 | */ |
317 | v = (vpn >> (23 - VPN_SHIFT)) & ~(mmu_psize_defs[psize].avpnm); | 321 | v = (vpn >> (23 - VPN_SHIFT)) & ~(mmu_psize_defs[psize].avpnm); |
318 | v <<= HPTE_V_AVPN_SHIFT; | 322 | v <<= HPTE_V_AVPN_SHIFT; |
319 | if (!cpu_has_feature(CPU_FTR_ARCH_300)) | 323 | v |= ((unsigned long) ssize) << HPTE_V_SSIZE_SHIFT; |
320 | v |= ((unsigned long) ssize) << HPTE_V_SSIZE_SHIFT; | ||
321 | return v; | 324 | return v; |
322 | } | 325 | } |
323 | 326 | ||
324 | /* | 327 | /* |
328 | * ISA v3.0 defines a new HPTE format, which differs from the old | ||
329 | * format in having smaller AVPN and ARPN fields, and the B field | ||
330 | * in the second dword instead of the first. | ||
331 | */ | ||
332 | static inline unsigned long hpte_old_to_new_v(unsigned long v) | ||
333 | { | ||
334 | /* trim AVPN, drop B */ | ||
335 | return v & HPTE_V_COMMON_BITS; | ||
336 | } | ||
337 | |||
338 | static inline unsigned long hpte_old_to_new_r(unsigned long v, unsigned long r) | ||
339 | { | ||
340 | /* move B field from 1st to 2nd dword, trim ARPN */ | ||
341 | return (r & ~HPTE_R_3_0_SSIZE_MASK) | | ||
342 | (((v) >> HPTE_V_SSIZE_SHIFT) << HPTE_R_3_0_SSIZE_SHIFT); | ||
343 | } | ||
344 | |||
345 | static inline unsigned long hpte_new_to_old_v(unsigned long v, unsigned long r) | ||
346 | { | ||
347 | /* insert B field */ | ||
348 | return (v & HPTE_V_COMMON_BITS) | | ||
349 | ((r & HPTE_R_3_0_SSIZE_MASK) << | ||
350 | (HPTE_V_SSIZE_SHIFT - HPTE_R_3_0_SSIZE_SHIFT)); | ||
351 | } | ||
352 | |||
353 | static inline unsigned long hpte_new_to_old_r(unsigned long r) | ||
354 | { | ||
355 | /* clear out B field */ | ||
356 | return r & ~HPTE_R_3_0_SSIZE_MASK; | ||
357 | } | ||
358 | |||
359 | /* | ||
325 | * This function sets the AVPN and L fields of the HPTE appropriately | 360 | * This function sets the AVPN and L fields of the HPTE appropriately |
326 | * using the base page size and actual page size. | 361 | * using the base page size and actual page size. |
327 | */ | 362 | */ |
@@ -341,12 +376,8 @@ static inline unsigned long hpte_encode_v(unsigned long vpn, int base_psize, | |||
341 | * aligned for the requested page size | 376 | * aligned for the requested page size |
342 | */ | 377 | */ |
343 | static inline unsigned long hpte_encode_r(unsigned long pa, int base_psize, | 378 | static inline unsigned long hpte_encode_r(unsigned long pa, int base_psize, |
344 | int actual_psize, int ssize) | 379 | int actual_psize) |
345 | { | 380 | { |
346 | |||
347 | if (cpu_has_feature(CPU_FTR_ARCH_300)) | ||
348 | pa |= ((unsigned long) ssize) << HPTE_R_3_0_SSIZE_SHIFT; | ||
349 | |||
350 | /* A 4K page needs no special encoding */ | 381 | /* A 4K page needs no special encoding */ |
351 | if (actual_psize == MMU_PAGE_4K) | 382 | if (actual_psize == MMU_PAGE_4K) |
352 | return pa & HPTE_R_RPN; | 383 | return pa & HPTE_R_RPN; |
diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h index e88368354e49..060b40b1bc3d 100644 --- a/arch/powerpc/include/asm/mmu.h +++ b/arch/powerpc/include/asm/mmu.h | |||
@@ -208,6 +208,11 @@ extern u64 ppc64_rma_size; | |||
208 | /* Cleanup function used by kexec */ | 208 | /* Cleanup function used by kexec */ |
209 | extern void mmu_cleanup_all(void); | 209 | extern void mmu_cleanup_all(void); |
210 | extern void radix__mmu_cleanup_all(void); | 210 | extern void radix__mmu_cleanup_all(void); |
211 | |||
212 | /* Functions for creating and updating partition table on POWER9 */ | ||
213 | extern void mmu_partition_table_init(void); | ||
214 | extern void mmu_partition_table_set_entry(unsigned int lpid, unsigned long dw0, | ||
215 | unsigned long dw1); | ||
211 | #endif /* CONFIG_PPC64 */ | 216 | #endif /* CONFIG_PPC64 */ |
212 | 217 | ||
213 | struct mm_struct; | 218 | struct mm_struct; |
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h index e958b7096f19..5c7db0f1a708 100644 --- a/arch/powerpc/include/asm/opal.h +++ b/arch/powerpc/include/asm/opal.h | |||
@@ -220,9 +220,12 @@ int64_t opal_pci_set_power_state(uint64_t async_token, uint64_t id, | |||
220 | int64_t opal_pci_poll2(uint64_t id, uint64_t data); | 220 | int64_t opal_pci_poll2(uint64_t id, uint64_t data); |
221 | 221 | ||
222 | int64_t opal_int_get_xirr(uint32_t *out_xirr, bool just_poll); | 222 | int64_t opal_int_get_xirr(uint32_t *out_xirr, bool just_poll); |
223 | int64_t opal_rm_int_get_xirr(__be32 *out_xirr, bool just_poll); | ||
223 | int64_t opal_int_set_cppr(uint8_t cppr); | 224 | int64_t opal_int_set_cppr(uint8_t cppr); |
224 | int64_t opal_int_eoi(uint32_t xirr); | 225 | int64_t opal_int_eoi(uint32_t xirr); |
226 | int64_t opal_rm_int_eoi(uint32_t xirr); | ||
225 | int64_t opal_int_set_mfrr(uint32_t cpu, uint8_t mfrr); | 227 | int64_t opal_int_set_mfrr(uint32_t cpu, uint8_t mfrr); |
228 | int64_t opal_rm_int_set_mfrr(uint32_t cpu, uint8_t mfrr); | ||
226 | int64_t opal_pci_tce_kill(uint64_t phb_id, uint32_t kill_type, | 229 | int64_t opal_pci_tce_kill(uint64_t phb_id, uint32_t kill_type, |
227 | uint32_t pe_num, uint32_t tce_size, | 230 | uint32_t pe_num, uint32_t tce_size, |
228 | uint64_t dma_addr, uint32_t npages); | 231 | uint64_t dma_addr, uint32_t npages); |
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index 9cd4e8cbc78c..04aa1ee8cdb6 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h | |||
@@ -153,6 +153,8 @@ | |||
153 | #define PSSCR_EC 0x00100000 /* Exit Criterion */ | 153 | #define PSSCR_EC 0x00100000 /* Exit Criterion */ |
154 | #define PSSCR_ESL 0x00200000 /* Enable State Loss */ | 154 | #define PSSCR_ESL 0x00200000 /* Enable State Loss */ |
155 | #define PSSCR_SD 0x00400000 /* Status Disable */ | 155 | #define PSSCR_SD 0x00400000 /* Status Disable */ |
156 | #define PSSCR_PLS 0xf000000000000000 /* Power-saving Level Status */ | ||
157 | #define PSSCR_GUEST_VIS 0xf0000000000003ff /* Guest-visible PSSCR fields */ | ||
156 | 158 | ||
157 | /* Floating Point Status and Control Register (FPSCR) Fields */ | 159 | /* Floating Point Status and Control Register (FPSCR) Fields */ |
158 | #define FPSCR_FX 0x80000000 /* FPU exception summary */ | 160 | #define FPSCR_FX 0x80000000 /* FPU exception summary */ |
@@ -236,6 +238,7 @@ | |||
236 | #define SPRN_TEXASRU 0x83 /* '' '' '' Upper 32 */ | 238 | #define SPRN_TEXASRU 0x83 /* '' '' '' Upper 32 */ |
237 | #define TEXASR_FS __MASK(63-36) /* TEXASR Failure Summary */ | 239 | #define TEXASR_FS __MASK(63-36) /* TEXASR Failure Summary */ |
238 | #define SPRN_TFHAR 0x80 /* Transaction Failure Handler Addr */ | 240 | #define SPRN_TFHAR 0x80 /* Transaction Failure Handler Addr */ |
241 | #define SPRN_TIDR 144 /* Thread ID register */ | ||
239 | #define SPRN_CTRLF 0x088 | 242 | #define SPRN_CTRLF 0x088 |
240 | #define SPRN_CTRLT 0x098 | 243 | #define SPRN_CTRLT 0x098 |
241 | #define CTRL_CT 0xc0000000 /* current thread */ | 244 | #define CTRL_CT 0xc0000000 /* current thread */ |
@@ -294,6 +297,7 @@ | |||
294 | #define SPRN_HSRR1 0x13B /* Hypervisor Save/Restore 1 */ | 297 | #define SPRN_HSRR1 0x13B /* Hypervisor Save/Restore 1 */ |
295 | #define SPRN_LMRR 0x32D /* Load Monitor Region Register */ | 298 | #define SPRN_LMRR 0x32D /* Load Monitor Region Register */ |
296 | #define SPRN_LMSER 0x32E /* Load Monitor Section Enable Register */ | 299 | #define SPRN_LMSER 0x32E /* Load Monitor Section Enable Register */ |
300 | #define SPRN_ASDR 0x330 /* Access segment descriptor register */ | ||
297 | #define SPRN_IC 0x350 /* Virtual Instruction Count */ | 301 | #define SPRN_IC 0x350 /* Virtual Instruction Count */ |
298 | #define SPRN_VTB 0x351 /* Virtual Time Base */ | 302 | #define SPRN_VTB 0x351 /* Virtual Time Base */ |
299 | #define SPRN_LDBAR 0x352 /* LD Base Address Register */ | 303 | #define SPRN_LDBAR 0x352 /* LD Base Address Register */ |
@@ -305,6 +309,7 @@ | |||
305 | 309 | ||
306 | /* HFSCR and FSCR bit numbers are the same */ | 310 | /* HFSCR and FSCR bit numbers are the same */ |
307 | #define FSCR_LM_LG 11 /* Enable Load Monitor Registers */ | 311 | #define FSCR_LM_LG 11 /* Enable Load Monitor Registers */ |
312 | #define FSCR_MSGP_LG 10 /* Enable MSGP */ | ||
308 | #define FSCR_TAR_LG 8 /* Enable Target Address Register */ | 313 | #define FSCR_TAR_LG 8 /* Enable Target Address Register */ |
309 | #define FSCR_EBB_LG 7 /* Enable Event Based Branching */ | 314 | #define FSCR_EBB_LG 7 /* Enable Event Based Branching */ |
310 | #define FSCR_TM_LG 5 /* Enable Transactional Memory */ | 315 | #define FSCR_TM_LG 5 /* Enable Transactional Memory */ |
@@ -320,6 +325,7 @@ | |||
320 | #define FSCR_DSCR __MASK(FSCR_DSCR_LG) | 325 | #define FSCR_DSCR __MASK(FSCR_DSCR_LG) |
321 | #define SPRN_HFSCR 0xbe /* HV=1 Facility Status & Control Register */ | 326 | #define SPRN_HFSCR 0xbe /* HV=1 Facility Status & Control Register */ |
322 | #define HFSCR_LM __MASK(FSCR_LM_LG) | 327 | #define HFSCR_LM __MASK(FSCR_LM_LG) |
328 | #define HFSCR_MSGP __MASK(FSCR_MSGP_LG) | ||
323 | #define HFSCR_TAR __MASK(FSCR_TAR_LG) | 329 | #define HFSCR_TAR __MASK(FSCR_TAR_LG) |
324 | #define HFSCR_EBB __MASK(FSCR_EBB_LG) | 330 | #define HFSCR_EBB __MASK(FSCR_EBB_LG) |
325 | #define HFSCR_TM __MASK(FSCR_TM_LG) | 331 | #define HFSCR_TM __MASK(FSCR_TM_LG) |
@@ -355,8 +361,10 @@ | |||
355 | #define LPCR_PECE0 ASM_CONST(0x0000000000004000) /* ext. exceptions can cause exit */ | 361 | #define LPCR_PECE0 ASM_CONST(0x0000000000004000) /* ext. exceptions can cause exit */ |
356 | #define LPCR_PECE1 ASM_CONST(0x0000000000002000) /* decrementer can cause exit */ | 362 | #define LPCR_PECE1 ASM_CONST(0x0000000000002000) /* decrementer can cause exit */ |
357 | #define LPCR_PECE2 ASM_CONST(0x0000000000001000) /* machine check etc can cause exit */ | 363 | #define LPCR_PECE2 ASM_CONST(0x0000000000001000) /* machine check etc can cause exit */ |
364 | #define LPCR_PECE_HVEE ASM_CONST(0x0000400000000000) /* P9 Wakeup on HV interrupts */ | ||
358 | #define LPCR_MER ASM_CONST(0x0000000000000800) /* Mediated External Exception */ | 365 | #define LPCR_MER ASM_CONST(0x0000000000000800) /* Mediated External Exception */ |
359 | #define LPCR_MER_SH 11 | 366 | #define LPCR_MER_SH 11 |
367 | #define LPCR_GTSE ASM_CONST(0x0000000000000400) /* Guest Translation Shootdown Enable */ | ||
360 | #define LPCR_TC ASM_CONST(0x0000000000000200) /* Translation control */ | 368 | #define LPCR_TC ASM_CONST(0x0000000000000200) /* Translation control */ |
361 | #define LPCR_LPES 0x0000000c | 369 | #define LPCR_LPES 0x0000000c |
362 | #define LPCR_LPES0 ASM_CONST(0x0000000000000008) /* LPAR Env selector 0 */ | 370 | #define LPCR_LPES0 ASM_CONST(0x0000000000000008) /* LPAR Env selector 0 */ |
@@ -377,6 +385,12 @@ | |||
377 | #define PCR_VEC_DIS (1ul << (63-0)) /* Vec. disable (bit NA since POWER8) */ | 385 | #define PCR_VEC_DIS (1ul << (63-0)) /* Vec. disable (bit NA since POWER8) */ |
378 | #define PCR_VSX_DIS (1ul << (63-1)) /* VSX disable (bit NA since POWER8) */ | 386 | #define PCR_VSX_DIS (1ul << (63-1)) /* VSX disable (bit NA since POWER8) */ |
379 | #define PCR_TM_DIS (1ul << (63-2)) /* Trans. memory disable (POWER8) */ | 387 | #define PCR_TM_DIS (1ul << (63-2)) /* Trans. memory disable (POWER8) */ |
388 | /* | ||
389 | * These bits are used in the function kvmppc_set_arch_compat() to specify and | ||
390 | * determine both the compatibility level which we want to emulate and the | ||
391 | * compatibility level which the host is capable of emulating. | ||
392 | */ | ||
393 | #define PCR_ARCH_207 0x8 /* Architecture 2.07 */ | ||
380 | #define PCR_ARCH_206 0x4 /* Architecture 2.06 */ | 394 | #define PCR_ARCH_206 0x4 /* Architecture 2.06 */ |
381 | #define PCR_ARCH_205 0x2 /* Architecture 2.05 */ | 395 | #define PCR_ARCH_205 0x2 /* Architecture 2.05 */ |
382 | #define SPRN_HEIR 0x153 /* Hypervisor Emulated Instruction Register */ | 396 | #define SPRN_HEIR 0x153 /* Hypervisor Emulated Instruction Register */ |
@@ -1218,6 +1232,7 @@ | |||
1218 | #define PVR_ARCH_206 0x0f000003 | 1232 | #define PVR_ARCH_206 0x0f000003 |
1219 | #define PVR_ARCH_206p 0x0f100003 | 1233 | #define PVR_ARCH_206p 0x0f100003 |
1220 | #define PVR_ARCH_207 0x0f000004 | 1234 | #define PVR_ARCH_207 0x0f000004 |
1235 | #define PVR_ARCH_300 0x0f000005 | ||
1221 | 1236 | ||
1222 | /* Macros for setting and retrieving special purpose registers */ | 1237 | /* Macros for setting and retrieving special purpose registers */ |
1223 | #ifndef __ASSEMBLY__ | 1238 | #ifndef __ASSEMBLY__ |
diff --git a/arch/powerpc/kernel/cpu_setup_power.S b/arch/powerpc/kernel/cpu_setup_power.S index 52ff3f025437..bdfc1c67eb38 100644 --- a/arch/powerpc/kernel/cpu_setup_power.S +++ b/arch/powerpc/kernel/cpu_setup_power.S | |||
@@ -174,7 +174,7 @@ __init_FSCR: | |||
174 | __init_HFSCR: | 174 | __init_HFSCR: |
175 | mfspr r3,SPRN_HFSCR | 175 | mfspr r3,SPRN_HFSCR |
176 | ori r3,r3,HFSCR_TAR|HFSCR_TM|HFSCR_BHRB|HFSCR_PM|\ | 176 | ori r3,r3,HFSCR_TAR|HFSCR_TM|HFSCR_BHRB|HFSCR_PM|\ |
177 | HFSCR_DSCR|HFSCR_VECVSX|HFSCR_FP|HFSCR_EBB | 177 | HFSCR_DSCR|HFSCR_VECVSX|HFSCR_FP|HFSCR_EBB|HFSCR_MSGP |
178 | mtspr SPRN_HFSCR,r3 | 178 | mtspr SPRN_HFSCR,r3 |
179 | blr | 179 | blr |
180 | 180 | ||
diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c index 83ddc0e171b0..ad9fd5245be2 100644 --- a/arch/powerpc/mm/hash_native_64.c +++ b/arch/powerpc/mm/hash_native_64.c | |||
@@ -221,13 +221,18 @@ static long native_hpte_insert(unsigned long hpte_group, unsigned long vpn, | |||
221 | return -1; | 221 | return -1; |
222 | 222 | ||
223 | hpte_v = hpte_encode_v(vpn, psize, apsize, ssize) | vflags | HPTE_V_VALID; | 223 | hpte_v = hpte_encode_v(vpn, psize, apsize, ssize) | vflags | HPTE_V_VALID; |
224 | hpte_r = hpte_encode_r(pa, psize, apsize, ssize) | rflags; | 224 | hpte_r = hpte_encode_r(pa, psize, apsize) | rflags; |
225 | 225 | ||
226 | if (!(vflags & HPTE_V_BOLTED)) { | 226 | if (!(vflags & HPTE_V_BOLTED)) { |
227 | DBG_LOW(" i=%x hpte_v=%016lx, hpte_r=%016lx\n", | 227 | DBG_LOW(" i=%x hpte_v=%016lx, hpte_r=%016lx\n", |
228 | i, hpte_v, hpte_r); | 228 | i, hpte_v, hpte_r); |
229 | } | 229 | } |
230 | 230 | ||
231 | if (cpu_has_feature(CPU_FTR_ARCH_300)) { | ||
232 | hpte_r = hpte_old_to_new_r(hpte_v, hpte_r); | ||
233 | hpte_v = hpte_old_to_new_v(hpte_v); | ||
234 | } | ||
235 | |||
231 | hptep->r = cpu_to_be64(hpte_r); | 236 | hptep->r = cpu_to_be64(hpte_r); |
232 | /* Guarantee the second dword is visible before the valid bit */ | 237 | /* Guarantee the second dword is visible before the valid bit */ |
233 | eieio(); | 238 | eieio(); |
@@ -295,6 +300,8 @@ static long native_hpte_updatepp(unsigned long slot, unsigned long newpp, | |||
295 | vpn, want_v & HPTE_V_AVPN, slot, newpp); | 300 | vpn, want_v & HPTE_V_AVPN, slot, newpp); |
296 | 301 | ||
297 | hpte_v = be64_to_cpu(hptep->v); | 302 | hpte_v = be64_to_cpu(hptep->v); |
303 | if (cpu_has_feature(CPU_FTR_ARCH_300)) | ||
304 | hpte_v = hpte_new_to_old_v(hpte_v, be64_to_cpu(hptep->r)); | ||
298 | /* | 305 | /* |
299 | * We need to invalidate the TLB always because hpte_remove doesn't do | 306 | * We need to invalidate the TLB always because hpte_remove doesn't do |
300 | * a tlb invalidate. If a hash bucket gets full, we "evict" a more/less | 307 | * a tlb invalidate. If a hash bucket gets full, we "evict" a more/less |
@@ -309,6 +316,8 @@ static long native_hpte_updatepp(unsigned long slot, unsigned long newpp, | |||
309 | native_lock_hpte(hptep); | 316 | native_lock_hpte(hptep); |
310 | /* recheck with locks held */ | 317 | /* recheck with locks held */ |
311 | hpte_v = be64_to_cpu(hptep->v); | 318 | hpte_v = be64_to_cpu(hptep->v); |
319 | if (cpu_has_feature(CPU_FTR_ARCH_300)) | ||
320 | hpte_v = hpte_new_to_old_v(hpte_v, be64_to_cpu(hptep->r)); | ||
312 | if (unlikely(!HPTE_V_COMPARE(hpte_v, want_v) || | 321 | if (unlikely(!HPTE_V_COMPARE(hpte_v, want_v) || |
313 | !(hpte_v & HPTE_V_VALID))) { | 322 | !(hpte_v & HPTE_V_VALID))) { |
314 | ret = -1; | 323 | ret = -1; |
@@ -350,6 +359,8 @@ static long native_hpte_find(unsigned long vpn, int psize, int ssize) | |||
350 | for (i = 0; i < HPTES_PER_GROUP; i++) { | 359 | for (i = 0; i < HPTES_PER_GROUP; i++) { |
351 | hptep = htab_address + slot; | 360 | hptep = htab_address + slot; |
352 | hpte_v = be64_to_cpu(hptep->v); | 361 | hpte_v = be64_to_cpu(hptep->v); |
362 | if (cpu_has_feature(CPU_FTR_ARCH_300)) | ||
363 | hpte_v = hpte_new_to_old_v(hpte_v, be64_to_cpu(hptep->r)); | ||
353 | 364 | ||
354 | if (HPTE_V_COMPARE(hpte_v, want_v) && (hpte_v & HPTE_V_VALID)) | 365 | if (HPTE_V_COMPARE(hpte_v, want_v) && (hpte_v & HPTE_V_VALID)) |
355 | /* HPTE matches */ | 366 | /* HPTE matches */ |
@@ -409,6 +420,8 @@ static void native_hpte_invalidate(unsigned long slot, unsigned long vpn, | |||
409 | want_v = hpte_encode_avpn(vpn, bpsize, ssize); | 420 | want_v = hpte_encode_avpn(vpn, bpsize, ssize); |
410 | native_lock_hpte(hptep); | 421 | native_lock_hpte(hptep); |
411 | hpte_v = be64_to_cpu(hptep->v); | 422 | hpte_v = be64_to_cpu(hptep->v); |
423 | if (cpu_has_feature(CPU_FTR_ARCH_300)) | ||
424 | hpte_v = hpte_new_to_old_v(hpte_v, be64_to_cpu(hptep->r)); | ||
412 | 425 | ||
413 | /* | 426 | /* |
414 | * We need to invalidate the TLB always because hpte_remove doesn't do | 427 | * We need to invalidate the TLB always because hpte_remove doesn't do |
@@ -467,6 +480,8 @@ static void native_hugepage_invalidate(unsigned long vsid, | |||
467 | want_v = hpte_encode_avpn(vpn, psize, ssize); | 480 | want_v = hpte_encode_avpn(vpn, psize, ssize); |
468 | native_lock_hpte(hptep); | 481 | native_lock_hpte(hptep); |
469 | hpte_v = be64_to_cpu(hptep->v); | 482 | hpte_v = be64_to_cpu(hptep->v); |
483 | if (cpu_has_feature(CPU_FTR_ARCH_300)) | ||
484 | hpte_v = hpte_new_to_old_v(hpte_v, be64_to_cpu(hptep->r)); | ||
470 | 485 | ||
471 | /* Even if we miss, we need to invalidate the TLB */ | 486 | /* Even if we miss, we need to invalidate the TLB */ |
472 | if (!HPTE_V_COMPARE(hpte_v, want_v) || !(hpte_v & HPTE_V_VALID)) | 487 | if (!HPTE_V_COMPARE(hpte_v, want_v) || !(hpte_v & HPTE_V_VALID)) |
@@ -504,6 +519,10 @@ static void hpte_decode(struct hash_pte *hpte, unsigned long slot, | |||
504 | /* Look at the 8 bit LP value */ | 519 | /* Look at the 8 bit LP value */ |
505 | unsigned int lp = (hpte_r >> LP_SHIFT) & ((1 << LP_BITS) - 1); | 520 | unsigned int lp = (hpte_r >> LP_SHIFT) & ((1 << LP_BITS) - 1); |
506 | 521 | ||
522 | if (cpu_has_feature(CPU_FTR_ARCH_300)) { | ||
523 | hpte_v = hpte_new_to_old_v(hpte_v, hpte_r); | ||
524 | hpte_r = hpte_new_to_old_r(hpte_r); | ||
525 | } | ||
507 | if (!(hpte_v & HPTE_V_LARGE)) { | 526 | if (!(hpte_v & HPTE_V_LARGE)) { |
508 | size = MMU_PAGE_4K; | 527 | size = MMU_PAGE_4K; |
509 | a_size = MMU_PAGE_4K; | 528 | a_size = MMU_PAGE_4K; |
@@ -512,11 +531,7 @@ static void hpte_decode(struct hash_pte *hpte, unsigned long slot, | |||
512 | a_size = hpte_page_sizes[lp] >> 4; | 531 | a_size = hpte_page_sizes[lp] >> 4; |
513 | } | 532 | } |
514 | /* This works for all page sizes, and for 256M and 1T segments */ | 533 | /* This works for all page sizes, and for 256M and 1T segments */ |
515 | if (cpu_has_feature(CPU_FTR_ARCH_300)) | 534 | *ssize = hpte_v >> HPTE_V_SSIZE_SHIFT; |
516 | *ssize = hpte_r >> HPTE_R_3_0_SSIZE_SHIFT; | ||
517 | else | ||
518 | *ssize = hpte_v >> HPTE_V_SSIZE_SHIFT; | ||
519 | |||
520 | shift = mmu_psize_defs[size].shift; | 535 | shift = mmu_psize_defs[size].shift; |
521 | 536 | ||
522 | avpn = (HPTE_V_AVPN_VAL(hpte_v) & ~mmu_psize_defs[size].avpnm); | 537 | avpn = (HPTE_V_AVPN_VAL(hpte_v) & ~mmu_psize_defs[size].avpnm); |
@@ -639,6 +654,9 @@ static void native_flush_hash_range(unsigned long number, int local) | |||
639 | want_v = hpte_encode_avpn(vpn, psize, ssize); | 654 | want_v = hpte_encode_avpn(vpn, psize, ssize); |
640 | native_lock_hpte(hptep); | 655 | native_lock_hpte(hptep); |
641 | hpte_v = be64_to_cpu(hptep->v); | 656 | hpte_v = be64_to_cpu(hptep->v); |
657 | if (cpu_has_feature(CPU_FTR_ARCH_300)) | ||
658 | hpte_v = hpte_new_to_old_v(hpte_v, | ||
659 | be64_to_cpu(hptep->r)); | ||
642 | if (!HPTE_V_COMPARE(hpte_v, want_v) || | 660 | if (!HPTE_V_COMPARE(hpte_v, want_v) || |
643 | !(hpte_v & HPTE_V_VALID)) | 661 | !(hpte_v & HPTE_V_VALID)) |
644 | native_unlock_hpte(hptep); | 662 | native_unlock_hpte(hptep); |
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index 44d3c3a38e3e..b9a062f5805b 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c | |||
@@ -792,37 +792,17 @@ static void update_hid_for_hash(void) | |||
792 | static void __init hash_init_partition_table(phys_addr_t hash_table, | 792 | static void __init hash_init_partition_table(phys_addr_t hash_table, |
793 | unsigned long htab_size) | 793 | unsigned long htab_size) |
794 | { | 794 | { |
795 | unsigned long ps_field; | 795 | mmu_partition_table_init(); |
796 | unsigned long patb_size = 1UL << PATB_SIZE_SHIFT; | ||
797 | 796 | ||
798 | /* | 797 | /* |
799 | * slb llp encoding for the page size used in VPM real mode. | 798 | * PS field (VRMA page size) is not used for LPID 0, hence set to 0. |
800 | * We can ignore that for lpid 0 | 799 | * For now, UPRT is 0 and we have no segment table. |
801 | */ | 800 | */ |
802 | ps_field = 0; | ||
803 | htab_size = __ilog2(htab_size) - 18; | 801 | htab_size = __ilog2(htab_size) - 18; |
804 | 802 | mmu_partition_table_set_entry(0, hash_table | htab_size, 0); | |
805 | BUILD_BUG_ON_MSG((PATB_SIZE_SHIFT > 24), "Partition table size too large."); | ||
806 | partition_tb = __va(memblock_alloc_base(patb_size, patb_size, | ||
807 | MEMBLOCK_ALLOC_ANYWHERE)); | ||
808 | |||
809 | /* Initialize the Partition Table with no entries */ | ||
810 | memset((void *)partition_tb, 0, patb_size); | ||
811 | partition_tb->patb0 = cpu_to_be64(ps_field | hash_table | htab_size); | ||
812 | /* | ||
813 | * FIXME!! This should be done via update_partition table | ||
814 | * For now UPRT is 0 for us. | ||
815 | */ | ||
816 | partition_tb->patb1 = 0; | ||
817 | pr_info("Partition table %p\n", partition_tb); | 803 | pr_info("Partition table %p\n", partition_tb); |
818 | if (cpu_has_feature(CPU_FTR_POWER9_DD1)) | 804 | if (cpu_has_feature(CPU_FTR_POWER9_DD1)) |
819 | update_hid_for_hash(); | 805 | update_hid_for_hash(); |
820 | /* | ||
821 | * update partition table control register, | ||
822 | * 64 K size. | ||
823 | */ | ||
824 | mtspr(SPRN_PTCR, __pa(partition_tb) | (PATB_SIZE_SHIFT - 12)); | ||
825 | |||
826 | } | 806 | } |
827 | 807 | ||
828 | static void __init htab_initialize(void) | 808 | static void __init htab_initialize(void) |
diff --git a/arch/powerpc/mm/pgtable-radix.c b/arch/powerpc/mm/pgtable-radix.c index ed7bddc456b7..186f1adb04ec 100644 --- a/arch/powerpc/mm/pgtable-radix.c +++ b/arch/powerpc/mm/pgtable-radix.c | |||
@@ -177,23 +177,15 @@ redo: | |||
177 | 177 | ||
178 | static void __init radix_init_partition_table(void) | 178 | static void __init radix_init_partition_table(void) |
179 | { | 179 | { |
180 | unsigned long rts_field; | 180 | unsigned long rts_field, dw0; |
181 | 181 | ||
182 | mmu_partition_table_init(); | ||
182 | rts_field = radix__get_tree_size(); | 183 | rts_field = radix__get_tree_size(); |
184 | dw0 = rts_field | __pa(init_mm.pgd) | RADIX_PGD_INDEX_SIZE | PATB_HR; | ||
185 | mmu_partition_table_set_entry(0, dw0, 0); | ||
183 | 186 | ||
184 | BUILD_BUG_ON_MSG((PATB_SIZE_SHIFT > 24), "Partition table size too large."); | ||
185 | partition_tb = early_alloc_pgtable(1UL << PATB_SIZE_SHIFT); | ||
186 | partition_tb->patb0 = cpu_to_be64(rts_field | __pa(init_mm.pgd) | | ||
187 | RADIX_PGD_INDEX_SIZE | PATB_HR); | ||
188 | pr_info("Initializing Radix MMU\n"); | 187 | pr_info("Initializing Radix MMU\n"); |
189 | pr_info("Partition table %p\n", partition_tb); | 188 | pr_info("Partition table %p\n", partition_tb); |
190 | |||
191 | memblock_set_current_limit(MEMBLOCK_ALLOC_ANYWHERE); | ||
192 | /* | ||
193 | * update partition table control register, | ||
194 | * 64 K size. | ||
195 | */ | ||
196 | mtspr(SPRN_PTCR, __pa(partition_tb) | (PATB_SIZE_SHIFT - 12)); | ||
197 | } | 189 | } |
198 | 190 | ||
199 | void __init radix_init_native(void) | 191 | void __init radix_init_native(void) |
@@ -378,6 +370,8 @@ void __init radix__early_init_mmu(void) | |||
378 | radix_init_partition_table(); | 370 | radix_init_partition_table(); |
379 | } | 371 | } |
380 | 372 | ||
373 | memblock_set_current_limit(MEMBLOCK_ALLOC_ANYWHERE); | ||
374 | |||
381 | radix_init_pgtable(); | 375 | radix_init_pgtable(); |
382 | } | 376 | } |
383 | 377 | ||
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c index f5e8d4edb808..8bca7f58afc4 100644 --- a/arch/powerpc/mm/pgtable_64.c +++ b/arch/powerpc/mm/pgtable_64.c | |||
@@ -431,3 +431,37 @@ void pgtable_free_tlb(struct mmu_gather *tlb, void *table, int shift) | |||
431 | } | 431 | } |
432 | } | 432 | } |
433 | #endif | 433 | #endif |
434 | |||
435 | #ifdef CONFIG_PPC_BOOK3S_64 | ||
436 | void __init mmu_partition_table_init(void) | ||
437 | { | ||
438 | unsigned long patb_size = 1UL << PATB_SIZE_SHIFT; | ||
439 | |||
440 | BUILD_BUG_ON_MSG((PATB_SIZE_SHIFT > 36), "Partition table size too large."); | ||
441 | partition_tb = __va(memblock_alloc_base(patb_size, patb_size, | ||
442 | MEMBLOCK_ALLOC_ANYWHERE)); | ||
443 | |||
444 | /* Initialize the Partition Table with no entries */ | ||
445 | memset((void *)partition_tb, 0, patb_size); | ||
446 | |||
447 | /* | ||
448 | * update partition table control register, | ||
449 | * 64 K size. | ||
450 | */ | ||
451 | mtspr(SPRN_PTCR, __pa(partition_tb) | (PATB_SIZE_SHIFT - 12)); | ||
452 | } | ||
453 | |||
454 | void mmu_partition_table_set_entry(unsigned int lpid, unsigned long dw0, | ||
455 | unsigned long dw1) | ||
456 | { | ||
457 | partition_tb[lpid].patb0 = cpu_to_be64(dw0); | ||
458 | partition_tb[lpid].patb1 = cpu_to_be64(dw1); | ||
459 | |||
460 | /* Global flush of TLBs and partition table caches for this lpid */ | ||
461 | asm volatile("ptesync" : : : "memory"); | ||
462 | asm volatile(PPC_TLBIE_5(%0,%1,2,0,0) : : | ||
463 | "r" (TLBIEL_INVAL_SET_LPID), "r" (lpid)); | ||
464 | asm volatile("eieio; tlbsync; ptesync" : : : "memory"); | ||
465 | } | ||
466 | EXPORT_SYMBOL_GPL(mmu_partition_table_set_entry); | ||
467 | #endif /* CONFIG_PPC_BOOK3S_64 */ | ||
diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S index 44d2d842cee7..3aa40f1b20f5 100644 --- a/arch/powerpc/platforms/powernv/opal-wrappers.S +++ b/arch/powerpc/platforms/powernv/opal-wrappers.S | |||
@@ -304,8 +304,11 @@ OPAL_CALL(opal_pci_get_presence_state, OPAL_PCI_GET_PRESENCE_STATE); | |||
304 | OPAL_CALL(opal_pci_get_power_state, OPAL_PCI_GET_POWER_STATE); | 304 | OPAL_CALL(opal_pci_get_power_state, OPAL_PCI_GET_POWER_STATE); |
305 | OPAL_CALL(opal_pci_set_power_state, OPAL_PCI_SET_POWER_STATE); | 305 | OPAL_CALL(opal_pci_set_power_state, OPAL_PCI_SET_POWER_STATE); |
306 | OPAL_CALL(opal_int_get_xirr, OPAL_INT_GET_XIRR); | 306 | OPAL_CALL(opal_int_get_xirr, OPAL_INT_GET_XIRR); |
307 | OPAL_CALL_REAL(opal_rm_int_get_xirr, OPAL_INT_GET_XIRR); | ||
307 | OPAL_CALL(opal_int_set_cppr, OPAL_INT_SET_CPPR); | 308 | OPAL_CALL(opal_int_set_cppr, OPAL_INT_SET_CPPR); |
308 | OPAL_CALL(opal_int_eoi, OPAL_INT_EOI); | 309 | OPAL_CALL(opal_int_eoi, OPAL_INT_EOI); |
310 | OPAL_CALL_REAL(opal_rm_int_eoi, OPAL_INT_EOI); | ||
309 | OPAL_CALL(opal_int_set_mfrr, OPAL_INT_SET_MFRR); | 311 | OPAL_CALL(opal_int_set_mfrr, OPAL_INT_SET_MFRR); |
312 | OPAL_CALL_REAL(opal_rm_int_set_mfrr, OPAL_INT_SET_MFRR); | ||
310 | OPAL_CALL(opal_pci_tce_kill, OPAL_PCI_TCE_KILL); | 313 | OPAL_CALL(opal_pci_tce_kill, OPAL_PCI_TCE_KILL); |
311 | OPAL_CALL_REAL(opal_rm_pci_tce_kill, OPAL_PCI_TCE_KILL); | 314 | OPAL_CALL_REAL(opal_rm_pci_tce_kill, OPAL_PCI_TCE_KILL); |
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c index 6c9a65b52e63..b3b8930ac52f 100644 --- a/arch/powerpc/platforms/powernv/opal.c +++ b/arch/powerpc/platforms/powernv/opal.c | |||
@@ -896,3 +896,5 @@ EXPORT_SYMBOL_GPL(opal_leds_get_ind); | |||
896 | EXPORT_SYMBOL_GPL(opal_leds_set_ind); | 896 | EXPORT_SYMBOL_GPL(opal_leds_set_ind); |
897 | /* Export this symbol for PowerNV Operator Panel class driver */ | 897 | /* Export this symbol for PowerNV Operator Panel class driver */ |
898 | EXPORT_SYMBOL_GPL(opal_write_oppanel_async); | 898 | EXPORT_SYMBOL_GPL(opal_write_oppanel_async); |
899 | /* Export this for KVM */ | ||
900 | EXPORT_SYMBOL_GPL(opal_int_set_mfrr); | ||
diff --git a/arch/powerpc/platforms/ps3/htab.c b/arch/powerpc/platforms/ps3/htab.c index cb3c50328de8..cc2b281a3766 100644 --- a/arch/powerpc/platforms/ps3/htab.c +++ b/arch/powerpc/platforms/ps3/htab.c | |||
@@ -63,7 +63,7 @@ static long ps3_hpte_insert(unsigned long hpte_group, unsigned long vpn, | |||
63 | vflags &= ~HPTE_V_SECONDARY; | 63 | vflags &= ~HPTE_V_SECONDARY; |
64 | 64 | ||
65 | hpte_v = hpte_encode_v(vpn, psize, apsize, ssize) | vflags | HPTE_V_VALID; | 65 | hpte_v = hpte_encode_v(vpn, psize, apsize, ssize) | vflags | HPTE_V_VALID; |
66 | hpte_r = hpte_encode_r(ps3_mm_phys_to_lpar(pa), psize, apsize, ssize) | rflags; | 66 | hpte_r = hpte_encode_r(ps3_mm_phys_to_lpar(pa), psize, apsize) | rflags; |
67 | 67 | ||
68 | spin_lock_irqsave(&ps3_htab_lock, flags); | 68 | spin_lock_irqsave(&ps3_htab_lock, flags); |
69 | 69 | ||
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index aa35245d8d6d..f2c98f6c1c9c 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c | |||
@@ -145,7 +145,7 @@ static long pSeries_lpar_hpte_insert(unsigned long hpte_group, | |||
145 | hpte_group, vpn, pa, rflags, vflags, psize); | 145 | hpte_group, vpn, pa, rflags, vflags, psize); |
146 | 146 | ||
147 | hpte_v = hpte_encode_v(vpn, psize, apsize, ssize) | vflags | HPTE_V_VALID; | 147 | hpte_v = hpte_encode_v(vpn, psize, apsize, ssize) | vflags | HPTE_V_VALID; |
148 | hpte_r = hpte_encode_r(pa, psize, apsize, ssize) | rflags; | 148 | hpte_r = hpte_encode_r(pa, psize, apsize) | rflags; |
149 | 149 | ||
150 | if (!(vflags & HPTE_V_BOLTED)) | 150 | if (!(vflags & HPTE_V_BOLTED)) |
151 | pr_devel(" hpte_v=%016lx, hpte_r=%016lx\n", hpte_v, hpte_r); | 151 | pr_devel(" hpte_v=%016lx, hpte_r=%016lx\n", hpte_v, hpte_r); |