mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-20 14:16:02 +00:00
s390/mm,vmem: fix vmem_add_mem()/vmem_remove_range()
vmem_add_mem() should only then insert a large page if pmd_none() is true for the specific entry. We might have a leftover from a previous mapping. In addition make vmem_remove_range()'s page table walk code more complete and fix a couple of potential endless loops (which can never happen :). Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
parent
c972cc60c2
commit
fc7e48aad3
1 changed files with 12 additions and 4 deletions
|
@ -109,8 +109,8 @@ static int vmem_add_mem(unsigned long start, unsigned long size, int ro)
|
|||
pm_dir = pmd_offset(pu_dir, address);
|
||||
|
||||
#if defined(CONFIG_64BIT) && !defined(CONFIG_DEBUG_PAGEALLOC)
|
||||
if (MACHINE_HAS_EDAT1 && address && !(address & ~PMD_MASK) &&
|
||||
(address + PMD_SIZE <= end)) {
|
||||
if (MACHINE_HAS_EDAT1 && pmd_none(*pm_dir) && address &&
|
||||
!(address & ~PMD_MASK) && (address + PMD_SIZE <= end)) {
|
||||
pte_val(pte) |= _SEGMENT_ENTRY_LARGE;
|
||||
pmd_val(*pm_dir) = pte_val(pte);
|
||||
address += PMD_SIZE;
|
||||
|
@ -151,12 +151,20 @@ static void vmem_remove_range(unsigned long start, unsigned long size)
|
|||
pte_val(pte) = _PAGE_TYPE_EMPTY;
|
||||
while (address < end) {
|
||||
pg_dir = pgd_offset_k(address);
|
||||
if (pgd_none(*pg_dir)) {
|
||||
address += PGDIR_SIZE;
|
||||
continue;
|
||||
}
|
||||
pu_dir = pud_offset(pg_dir, address);
|
||||
if (pud_none(*pu_dir))
|
||||
if (pud_none(*pu_dir)) {
|
||||
address += PUD_SIZE;
|
||||
continue;
|
||||
}
|
||||
pm_dir = pmd_offset(pu_dir, address);
|
||||
if (pmd_none(*pm_dir))
|
||||
if (pmd_none(*pm_dir)) {
|
||||
address += PMD_SIZE;
|
||||
continue;
|
||||
}
|
||||
if (pmd_large(*pm_dir)) {
|
||||
pmd_clear(pm_dir);
|
||||
address += PMD_SIZE;
|
||||
|
|
Loading…
Reference in a new issue