aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBadari Pulavarty <pbadari@us.ibm.com>2008-01-28 17:19:24 -0500
committerPaul Mackerras <paulus@samba.org>2008-02-26 06:17:03 -0500
commitf8c8803bda4db47cbbdadb9b27b024e903e1d645 (patch)
tree394411edf1626257193e904e25a4dc763528e34f
parentf8303dd3db57bd7ab2062985ad7a9e898a8ac423 (diff)
[POWERPC] Add code for removing HPTEs for parts of the linear mapping
For memory remove, we need to clean up htab mappings for the section of the memory we are removing. This implements support for removing htab bolted mappings for pSeries logical partitions. Other sub-archs may need to implement similar functionality for hotplug memory remove to work on them. Signed-off-by: Badari Pulavarty <pbadari@us.ibm.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
-rw-r--r--arch/powerpc/mm/hash_utils_64.c23
-rw-r--r--arch/powerpc/platforms/pseries/lpar.c15
-rw-r--r--include/asm-powerpc/machdep.h2
-rw-r--r--include/asm-powerpc/sparsemem.h1
4 files changed, 41 insertions, 0 deletions
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index 73b78486abfc..4cc53f92377e 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -192,6 +192,24 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
192 return ret < 0 ? ret : 0; 192 return ret < 0 ? ret : 0;
193} 193}
194 194
195static void htab_remove_mapping(unsigned long vstart, unsigned long vend,
196 int psize, int ssize)
197{
198 unsigned long vaddr;
199 unsigned int step, shift;
200
201 shift = mmu_psize_defs[psize].shift;
202 step = 1 << shift;
203
204 if (!ppc_md.hpte_removebolted) {
205 printk("Sub-arch doesn't implement hpte_removebolted\n");
206 return;
207 }
208
209 for (vaddr = vstart; vaddr < vend; vaddr += step)
210 ppc_md.hpte_removebolted(vaddr, psize, ssize);
211}
212
195static int __init htab_dt_scan_seg_sizes(unsigned long node, 213static int __init htab_dt_scan_seg_sizes(unsigned long node,
196 const char *uname, int depth, 214 const char *uname, int depth,
197 void *data) 215 void *data)
@@ -430,6 +448,11 @@ void create_section_mapping(unsigned long start, unsigned long end)
430 _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | PP_RWXX, 448 _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | PP_RWXX,
431 mmu_linear_psize, mmu_kernel_ssize)); 449 mmu_linear_psize, mmu_kernel_ssize));
432} 450}
451
452void remove_section_mapping(unsigned long start, unsigned long end)
453{
454 htab_remove_mapping(start, end, mmu_linear_psize, mmu_kernel_ssize);
455}
433#endif /* CONFIG_MEMORY_HOTPLUG */ 456#endif /* CONFIG_MEMORY_HOTPLUG */
434 457
435static inline void make_bl(unsigned int *insn_addr, void *func) 458static inline void make_bl(unsigned int *insn_addr, void *func)
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index 9a455d46379d..233d9be25f49 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -520,6 +520,20 @@ static void pSeries_lpar_hpte_invalidate(unsigned long slot, unsigned long va,
520 BUG_ON(lpar_rc != H_SUCCESS); 520 BUG_ON(lpar_rc != H_SUCCESS);
521} 521}
522 522
523static void pSeries_lpar_hpte_removebolted(unsigned long ea,
524 int psize, int ssize)
525{
526 unsigned long slot, vsid, va;
527
528 vsid = get_kernel_vsid(ea, ssize);
529 va = hpt_va(ea, vsid, ssize);
530
531 slot = pSeries_lpar_hpte_find(va, psize, ssize);
532 BUG_ON(slot == -1);
533
534 pSeries_lpar_hpte_invalidate(slot, va, psize, ssize, 0);
535}
536
523/* Flag bits for H_BULK_REMOVE */ 537/* Flag bits for H_BULK_REMOVE */
524#define HBR_REQUEST 0x4000000000000000UL 538#define HBR_REQUEST 0x4000000000000000UL
525#define HBR_RESPONSE 0x8000000000000000UL 539#define HBR_RESPONSE 0x8000000000000000UL
@@ -597,6 +611,7 @@ void __init hpte_init_lpar(void)
597 ppc_md.hpte_updateboltedpp = pSeries_lpar_hpte_updateboltedpp; 611 ppc_md.hpte_updateboltedpp = pSeries_lpar_hpte_updateboltedpp;
598 ppc_md.hpte_insert = pSeries_lpar_hpte_insert; 612 ppc_md.hpte_insert = pSeries_lpar_hpte_insert;
599 ppc_md.hpte_remove = pSeries_lpar_hpte_remove; 613 ppc_md.hpte_remove = pSeries_lpar_hpte_remove;
614 ppc_md.hpte_removebolted = pSeries_lpar_hpte_removebolted;
600 ppc_md.flush_hash_range = pSeries_lpar_flush_hash_range; 615 ppc_md.flush_hash_range = pSeries_lpar_flush_hash_range;
601 ppc_md.hpte_clear_all = pSeries_lpar_hptab_clear; 616 ppc_md.hpte_clear_all = pSeries_lpar_hptab_clear;
602} 617}
diff --git a/include/asm-powerpc/machdep.h b/include/asm-powerpc/machdep.h
index 0872ec228c1e..b95386aed50d 100644
--- a/include/asm-powerpc/machdep.h
+++ b/include/asm-powerpc/machdep.h
@@ -68,6 +68,8 @@ struct machdep_calls {
68 unsigned long vflags, 68 unsigned long vflags,
69 int psize, int ssize); 69 int psize, int ssize);
70 long (*hpte_remove)(unsigned long hpte_group); 70 long (*hpte_remove)(unsigned long hpte_group);
71 void (*hpte_removebolted)(unsigned long ea,
72 int psize, int ssize);
71 void (*flush_hash_range)(unsigned long number, int local); 73 void (*flush_hash_range)(unsigned long number, int local);
72 74
73 /* special for kexec, to be called in real mode, linar mapping is 75 /* special for kexec, to be called in real mode, linar mapping is
diff --git a/include/asm-powerpc/sparsemem.h b/include/asm-powerpc/sparsemem.h
index e8b493d52b4f..c5acf4ccf571 100644
--- a/include/asm-powerpc/sparsemem.h
+++ b/include/asm-powerpc/sparsemem.h
@@ -15,6 +15,7 @@
15 15
16#ifdef CONFIG_MEMORY_HOTPLUG 16#ifdef CONFIG_MEMORY_HOTPLUG
17extern void create_section_mapping(unsigned long start, unsigned long end); 17extern void create_section_mapping(unsigned long start, unsigned long end);
18extern void remove_section_mapping(unsigned long start, unsigned long end);
18#ifdef CONFIG_NUMA 19#ifdef CONFIG_NUMA
19extern int hot_add_scn_to_nid(unsigned long scn_addr); 20extern int hot_add_scn_to_nid(unsigned long scn_addr);
20#else 21#else