Commit 86758b50 authored by Ryan Roberts's avatar Ryan Roberts Committed by Andrew Morton
Browse files

mm/ioremap: pass pgprot_t to ioremap_prot() instead of unsigned long

ioremap_prot() currently accepts pgprot_val parameter as an unsigned long,
thus implicitly assuming that pgprot_val and pgprot_t could never be
bigger than unsigned long.  But this assumption soon will not be true on
arm64 when using D128 pgtables.  In 128 bit page table configuration,
unsigned long is 64 bit, but pgprot_t is 128 bit.

Passing platform abstracted pgprot_t argument is better as compared to
size based data types.  Let's change the parameter to directly pass
pgprot_t like another similar helper generic_ioremap_prot().

Without this change in place, D128 configuration does not work on arm64 as
the top 64 bits gets silently stripped when passing the protection value
to this function.

Link: https://lkml.kernel.org/r/20250218101954.415331-1-anshuman.khandual@arm.com


Signed-off-by: default avatarRyan Roberts <ryan.roberts@arm.com>
Co-developed-by: default avatarAnshuman Khandual <anshuman.khandual@arm.com>
Signed-off-by: default avatarAnshuman Khandual <anshuman.khandual@arm.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com> [arm64]
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
parent af3b45aa
Loading
Loading
Loading
Loading
+2 −4
Original line number Diff line number Diff line
@@ -32,7 +32,7 @@ void __iomem *ioremap(phys_addr_t paddr, unsigned long size)
		return (void __iomem *)(u32)paddr;

	return ioremap_prot(paddr, size,
			    pgprot_val(pgprot_noncached(PAGE_KERNEL)));
			    pgprot_noncached(PAGE_KERNEL));
}
EXPORT_SYMBOL(ioremap);

@@ -44,10 +44,8 @@ EXPORT_SYMBOL(ioremap);
 * might need finer access control (R/W/X)
 */
void __iomem *ioremap_prot(phys_addr_t paddr, size_t size,
			   unsigned long flags)
			   pgprot_t prot)
{
	pgprot_t prot = __pgprot(flags);

	/* force uncached */
	return generic_ioremap_prot(paddr, size, pgprot_noncached(prot));
}
+3 −3
Original line number Diff line number Diff line
@@ -270,9 +270,9 @@ int arm64_ioremap_prot_hook_register(const ioremap_prot_hook_t hook);
#define _PAGE_IOREMAP PROT_DEVICE_nGnRE

#define ioremap_wc(addr, size)	\
	ioremap_prot((addr), (size), PROT_NORMAL_NC)
	ioremap_prot((addr), (size), __pgprot(PROT_NORMAL_NC))
#define ioremap_np(addr, size)	\
	ioremap_prot((addr), (size), PROT_DEVICE_nGnRnE)
	ioremap_prot((addr), (size), __pgprot(PROT_DEVICE_nGnRnE))

/*
 * io{read,write}{16,32,64}be() macros
@@ -293,7 +293,7 @@ static inline void __iomem *ioremap_cache(phys_addr_t addr, size_t size)
	if (pfn_is_map_memory(__phys_to_pfn(addr)))
		return (void __iomem *)__phys_to_virt(addr);

	return ioremap_prot(addr, size, PROT_NORMAL);
	return ioremap_prot(addr, size, __pgprot(PROT_NORMAL));
}

/*
+1 −1
Original line number Diff line number Diff line
@@ -379,7 +379,7 @@ void __iomem *acpi_os_ioremap(acpi_physical_address phys, acpi_size size)
				prot = __acpi_get_writethrough_mem_attribute();
		}
	}
	return ioremap_prot(phys, size, pgprot_val(prot));
	return ioremap_prot(phys, size, prot);
}

/*
+1 −2
Original line number Diff line number Diff line
@@ -15,10 +15,9 @@ int arm64_ioremap_prot_hook_register(ioremap_prot_hook_t hook)
}

void __iomem *ioremap_prot(phys_addr_t phys_addr, size_t size,
			   unsigned long prot)
			   pgprot_t pgprot)
{
	unsigned long last_addr = phys_addr + size - 1;
	pgprot_t pgprot = __pgprot(prot);

	/* Don't allow outside PHYS_MASK */
	if (last_addr & ~PHYS_MASK)
+1 −1
Original line number Diff line number Diff line
@@ -36,7 +36,7 @@
 */
#define ioremap_wc(addr, size) \
	ioremap_prot((addr), (size), \
		(_PAGE_IOREMAP & ~_CACHE_MASK) | _CACHE_UNCACHED)
		__pgprot((_PAGE_IOREMAP & ~_CACHE_MASK) | _CACHE_UNCACHED))

#include <asm-generic/io.h>

Loading