Commit ddd63c85 authored by Alexander Gordeev's avatar Alexander Gordeev Committed by Heiko Carstens
Browse files

s390/kasan: fix large PMD pages address alignment check



It is currently possible to initialize a large PMD page when
the address is not aligned on page boundary.

Signed-off-by: default avatarAlexander Gordeev <agordeev@linux.ibm.com>
Reviewed-by: default avatarVasily Gorbik <gor@linux.ibm.com>
Signed-off-by: default avatarVasily Gorbik <gor@linux.ibm.com>
Signed-off-by: default avatarHeiko Carstens <hca@linux.ibm.com>
parent c42257d6
Loading
Loading
Loading
Loading
+20 −21
Original line number Original line Diff line number Diff line
@@ -107,6 +107,9 @@ static void __init kasan_early_pgtable_populate(unsigned long address,
		sgt_prot &= ~_SEGMENT_ENTRY_NOEXEC;
		sgt_prot &= ~_SEGMENT_ENTRY_NOEXEC;
	}
	}


	/*
	 * The first 1MB of 1:1 mapping is mapped with 4KB pages
	 */
	while (address < end) {
	while (address < end) {
		pg_dir = pgd_offset_k(address);
		pg_dir = pgd_offset_k(address);
		if (pgd_none(*pg_dir)) {
		if (pgd_none(*pg_dir)) {
@@ -157,17 +160,13 @@ static void __init kasan_early_pgtable_populate(unsigned long address,


		pm_dir = pmd_offset(pu_dir, address);
		pm_dir = pmd_offset(pu_dir, address);
		if (pmd_none(*pm_dir)) {
		if (pmd_none(*pm_dir)) {
			if (mode == POPULATE_ZERO_SHADOW &&
			if (IS_ALIGNED(address, PMD_SIZE) &&
			    IS_ALIGNED(address, PMD_SIZE) &&
			    end - address >= PMD_SIZE) {
			    end - address >= PMD_SIZE) {
				pmd_populate(&init_mm, pm_dir,
				if (mode == POPULATE_ZERO_SHADOW) {
						kasan_early_shadow_pte);
					pmd_populate(&init_mm, pm_dir, kasan_early_shadow_pte);
					address = (address + PMD_SIZE) & PMD_MASK;
					address = (address + PMD_SIZE) & PMD_MASK;
					continue;
					continue;
			}
				} else if (has_edat && address) {
			/* the first megabyte of 1:1 is mapped with 4k pages */
			if (has_edat && address && end - address >= PMD_SIZE &&
			    mode != POPULATE_ZERO_SHADOW) {
					void *page;
					void *page;


					if (mode == POPULATE_ONE2ONE) {
					if (mode == POPULATE_ONE2ONE) {
@@ -180,7 +179,7 @@ static void __init kasan_early_pgtable_populate(unsigned long address,
					address = (address + PMD_SIZE) & PMD_MASK;
					address = (address + PMD_SIZE) & PMD_MASK;
					continue;
					continue;
				}
				}

			}
			pt_dir = kasan_early_pte_alloc();
			pt_dir = kasan_early_pte_alloc();
			pmd_populate(&init_mm, pm_dir, pt_dir);
			pmd_populate(&init_mm, pm_dir, pt_dir);
		} else if (pmd_large(*pm_dir)) {
		} else if (pmd_large(*pm_dir)) {