]> err.no Git - linux-2.6/commitdiff
[POWERPC] Add code for removing HPTEs for parts of the linear mapping
authorBadari Pulavarty <pbadari@us.ibm.com>
Mon, 28 Jan 2008 22:19:24 +0000 (09:19 +1100)
committerPaul Mackerras <paulus@samba.org>
Tue, 26 Feb 2008 11:17:03 +0000 (22:17 +1100)
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>
arch/powerpc/mm/hash_utils_64.c
arch/powerpc/platforms/pseries/lpar.c
include/asm-powerpc/machdep.h
include/asm-powerpc/sparsemem.h

index 73b78486abfc5b6ee4283d24e35cb30021f6f8ea..4cc53f92377e7d65eef6c46c3bdf3f26a4d0c018 100644 (file)
@@ -192,6 +192,24 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
        return ret < 0 ? ret : 0;
 }
 
+static void htab_remove_mapping(unsigned long vstart, unsigned long vend,
+                     int psize, int ssize)
+{
+       unsigned long vaddr;
+       unsigned int step, shift;
+
+       shift = mmu_psize_defs[psize].shift;
+       step = 1 << shift;
+
+       if (!ppc_md.hpte_removebolted) {
+               printk("Sub-arch doesn't implement hpte_removebolted\n");
+               return;
+       }
+
+       for (vaddr = vstart; vaddr < vend; vaddr += step)
+               ppc_md.hpte_removebolted(vaddr, psize, ssize);
+}
+
 static int __init htab_dt_scan_seg_sizes(unsigned long node,
                                         const char *uname, int depth,
                                         void *data)
@@ -430,6 +448,11 @@ void create_section_mapping(unsigned long start, unsigned long end)
                        _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | PP_RWXX,
                        mmu_linear_psize, mmu_kernel_ssize));
 }
+
+void remove_section_mapping(unsigned long start, unsigned long end)
+{
+       htab_remove_mapping(start, end, mmu_linear_psize, mmu_kernel_ssize);
+}
 #endif /* CONFIG_MEMORY_HOTPLUG */
 
 static inline void make_bl(unsigned int *insn_addr, void *func)
index 9a455d46379d525181a4278714e22304f72028db..233d9be25f49248958f93eb91d55a92c8d5ebde6 100644 (file)
@@ -520,6 +520,20 @@ static void pSeries_lpar_hpte_invalidate(unsigned long slot, unsigned long va,
        BUG_ON(lpar_rc != H_SUCCESS);
 }
 
+static void pSeries_lpar_hpte_removebolted(unsigned long ea,
+                                          int psize, int ssize)
+{
+       unsigned long slot, vsid, va;
+
+       vsid = get_kernel_vsid(ea, ssize);
+       va = hpt_va(ea, vsid, ssize);
+
+       slot = pSeries_lpar_hpte_find(va, psize, ssize);
+       BUG_ON(slot == -1);
+
+       pSeries_lpar_hpte_invalidate(slot, va, psize, ssize, 0);
+}
+
 /* Flag bits for H_BULK_REMOVE */
 #define HBR_REQUEST    0x4000000000000000UL
 #define HBR_RESPONSE   0x8000000000000000UL
@@ -597,6 +611,7 @@ void __init hpte_init_lpar(void)
        ppc_md.hpte_updateboltedpp = pSeries_lpar_hpte_updateboltedpp;
        ppc_md.hpte_insert      = pSeries_lpar_hpte_insert;
        ppc_md.hpte_remove      = pSeries_lpar_hpte_remove;
+       ppc_md.hpte_removebolted = pSeries_lpar_hpte_removebolted;
        ppc_md.flush_hash_range = pSeries_lpar_flush_hash_range;
        ppc_md.hpte_clear_all   = pSeries_lpar_hptab_clear;
 }
index 0872ec228c1e45d1e27c094f37a8c948823850bf..b95386aed50d15bd1063ea39d228e189d6df1491 100644 (file)
@@ -68,6 +68,8 @@ struct machdep_calls {
                                       unsigned long vflags,
                                       int psize, int ssize);
        long            (*hpte_remove)(unsigned long hpte_group);
+       void            (*hpte_removebolted)(unsigned long ea,
+                                            int psize, int ssize);
        void            (*flush_hash_range)(unsigned long number, int local);
 
        /* special for kexec, to be called in real mode, linar mapping is
index e8b493d52b4f68a6807ed25475262b47e4defbd7..c5acf4ccf57198dba85e3ce895de6aefbb433609 100644 (file)
@@ -15,6 +15,7 @@
 
 #ifdef CONFIG_MEMORY_HOTPLUG
 extern void create_section_mapping(unsigned long start, unsigned long end);
+extern void remove_section_mapping(unsigned long start, unsigned long end);
 #ifdef CONFIG_NUMA
 extern int hot_add_scn_to_nid(unsigned long scn_addr);
 #else