Skip to content

Commit 340a982

Browse files
giuliobenettiRussell King (Oracle)
authored andcommitted
ARM: 9266/1: mm: fix no-MMU ZERO_PAGE() implementation
Actually in no-MMU SoCs(i.e. i.MXRT) ZERO_PAGE(vaddr) expands to ``` virt_to_page(0) ``` that in order expands to: ``` pfn_to_page(virt_to_pfn(0)) ``` and then virt_to_pfn(0) to: ``` ((((unsigned long)(0) - PAGE_OFFSET) >> PAGE_SHIFT) + PHYS_PFN_OFFSET) ``` where PAGE_OFFSET and PHYS_PFN_OFFSET are the DRAM offset(0x80000000) and PAGE_SHIFT is 12. This way we obtain 16MB(0x01000000) summed to the base of DRAM(0x80000000). When ZERO_PAGE(0) is then used, for example in bio_add_page(), the page gets an address that is out of DRAM bounds. So instead of using fake virtual page 0 let's allocate a dedicated zero_page during paging_init() and assign it to a global 'struct page * empty_zero_page' the same way mmu.c does and it's the same approach used in m68k with commit dc068f4 as discussed here[0]. Then let's move ZERO_PAGE() definition to the top of pgtable.h to be in common between mmu.c and nommu.c. [0]: https://lore.kernel.org/linux-m68k/[email protected]/T/#m1266ceb63 ad140743174d6b3070364d3c9a5179b Signed-off-by: Giulio Benetti <[email protected]> Reviewed-by: Arnd Bergmann <[email protected]> Signed-off-by: Russell King (Oracle) <[email protected]>
1 parent 612695b commit 340a982

File tree

3 files changed

+28
-13
lines changed

3 files changed

+28
-13
lines changed

arch/arm/include/asm/pgtable-nommu.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,6 @@
4444

4545
typedef pte_t *pte_addr_t;
4646

47-
/*
48-
* ZERO_PAGE is a global shared page that is always zero: used
49-
* for zero-mapped memory areas etc..
50-
*/
51-
#define ZERO_PAGE(vaddr) (virt_to_page(0))
52-
5347
/*
5448
* Mark the prot value as uncacheable and unbufferable.
5549
*/

arch/arm/include/asm/pgtable.h

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,15 @@
1010
#include <linux/const.h>
1111
#include <asm/proc-fns.h>
1212

13+
#ifndef __ASSEMBLY__
14+
/*
15+
* ZERO_PAGE is a global shared page that is always zero: used
16+
* for zero-mapped memory areas etc..
17+
*/
18+
extern struct page *empty_zero_page;
19+
#define ZERO_PAGE(vaddr) (empty_zero_page)
20+
#endif
21+
1322
#ifndef CONFIG_MMU
1423

1524
#include <asm-generic/pgtable-nopud.h>
@@ -139,13 +148,6 @@ extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
139148
*/
140149

141150
#ifndef __ASSEMBLY__
142-
/*
143-
* ZERO_PAGE is a global shared page that is always zero: used
144-
* for zero-mapped memory areas etc..
145-
*/
146-
extern struct page *empty_zero_page;
147-
#define ZERO_PAGE(vaddr) (empty_zero_page)
148-
149151

150152
extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
151153

arch/arm/mm/nommu.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,13 @@
2626

2727
unsigned long vectors_base;
2828

29+
/*
30+
* empty_zero_page is a special page that is used for
31+
* zero-initialized data and COW.
32+
*/
33+
struct page *empty_zero_page;
34+
EXPORT_SYMBOL(empty_zero_page);
35+
2936
#ifdef CONFIG_ARM_MPU
3037
struct mpu_rgn_info mpu_rgn_info;
3138
#endif
@@ -148,9 +155,21 @@ void __init adjust_lowmem_bounds(void)
148155
*/
149156
void __init paging_init(const struct machine_desc *mdesc)
150157
{
158+
void *zero_page;
159+
151160
early_trap_init((void *)vectors_base);
152161
mpu_setup();
162+
163+
/* allocate the zero page. */
164+
zero_page = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
165+
if (!zero_page)
166+
panic("%s: Failed to allocate %lu bytes align=0x%lx\n",
167+
__func__, PAGE_SIZE, PAGE_SIZE);
168+
153169
bootmem_init();
170+
171+
empty_zero_page = virt_to_page(zero_page);
172+
flush_dcache_page(empty_zero_page);
154173
}
155174

156175
/*

0 commit comments

Comments
 (0)