mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-11-01 17:08:10 +00:00
powerpc/mm: implement set_memory_attr()
In addition to the set_memory_xx() functions which allows to change the memory attributes of not (yet) used memory regions, implement a set_memory_attr() function to: - set the final memory protection after init on currently used kernel regions. - enable/disable kernel memory regions in the scope of DEBUG_PAGEALLOC. Unlike the set_memory_xx() which can act in three step as the regions are unused, this function must modify 'on the fly' as the kernel is executing from them. At the moment only PPC32 will use it and changing page attributes on the fly is not an issue. Reported-by: kbuild test robot <lkp@intel.com> [ruscur: cast "data" to unsigned long instead of int] Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> Signed-off-by: Russell Currey <ruscur@russell.cc> Signed-off-by: Jordan Niethe <jniethe5@gmail.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/20210609013431.9805-9-jniethe5@gmail.com
This commit is contained in:
parent
c35717c71e
commit
4d1755b6a7
2 changed files with 35 additions and 0 deletions
|
@ -29,4 +29,6 @@ static inline int set_memory_x(unsigned long addr, int numpages)
|
|||
return change_memory_attr(addr, numpages, SET_MEMORY_X);
|
||||
}
|
||||
|
||||
int set_memory_attr(unsigned long addr, int numpages, pgprot_t prot);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -99,3 +99,36 @@ int change_memory_attr(unsigned long addr, int numpages, long action)
|
|||
return apply_to_existing_page_range(&init_mm, start, size,
|
||||
change_page_attr, (void *)action);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the attributes of a page:
|
||||
*
|
||||
* This function is used by PPC32 at the end of init to set final kernel memory
|
||||
* protection. It includes changing the maping of the page it is executing from
|
||||
* and data pages it is using.
|
||||
*/
|
||||
static int set_page_attr(pte_t *ptep, unsigned long addr, void *data)
|
||||
{
|
||||
pgprot_t prot = __pgprot((unsigned long)data);
|
||||
|
||||
spin_lock(&init_mm.page_table_lock);
|
||||
|
||||
set_pte_at(&init_mm, addr, ptep, pte_modify(*ptep, prot));
|
||||
flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
|
||||
|
||||
spin_unlock(&init_mm.page_table_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_memory_attr(unsigned long addr, int numpages, pgprot_t prot)
|
||||
{
|
||||
unsigned long start = ALIGN_DOWN(addr, PAGE_SIZE);
|
||||
unsigned long sz = numpages * PAGE_SIZE;
|
||||
|
||||
if (numpages <= 0)
|
||||
return 0;
|
||||
|
||||
return apply_to_existing_page_range(&init_mm, start, sz, set_page_attr,
|
||||
(void *)pgprot_val(prot));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue