Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1b3cb73f authored by Russell King's avatar Russell King Committed by Russell King
Browse files

[ARM] Tighten pfn_valid() test.



Thomas Gleixner reported that mmaping and unmapping each physical
page in turn eventually caused the kernel to oops.  It appears
that pfn_valid() in the discontigmem case was too simplistic for
proper operation.

Tighten the logic so we also check if the PFN is within the range
of the selected memory node.

Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 13b9d47e
Loading
Loading
Loading
Loading
+14 −1
Original line number Original line Diff line number Diff line
@@ -160,12 +160,25 @@ static inline __deprecated void *bus_to_virt(unsigned long x)
#define page_to_pfn(page)					\
#define page_to_pfn(page)					\
	(( (page) - page_zone(page)->zone_mem_map)		\
	(( (page) - page_zone(page)->zone_mem_map)		\
	  + page_zone(page)->zone_start_pfn)
	  + page_zone(page)->zone_start_pfn)

#define pfn_to_page(pfn)					\
#define pfn_to_page(pfn)					\
	(PFN_TO_MAPBASE(pfn) + LOCAL_MAP_NR((pfn) << PAGE_SHIFT))
	(PFN_TO_MAPBASE(pfn) + LOCAL_MAP_NR((pfn) << PAGE_SHIFT))
#define pfn_valid(pfn)		(PFN_TO_NID(pfn) < MAX_NUMNODES)

#define pfn_valid(pfn)						\
	({							\
		unsigned int nid = PFN_TO_NID(pfn);		\
		int valid = nid < MAX_NUMNODES;			\
		if (valid) {					\
			pg_data_t *node = NODE_DATA(nid);	\
			valid = (pfn - node->node_start_pfn) <	\
				node->node_spanned_pages;	\
		}						\
		valid;						\
	})


#define virt_to_page(kaddr)					\
#define virt_to_page(kaddr)					\
	(ADDR_TO_MAPBASE(kaddr) + LOCAL_MAP_NR(kaddr))
	(ADDR_TO_MAPBASE(kaddr) + LOCAL_MAP_NR(kaddr))

#define virt_addr_valid(kaddr)	(KVADDR_TO_NID(kaddr) < MAX_NUMNODES)
#define virt_addr_valid(kaddr)	(KVADDR_TO_NID(kaddr) < MAX_NUMNODES)


/*
/*