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

[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
...@@ -160,12 +160,25 @@ static inline __deprecated void *bus_to_virt(unsigned long x) ...@@ -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)
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment