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)
                        _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)
 
        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
        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;
 }
 
                                       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
 
 
 #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