From: David Howells <dhowells@redhat.com>

The attached patch fixes a number of problems in the VM routines:

 (1) Some inline funcs don't compile if CONFIG_MMU is not set.

 (2) swapper_pml4 needn't exist if CONFIG_MMU is not set.

 (3) __free_pages_ok() doesn't counter set_page_refs() different behaviour if
     CONFIG_MMU is not set.

 (4) swsusp.c invokes TLB flushing functions without including the header file
     that declares them.

Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/init/Kconfig          |    5 +++--
 25-akpm/kernel/power/swsusp.c |    1 +
 25-akpm/kernel/sysctl.c       |    4 ++++
 25-akpm/mm/Makefile           |    4 ++--
 25-akpm/mm/bootmem.c          |   10 ++++++----
 25-akpm/mm/internal.h         |   13 +++++++++++++
 25-akpm/mm/page_alloc.c       |   13 +++++++++++--
 25-akpm/mm/tiny-shmem.c       |    2 ++
 8 files changed, 42 insertions(+), 10 deletions(-)

diff -puN init/Kconfig~vm-routine-fixes init/Kconfig
--- 25/init/Kconfig~vm-routine-fixes	2005-01-01 21:21:48.771479272 -0800
+++ 25-akpm/init/Kconfig	2005-01-01 21:21:48.784477296 -0800
@@ -316,8 +316,9 @@ config CC_OPTIMIZE_FOR_SIZE
 	  If unsure, say N.
 
 config SHMEM
-	default y
-	bool "Use full shmem filesystem" if EMBEDDED && MMU
+	bool "Use full shmem filesystem"
+	default y if EMBEDDED
+	depends on MMU
 	help
 	  The shmem is an internal filesystem used to manage shared memory.
 	  It is backed by swap and manages resource limits. It is also exported
diff -puN kernel/power/swsusp.c~vm-routine-fixes kernel/power/swsusp.c
--- 25/kernel/power/swsusp.c~vm-routine-fixes	2005-01-01 21:21:48.773478968 -0800
+++ 25-akpm/kernel/power/swsusp.c	2005-01-01 21:21:48.785477144 -0800
@@ -67,6 +67,7 @@
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
 #include <asm/pgtable.h>
+#include <asm/tlbflush.h>
 #include <asm/io.h>
 
 #include "power.h"
diff -puN kernel/sysctl.c~vm-routine-fixes kernel/sysctl.c
--- 25/kernel/sysctl.c~vm-routine-fixes	2005-01-01 21:21:48.775478664 -0800
+++ 25-akpm/kernel/sysctl.c	2005-01-01 21:21:48.787476840 -0800
@@ -755,6 +755,7 @@ static ctl_table vm_table[] = {
 		.strategy	= &sysctl_intvec,
 		.extra1		= &zero,
 	},
