diff options
-rw-r--r-- | arch/powerpc/platforms/pseries/lpar.c | 17 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/plpar_wrappers.h | 15 | ||||
-rw-r--r-- | include/asm-powerpc/mmu-hash64.h | 3 |
3 files changed, 32 insertions, 3 deletions
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index 362dfbc260a6..8cc6eeeaae2f 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c | |||
@@ -373,12 +373,23 @@ static void pSeries_lpar_hptab_clear(void) | |||
373 | { | 373 | { |
374 | unsigned long size_bytes = 1UL << ppc64_pft_size; | 374 | unsigned long size_bytes = 1UL << ppc64_pft_size; |
375 | unsigned long hpte_count = size_bytes >> 4; | 375 | unsigned long hpte_count = size_bytes >> 4; |
376 | unsigned long dummy1, dummy2; | 376 | unsigned long dummy1, dummy2, dword0; |
377 | long lpar_rc; | ||
377 | int i; | 378 | int i; |
378 | 379 | ||
379 | /* TODO: Use bulk call */ | 380 | /* TODO: Use bulk call */ |
380 | for (i = 0; i < hpte_count; i++) | 381 | for (i = 0; i < hpte_count; i++) { |
381 | plpar_pte_remove_raw(0, i, 0, &dummy1, &dummy2); | 382 | /* dont remove HPTEs with VRMA mappings */ |
383 | lpar_rc = plpar_pte_remove_raw(H_ANDCOND, i, HPTE_V_1TB_SEG, | ||
384 | &dummy1, &dummy2); | ||
385 | if (lpar_rc == H_NOT_FOUND) { | ||
386 | lpar_rc = plpar_pte_read_raw(0, i, &dword0, &dummy1); | ||
387 | if (!lpar_rc && ((dword0 & HPTE_V_VRMA_MASK) | ||
388 | != HPTE_V_VRMA_MASK)) | ||
389 | /* Can be hpte for 1TB Seg. So remove it */ | ||
390 | plpar_pte_remove_raw(0, i, 0, &dummy1, &dummy2); | ||
391 | } | ||
392 | } | ||
382 | } | 393 | } |
383 | 394 | ||
384 | /* | 395 | /* |
diff --git a/arch/powerpc/platforms/pseries/plpar_wrappers.h b/arch/powerpc/platforms/pseries/plpar_wrappers.h index 2e4d10c9eea8..d003c80fa31d 100644 --- a/arch/powerpc/platforms/pseries/plpar_wrappers.h +++ b/arch/powerpc/platforms/pseries/plpar_wrappers.h | |||
@@ -108,6 +108,21 @@ static inline long plpar_pte_read(unsigned long flags, unsigned long ptex, | |||
108 | return rc; | 108 | return rc; |
109 | } | 109 | } |
110 | 110 | ||
111 | /* plpar_pte_read_raw can be called in real mode. It calls plpar_hcall_raw */ | ||
112 | static inline long plpar_pte_read_raw(unsigned long flags, unsigned long ptex, | ||
113 | unsigned long *old_pteh_ret, unsigned long *old_ptel_ret) | ||
114 | { | ||
115 | long rc; | ||
116 | unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; | ||
117 | |||
118 | rc = plpar_hcall_raw(H_READ, retbuf, flags, ptex); | ||
119 | |||
120 | *old_pteh_ret = retbuf[0]; | ||
121 | *old_ptel_ret = retbuf[1]; | ||
122 | |||
123 | return rc; | ||
124 | } | ||
125 | |||
111 | static inline long plpar_pte_protect(unsigned long flags, unsigned long ptex, | 126 | static inline long plpar_pte_protect(unsigned long flags, unsigned long ptex, |
112 | unsigned long avpn) | 127 | unsigned long avpn) |
113 | { | 128 | { |
diff --git a/include/asm-powerpc/mmu-hash64.h b/include/asm-powerpc/mmu-hash64.h index ba32019c51dd..695962f02059 100644 --- a/include/asm-powerpc/mmu-hash64.h +++ b/include/asm-powerpc/mmu-hash64.h | |||
@@ -94,6 +94,9 @@ extern char initial_stab[]; | |||
94 | #define HPTE_R_C ASM_CONST(0x0000000000000080) | 94 | #define HPTE_R_C ASM_CONST(0x0000000000000080) |
95 | #define HPTE_R_R ASM_CONST(0x0000000000000100) | 95 | #define HPTE_R_R ASM_CONST(0x0000000000000100) |
96 | 96 | ||
97 | #define HPTE_V_1TB_SEG ASM_CONST(0x4000000000000000) | ||
98 | #define HPTE_V_VRMA_MASK ASM_CONST(0x4001ffffff000000) | ||
99 | |||
97 | /* Values for PP (assumes Ks=0, Kp=1) */ | 100 | /* Values for PP (assumes Ks=0, Kp=1) */ |
98 | /* pp0 will always be 0 for linux */ | 101 | /* pp0 will always be 0 for linux */ |
99 | #define PP_RWXX 0 /* Supervisor read/write, User none */ | 102 | #define PP_RWXX 0 /* Supervisor read/write, User none */ |