|
@@ -17,10 +17,44 @@
|
|
|
#include <asm/proto.h>
|
|
|
#include <asm/dma.h> /* for MAX_DMA_PFN */
|
|
|
|
|
|
+#include "mm_internal.h"
|
|
|
+
|
|
|
unsigned long __initdata pgt_buf_start;
|
|
|
unsigned long __meminitdata pgt_buf_end;
|
|
|
unsigned long __meminitdata pgt_buf_top;
|
|
|
|
|
|
+__ref void *alloc_low_page(void)
|
|
|
+{
|
|
|
+ unsigned long pfn;
|
|
|
+ void *adr;
|
|
|
+
|
|
|
+#ifdef CONFIG_X86_64
|
|
|
+ if (after_bootmem) {
|
|
|
+ adr = (void *)get_zeroed_page(GFP_ATOMIC | __GFP_NOTRACK);
|
|
|
+
|
|
|
+ return adr;
|
|
|
+ }
|
|
|
+#endif
|
|
|
+
|
|
|
+ if ((pgt_buf_end + 1) >= pgt_buf_top) {
|
|
|
+ unsigned long ret;
|
|
|
+ if (min_pfn_mapped >= max_pfn_mapped)
|
|
|
+ panic("alloc_low_page: ran out of memory");
|
|
|
+ ret = memblock_find_in_range(min_pfn_mapped << PAGE_SHIFT,
|
|
|
+ max_pfn_mapped << PAGE_SHIFT,
|
|
|
+ PAGE_SIZE, PAGE_SIZE);
|
|
|
+ if (!ret)
|
|
|
+ panic("alloc_low_page: can not alloc memory");
|
|
|
+ memblock_reserve(ret, PAGE_SIZE);
|
|
|
+ pfn = ret >> PAGE_SHIFT;
|
|
|
+ } else
|
|
|
+ pfn = pgt_buf_end++;
|
|
|
+
|
|
|
+ adr = __va(pfn * PAGE_SIZE);
|
|
|
+ clear_page(adr);
|
|
|
+ return adr;
|
|
|
+}
|
|
|
+
|
|
|
/* need 4 4k for initial PMD_SIZE, 4k for 0-ISA_END_ADDRESS */
|
|
|
#define INIT_PGT_BUF_SIZE (5 * PAGE_SIZE)
|
|
|
RESERVE_BRK(early_pgt_alloc, INIT_PGT_BUF_SIZE);
|