+#ifdef CONFIG_MMU
 	{
 		.ctl_name	= VM_MAX_MAP_COUNT,
 		.procname	= "max_map_count",
@@ -763,6 +764,7 @@ static ctl_table vm_table[] = {
 		.mode		= 0644,
 		.proc_handler	= &proc_dointvec
 	},
+#endif
 	{
 		.ctl_name	= VM_LAPTOP_MODE,
 		.procname	= "laptop_mode",
@@ -904,6 +906,7 @@ static ctl_table fs_table[] = {
 		.proc_handler	= &proc_dointvec,
 	},
 #endif
+#ifdef CONFIG_MMU
 	{
 		.ctl_name	= FS_LEASE_TIME,
 		.procname	= "lease-break-time",
@@ -928,6 +931,7 @@ static ctl_table fs_table[] = {
 		.mode		= 0644,
 		.proc_handler	= &proc_dointvec,
 	},
+#endif
 	{ .ctl_name = 0 }
 };
 
diff -puN mm/bootmem.c~vm-routine-fixes mm/bootmem.c
--- 25/mm/bootmem.c~vm-routine-fixes	2005-01-01 21:21:48.776478512 -0800
+++ 25-akpm/mm/bootmem.c	2005-01-01 21:21:48.787476840 -0800
@@ -19,6 +19,7 @@
 #include <linux/module.h>
 #include <asm/dma.h>
 #include <asm/io.h>
+#include "internal.h"
 
 /*
  * Access to this subsystem has to be serialized externally. (this is
@@ -275,17 +276,18 @@ static unsigned long __init free_all_boo
 	for (i = 0; i < idx; ) {
 		unsigned long v = ~map[i / BITS_PER_LONG];
 		if (gofast && v == ~0UL) {
-			int j;
+			int j, order;
 
 			count += BITS_PER_LONG;
 			__ClearPageReserved(page);
-			set_page_count(page, 1);
+			order = ffs(BITS_PER_LONG) - 1;
+			set_page_refs(page, order);
 			for (j = 1; j < BITS_PER_LONG; j++) {
 				if (j + 16 < BITS_PER_LONG)
 					prefetchw(page + j + 16);
 				__ClearPageReserved(page + j);
 			}
-			__free_pages(page, ffs(BITS_PER_LONG)-1);
+			__free_pages(page, order);
 			i += BITS_PER_LONG;
 			page += BITS_PER_LONG;
 		} else if (v) {
@@ -294,7 +296,7 @@ static unsigned long __init free_all_boo
 				if (v & m) {
 					count++;
 					__ClearPageReserved(page);
-					set_page_count(page, 1);
+					set_page_refs(page, 0);
 					__free_page(page);
 				}
 			}
diff -puN /dev/null mm/internal.h
--- /dev/null	2003-09-15 06:40:47.000000000 -0700
+++ 25-akpm/mm/internal.h	2005-01-01 21:21:48.788476688 -0800
@@ -0,0 +1,13 @@
+/* internal.h: mm/ internal definitions
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+/* page_alloc.c */
+extern void set_page_refs(struct page *page, int order);
diff -puN mm/Makefile~vm-routine-fixes mm/Makefile
--- 25/mm/Makefile~vm-routine-fixes	2005-01-01 21:21:48.778478208 -0800
+++ 25-akpm/mm/Makefile	2005-01-01 21:21:48.788476688 -0800
@@ -5,10 +5,10 @@
 mmu-y			:= nommu.o
 mmu-$(CONFIG_MMU)	:= fremap.o highmem.o madvise.o memory.o mincore.o \
 			   mlock.o mmap.o mprotect.o mremap.o msync.o rmap.o \
-			   vmalloc.o
+			   vmalloc.o prio_tree.o
 
 obj-y			:= bootmem.o filemap.o mempool.o oom_kill.o fadvise.o \
-			   page_alloc.o page-writeback.o pdflush.o prio_tree.o \
+			   page_alloc.o page-writeback.o pdflush.o \
 			   readahead.o slab.o swap.o truncate.o vmscan.o \
 			   $(mmu-y)
 
diff -puN mm/page_alloc.c~vm-routine-fixes mm/page_alloc.c
--- 25/mm/page_alloc.c~vm-routine-fixes	2005-01-01 21:21:48.779478056 -0800
+++ 25-akpm/mm/page_alloc.c	2005-01-01 21:21:48.790476384 -0800
@@ -35,6 +35,7 @@
 #include <linux/vmalloc.h>
 
 #include <asm/tlbflush.h>
+#include "internal.h"
 
 nodemask_t node_online_map = NODE_MASK_NONE;
 nodemask_t node_possible_map = NODE_MASK_ALL;
@@ -284,6 +285,13 @@ void __free_pages_ok(struct page *page, 
 	arch_free_page(page, order);
 
 	mod_page_state(pgfree, 1 << order);
+
+#ifndef CONFIG_MMU
+	if (order > 0)
+		for (i = 1 ; i < (1 << order) ; ++i)
+			__put_page(page + i);
+#endif
+
 	for (i = 0 ; i < (1 << order) ; ++i)
 		free_pages_check(__FUNCTION__, page + i);
 	list_add(&page->lru, &list);
@@ -326,7 +334,7 @@ expand(struct zone *zone, struct page *p
 	return page;
 }
 
-static inline void set_page_refs(struct page *page, int order)
+void set_page_refs(struct page *page, int order)
 {
 #ifdef CONFIG_MMU
 	set_page_count(page, 1);
@@ -336,9 +344,10 @@ static inline void set_page_refs(struct 
 	/*
 	 * We need to reference all the pages for this order, otherwise if
 	 * anyone accesses one of the pages with (get/put) it will be freed.
+	 * - eg: access_process_vm()
 	 */
 	for (i = 0; i < (1 << order); i++)
-		set_page_count(page+i, 1);
+		set_page_count(page + i, 1);
 #endif /* CONFIG_MMU */
 }
 
diff -puN mm/tiny-shmem.c~vm-routine-fixes mm/tiny-shmem.c
--- 25/mm/tiny-shmem.c~vm-routine-fixes	2005-01-01 21:21:48.781477752 -0800
+++ 25-akpm/mm/tiny-shmem.c	2005-01-01 21:21:48.790476384 -0800
@@ -112,7 +112,9 @@ int shmem_zero_setup(struct vm_area_stru
 	if (vma->vm_file)
 		fput(vma->vm_file);
 	vma->vm_file = file;
+#ifdef CONFIG_MMU
 	vma->vm_ops = &generic_file_vm_ops;
+#endif
 	return 0;
 }
 
_