Commit f8c8803b authored by Badari Pulavarty's avatar Badari Pulavarty Committed by Paul Mackerras

[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: default avatarBadari Pulavarty <pbadari@us.ibm.com>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent f8303dd3
...@@ -192,6 +192,24 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend, ...@@ -192,6 +192,24 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
return ret < 0 ? ret : 0; 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, static int __init htab_dt_scan_seg_sizes(unsigned long node,
const char *uname, int depth, const char *uname, int depth,
void *data) void *data)
...@@ -430,6 +448,11 @@ void create_section_mapping(unsigned long start, unsigned long end) ...@@ -430,6 +448,11 @@ void create_section_mapping(unsigned long start, unsigned long end)
_PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | PP_RWXX, _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | PP_RWXX,
mmu_linear_psize, mmu_kernel_ssize)); 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 */ #endif /* CONFIG_MEMORY_HOTPLUG */
static inline void make_bl(unsigned int *insn_addr, void *func) static inline void make_bl(unsigned int *insn_addr, void *func)
......
...@@ -520,6 +520,20 @@ static void pSeries_lpar_hpte_invalidate(unsigned long slot, unsigned long va, ...@@ -520,6 +520,20 @@ static void pSeries_lpar_hpte_invalidate(unsigned long slot, unsigned long va,
BUG_ON(lpar_rc != H_SUCCESS); 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 */ /* Flag bits for H_BULK_REMOVE */
#define HBR_REQUEST 0x4000000000000000UL #define HBR_REQUEST 0x4000000000000000UL
#define HBR_RESPONSE 0x8000000000000000UL #define HBR_RESPONSE 0x8000000000000000UL
...@@ -597,6 +611,7 @@ void __init hpte_init_lpar(void) ...@@ -597,6 +611,7 @@ void __init hpte_init_lpar(void)
ppc_md.hpte_updateboltedpp = pSeries_lpar_hpte_updateboltedpp; ppc_md.hpte_updateboltedpp = pSeries_lpar_hpte_updateboltedpp;
ppc_md.hpte_insert = pSeries_lpar_hpte_insert; ppc_md.hpte_insert = pSeries_lpar_hpte_insert;
ppc_md.hpte_remove = pSeries_lpar_hpte_remove; 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.flush_hash_range = pSeries_lpar_flush_hash_range;
ppc_md.hpte_clear_all = pSeries_lpar_hptab_clear; ppc_md.hpte_clear_all = pSeries_lpar_hptab_clear;
} }
...@@ -68,6 +68,8 @@ struct machdep_calls { ...@@ -68,6 +68,8 @@ struct machdep_calls {
unsigned long vflags, unsigned long vflags,
int psize, int ssize); int psize, int ssize);
long (*hpte_remove)(unsigned long hpte_group); 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); void (*flush_hash_range)(unsigned long number, int local);
/* special for kexec, to be called in real mode, linar mapping is /* special for kexec, to be called in real mode, linar mapping is
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#ifdef CONFIG_MEMORY_HOTPLUG #ifdef CONFIG_MEMORY_HOTPLUG
extern void create_section_mapping(unsigned long start, unsigned long end); 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 #ifdef CONFIG_NUMA
extern int hot_add_scn_to_nid(unsigned long scn_addr); extern int hot_add_scn_to_nid(unsigned long scn_addr);
#else #else
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment