From: Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
Date: Fri, 17 Jan 97 10:34:39 +0100
To: linux-m68k@phil.uni-sb.de
Subject: L68K: Linux 2.1.21
X-Yow: Send your questions to ``ASK ZIPPY'', Box 40474,
 San Francisco, CA 94140, USA
Sender: owner-linux-m68k@phil.uni-sb.de
Reply-To: linux-m68k@phil.uni-sb.de

Hi!

Here are my changes for 2.1.21:

- ataints.c: kill IRQ_MACHSPEC
- atari_ksyms.c, m68k_ksyms.c: remove duplicate symbols
- entry.S, traps.c: fix fatal bug
- sys_m68k.c: remove calls to verify_area
- ataflop.c, atarimouse.c, atari_scsi.c: declare modules params
- lp_m68k.c: convert symbol table
- m68kserial.c: various changes from serial.c
- process.c, user.h: don't use pt_regs outside of kernel
- rd.c: fix little endian ext2 detection
- char/Makefile: remove duplicated rules
- mem.c, vc_screen.c, module.c: re-add lost m68k changes
- unistd.h: fix syscall number
- main.c: don't pass NULL pointer

Andreas.

----------------------------------------------------------------------
--- arch/m68k/atari/ataints.c.~1~	Wed Jan 15 17:39:38 1997
+++ arch/m68k/atari/ataints.c	Thu Jan 16 11:56:09 1997
@@ -190,7 +190,7 @@
 "	lea	"SYMBOL_NAME_STR(irq_handler)"+("#n"+8)*8,%%a0\n"	   \
 "	pea 	%%sp@\n"		/* push addr of frame */	   \
 "	movel	%%a0@(4),%%sp@-\n"	/* push handler data */		   \
-"	pea 	(" #n "+0x10000008)\n"	/* push int number */		   \
+"	pea 	(" #n "+8)\n"		/* push int number */		   \
 "	movel	%%a0@,%%a0\n"						   \
 "	jbsr	%%a0@\n"		/* call the handler */		   \
 "	addql	#8,%%sp\n"						   \
--- arch/m68k/atari/atari_ksyms.c.~1~	Wed Jan 15 17:39:40 1997
+++ arch/m68k/atari/atari_ksyms.c	Thu Jan 16 01:44:45 1997
@@ -24,7 +24,6 @@
 EXPORT_SYMBOL(atari_mouse_buttons);
 EXPORT_SYMBOL(atari_mouse_interrupt_hook);
 EXPORT_SYMBOL(atari_MIDI_interrupt_hook);
-EXPORT_SYMBOL(atari_mch_cookie);
 EXPORT_SYMBOL(ikbd_write);
 EXPORT_SYMBOL(ikbd_mouse_y0_top);
 EXPORT_SYMBOL(ikbd_mouse_thresh);
--- arch/m68k/kernel/entry.S.~1~	Wed Jan 15 21:11:11 1997
+++ arch/m68k/kernel/entry.S	Thu Jan 16 12:53:54 1997
@@ -407,7 +407,7 @@
 	pmove	%a1@(LTSS_CRP),%crp
 #endif
 
-#if defined(CPU_M68020_OR_M68030) && defined(CONFIG_M68040_OR_M68060)
+#if defined(CPU_M68020_OR_M68030) && defined(CPU_M68040_OR_M68060)
 	jra	2f	/* skip m68040 stuff */
 1:
 #endif
--- arch/m68k/kernel/m68k_ksyms.c.~1~	Wed Jan 15 17:39:48 1997
+++ arch/m68k/kernel/m68k_ksyms.c	Thu Jan 16 10:48:31 1997
@@ -32,8 +32,6 @@
 EXPORT_SYMBOL(mm_ptov);
 EXPORT_SYMBOL(mm_end_of_chunk);
 EXPORT_SYMBOL(m68k_debug_device);
-EXPORT_SYMBOL(request_irq);
-EXPORT_SYMBOL(free_irq);
 EXPORT_SYMBOL(dump_fpu);
 EXPORT_SYMBOL(dump_thread);
 EXPORT_SYMBOL(strnlen);
--- arch/m68k/kernel/process.c.~1~	Wed Jan 15 17:39:48 1997
+++ arch/m68k/kernel/process.c	Mon Dec 23 18:15:34 1996
@@ -189,7 +189,7 @@
 	if (dump->start_stack < TASK_SIZE)
 		dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT;
 
-	dump->u_ar0 = (struct pt_regs *)(((int)(&dump->regs)) -((int)(dump)));
+	dump->u_ar0 = (struct user_regs_struct *)((int)&dump->regs - (int)dump);
 	sw = ((struct switch_stack *)regs) - 1;
 	dump->regs.d1 = regs->d1;
 	dump->regs.d2 = regs->d2;
--- arch/m68k/kernel/sys_m68k.c.~1~	Wed Nov 27 18:06:30 1996
+++ arch/m68k/kernel/sys_m68k.c	Fri Jan  3 19:26:15 1997
@@ -31,15 +31,12 @@
 	int fd[2];
 	int error;
 
-	error = verify_area(VERIFY_WRITE,fildes,8);
-	if (error)
-		return error;
 	error = do_pipe(fd);
-	if (error)
-		return error;
-	put_user(fd[0],0+fildes);
-	put_user(fd[1],1+fildes);
-	return 0;
+	if (!error) {
+		if (copy_to_user(fildes, fd, 2*sizeof(int)))
+			error = -EFAULT;
+	}
+	return error;
 }
 
 /*
@@ -64,10 +61,8 @@
 	struct file * file = NULL;
 	struct mmap_arg_struct a;
 
-	error = verify_area(VERIFY_READ, arg, sizeof(*arg));
-	if (error)
-		return error;
-	copy_from_user(&a, arg, sizeof(a));
+	if (copy_from_user(&a, arg, sizeof(a)))
+		return -EFAULT; 
 	if (!(a.flags & MAP_ANONYMOUS)) {
 		if (a.fd >= NR_OPEN || !(file = current->files->fd[a.fd]))
 			return -EBADF;
@@ -115,12 +110,10 @@
 			return sys_semget (first, second, third);
 		case SEMCTL: {
 			union semun fourth;
-			int err;
 			if (!ptr)
 				return -EINVAL;
-			if ((err = verify_area (VERIFY_READ, ptr, sizeof(long))))
-				return err;
-			get_user(fourth.__pad, (void **)ptr);
+			if (get_user(fourth.__pad, (void **) ptr))
+				return -EFAULT;	
 			return sys_semctl (first, second, third, fourth);
 			}
 		default:
@@ -158,18 +151,11 @@
 			case 0: default: {
 				ulong raddr;
 				int err;
-				if ((err = verify_area(VERIFY_WRITE, (ulong*) third, sizeof(ulong))))
-					return err;
 				err = sys_shmat (first, (char *) ptr, second, &raddr);
 				if (err)
 					return err;
-				put_user (raddr, (ulong *) third);
-				return 0;
+				return put_user (raddr, (ulong *) third);
 				}
-			case 1:	/* iBCS2 emulator entry point */
-				if (get_fs() != get_ds())
-					return -EINVAL;
-				return sys_shmat (first, (char *) ptr, second, (ulong *) third);
 			}
 		case SHMDT: 
 			return sys_shmdt ((char *)ptr);
--- arch/m68k/kernel/traps.c.~1~	Wed Jan 15 17:39:50 1997
+++ arch/m68k/kernel/traps.c	Thu Jan 16 12:49:40 1997
@@ -349,7 +349,7 @@
 }
 #endif /* CONFIG_M68040 */
 
-#if defined(CONFIG_M68020_OR_M68030)
+#if defined(CPU_M68020_OR_M68030)
 static inline void bus_error030 (struct frame *fp)
 {
 	volatile unsigned short temp;
@@ -628,7 +628,7 @@
 	asm volatile ("ploadr #2,%0@" : /* no outputs */
 		      : "a" (addr));
 }
-#endif /* CONFIG_M68020_OR_M68030 */
+#endif /* CPU_M68020_OR_M68030 */
 
 asmlinkage void buserr_c(struct frame *fp)
 {
@@ -651,7 +651,7 @@
 	  access_error040 (fp);
 	  break;
 #endif
-#if defined (CONFIG_M68020_OR_M68030)
+#if defined (CPU_M68020_OR_M68030)
 	case 0xa:
 	case 0xb:
 	  bus_error030 (fp);
@@ -907,7 +907,7 @@
 
 	console_verbose();
 	printk("%s: %08x\n",str,nr);
-	printk("PC: %08lx\nSR: %04x  SP: %p\n", fp->pc, fp->sr, fp);
+	printk("PC: [<%08lx>]\nSR: %04x  SP: %p\n", fp->pc, fp->sr, fp);
 	printk("d0: %08lx    d1: %08lx    d2: %08lx    d3: %08lx\n",
 	       fp->d0, fp->d1, fp->d2, fp->d3);
 	printk("d4: %08lx    d5: %08lx    a0: %08lx    a1: %08lx\n",
--- arch/m68k/mm/extable.c.~1~	Wed Jan 15 17:39:51 1997
+++ arch/m68k/mm/extable.c	Mon Dec 30 22:31:50 1996
@@ -46,7 +46,7 @@
 		if (mp->ex_table_start == NULL)
 			continue;
 		ret = search_one_table(mp->ex_table_start,
-				       mp->ex_table_stop-1, addr);
+				       mp->ex_table_end-1, addr);
 		if (ret) return ret;
 	}
 #endif
--- drivers/block/ataflop.c.~1~	Wed Nov 27 17:49:09 1996
+++ drivers/block/ataflop.c	Sat Jan  4 10:49:31 1997
@@ -281,6 +281,7 @@
 static unsigned long PhysDMABuffer;   /* physical address */
 
 static int UseTrackbuffer = -1;		  /* Do track buffering? */
+MODULE_PARM(UseTrackbuffer, "i");
 
 unsigned char *TrackBuffer;			  /* buffer for reads */
 static unsigned long PhysTrackBuffer; /* physical address */
@@ -305,6 +306,7 @@
 static int IsFormatting = 0, FormatError;
 
 static int UserSteprate[FD_MAX_UNITS] = { -1, -1 };
+MODULE_PARM(UserSteprate, "1-" __MODULE_STRING(FD_MAX_UNITS) "i");
 
 /* Synchronization of FDC access. */
 static volatile int fdc_busy = 0;
--- drivers/block/rd.c.~1~	Wed Jan 15 17:41:43 1997
+++ drivers/block/rd.c	Wed Jan 15 21:17:38 1997
@@ -54,6 +54,7 @@
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
+#include <asm/byteorder.h>
 
 extern void wait_for_keypress(void);
 
@@ -407,7 +408,7 @@
 		printk(KERN_NOTICE
 		       "RAMDISK: Ext2 filesystem found at block %d\n",
 		       start_block);
-		nblocks = ext2sb->s_blocks_count;
+		nblocks = le32_to_cpu(ext2sb->s_blocks_count);
 		goto done;
 	}
 
--- drivers/char/Makefile.~1~	Wed Jan 15 17:41:59 1997
+++ drivers/char/Makefile	Wed Jan 15 21:18:05 1997
@@ -45,26 +45,6 @@
   endif
 endif
 
-ifeq ($(CONFIG_AMIGAMOUSE),y)
-M = y
-L_OBJS += amigamouse.o
-else
-  ifeq ($(CONFIG_AMIGAMOUSE),m)
-    M_OBJS += amigamouse.o
-    MM = m
-  endif
-endif
-
-ifeq ($(CONFIG_ATARIMOUSE),y)
-M = y
-L_OBJS += atarimouse.o
-else
-  ifeq ($(CONFIG_ATARIMOUSE),m)
-    M_OBJS += atarimouse.o
-    MM = m
-  endif
-endif
-
 ifeq ($(CONFIG_ATARI_MFPSER),y)
 L_OBJS += atari_MFPser.o
 S = y
--- drivers/char/atarimouse.c.~1~	Wed Oct 30 17:48:41 1996
+++ drivers/char/atarimouse.c	Thu Jan 16 11:15:41 1997
@@ -26,7 +26,8 @@
 #include <asm/uaccess.h>
 
 static struct mouse_status mouse;
-static int atari_mouse_x_threshold = 2, atari_mouse_y_threshold = 2;
+static int mouse_threshold[2];
+MODULE_PARM(mouse_threshold, "2i");
 extern int atari_mouse_buttons;
 
 static void atari_mouse_interrupt(char *buf)
@@ -80,7 +81,7 @@
     mouse.dx = mouse.dy = 0;
     atari_mouse_buttons = 0;
     ikbd_mouse_y0_top ();
-    ikbd_mouse_thresh (atari_mouse_x_threshold, atari_mouse_y_threshold);
+    ikbd_mouse_thresh (mouse_threshold[0], mouse_threshold[1]);
     ikbd_mouse_rel_pos();
     MOD_INC_USE_COUNT;
     atari_mouse_interrupt_hook = atari_mouse_interrupt;
@@ -188,13 +189,13 @@
     if (ints[1] < MIN_THRESHOLD || ints[1] > MAX_THRESHOLD)
 	printk( "atari_mouse_setup: bad threshold value (ignored)\n" );
     else {
-	atari_mouse_x_threshold = ints[1];
-	atari_mouse_y_threshold = ints[1];
+	mouse_threshold[0] = ints[1];
+	mouse_threshold[1] = ints[1];
 	if (ints[0] > 1) {
 	    if (ints[2] < MIN_THRESHOLD || ints[2] > MAX_THRESHOLD)
 		printk("atari_mouse_setup: bad threshold value (ignored)\n" );
 	    else
-		atari_mouse_y_threshold = ints[2];
+		mouse_threshold[1] = ints[2];
 	}
     }
 	
--- drivers/char/lp_m68k.c.~1~	Fri Nov 29 20:59:25 1996
+++ drivers/char/lp_m68k.c	Tue Dec 31 01:25:23 1996
@@ -34,8 +34,8 @@
  *
  */
 
-#include <linux/module.h>
 #include <linux/config.h>
+#include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/major.h>
@@ -457,18 +457,12 @@
 	lp_release
 };
 
-#ifdef CONFIG_MODULES
-static struct symbol_table parallel_syms = {
-#include <linux/symtab_begin.h>
-	X(lp_table),
-	X(lp_irq),
-	X(lp_interrupt),
-	X(lp_init),
-	X(register_parallel),
-	X(unregister_parallel),
-#include <linux/symtab_end.h>
-};
-#endif
+EXPORT_SYMBOL(lp_table);
+EXPORT_SYMBOL(lp_irq);
+EXPORT_SYMBOL(lp_interrupt);
+EXPORT_SYMBOL(lp_init);
+EXPORT_SYMBOL(register_parallel);
+EXPORT_SYMBOL(unregister_parallel);
 
 int lp_init(void)
 {
@@ -481,14 +475,6 @@
 		printk(KERN_ERR "unable to get major %d for line printer\n", LP_MAJOR);
 		return -ENXIO;
 	}
-
-#ifdef CONFIG_MODULES
-	if (register_symtab(&parallel_syms)) {
-		unregister_chrdev(LP_MAJOR, "lp");
-		printk(KERN_CRIT "unable to register parallel symtab\n");
-		return -ENXIO;
-	}
-#endif
 
 #if WHICH_DRIVER == FORCE_POLLING
 	lp_irq = 0;
--- drivers/char/m68kserial.c.~1~	Wed Jan 15 17:42:05 1997
+++ drivers/char/m68kserial.c	Wed Jan 15 21:18:27 1997
@@ -757,15 +757,24 @@
 			if (retval)
 				return retval;
 			tty_wait_until_sent(tty, 0);
-			if (!arg)
+			if (current->signal & ~current->blocked)
+				return -EINTR;
+			if (!arg) {
 				send_break(info, HZ/4);	/* 1/4 second */
+				if (current->signal & ~current->blocked)
+					return -EINTR;
+			}
 			return 0;
 		case TCSBRKP:	/* support for POSIX tcsendbreak() */
 			retval = tty_check_change(tty);
 			if (retval)
 				return retval;
 			tty_wait_until_sent(tty, 0);
+			if (current->signal & ~current->blocked)
+				return -EINTR;
 			send_break(info, arg ? arg*(HZ/10) : HZ/4);
+			if (current->signal & ~current->blocked)
+				return -EINTR;
 			return 0;
 		case TIOCGSOFTCAR:
 			return put_user(C_CLOCAL(tty) ? 1 : 0, (int *) arg);
@@ -989,9 +998,12 @@
 			current->state = TASK_INTERRUPTIBLE;
 			current->timeout = jiffies + info->timeout;
 			schedule();
+			if (current->signal & ~current->blocked)
+				break;
 			if (jiffies > timeout)
 				break;
 		}
+		current->state = TASK_RUNNING;
 	}
 	shutdown(info);
 	if (tty->driver.flush_buffer)
--- drivers/char/mem.c.~1~	Wed Jan 15 17:42:06 1997
+++ drivers/char/mem.c	Wed Jan 15 21:19:32 1997
@@ -145,7 +145,8 @@
 		else
 			tmp = count;
 		read = tmp;
-#if defined(__sparc__) /* we don't have page 0 mapped on sparc.. */
+#if defined(__sparc__) || defined(__mc68000__)
+		/* we don't have page 0 mapped on sparc and m68k.. */
 		while (p < PAGE_SIZE && tmp > 0) {
 			put_user(0,buf);
 			buf++;
@@ -178,7 +179,8 @@
 	if (count > (unsigned long) high_memory - p)
 		count = (unsigned long) high_memory - p;
 	written = 0;
-#if defined(__sparc__) /* we don't have page 0 mapped on sparc.. */
+#if defined(__sparc__) || defined(__mc68000__)
+	/* we don't have page 0 mapped on sparc and m68k.. */
 	while (p < PAGE_SIZE && count > 0) {
 		/* Hmm. Do something? */
 		buf++;
--- drivers/char/vc_screen.c.~1~	Wed Jan 15 17:42:18 1997
+++ drivers/char/vc_screen.c	Wed Jan 15 21:26:05 1997
@@ -155,7 +155,11 @@
 		    p -= HEADER_SIZE;
 		    org = screen_pos(currcons, p/2, viewed);
 		    if ((p & 1) && count > 0)
+#ifdef __mc68000__
 			    { count--; put_user(func_scr_readw(org++) >> 8, buf++); }
+#else
+			    { count--; put_user(func_scr_readw(org++) & 0xff, buf++); }
+#endif
 		}
 		while (count > 1) {
 			put_user(func_scr_readw(org++), (unsigned short *) buf);
@@ -163,7 +167,11 @@
 			count -= 2;
 		}
 		if (count > 0)
+#ifdef __mc68000__
+			put_user(func_scr_readw(org) >> 8, buf++);
+#else
 			put_user(func_scr_readw(org) & 0xff, buf++);
+#endif
 	}
 	read = buf - buf0;
 	file->f_pos += read;
@@ -224,8 +232,13 @@
 			    char c;
 				count--;
 				get_user(c,buf++);
+#ifdef __mc68000__
+				func_scr_writew(c |
+				     (func_scr_readw(org) & 0xff00), org);
+#else
 				func_scr_writew((c << 8) |
 				     (func_scr_readw(org) & 0xff), org);
+#endif
 				org++;
 			}
 		}
@@ -239,7 +252,11 @@
 		if (count > 0) {
 			unsigned char c;
 			get_user(c, (const unsigned char*)buf++);
+#ifdef __mc68000__
+			func_scr_writew((func_scr_readw(org) & 0xff) | (c << 8), org);
+#else
 			func_scr_writew((func_scr_readw(org) & 0xff00) | c, org);
+#endif
 		}
 	}
 #ifdef __mc68000__
--- drivers/net/ppp.c.~1~	Wed Jan 15 17:44:07 1997
+++ drivers/net/ppp.c	Thu Jan 16 01:45:21 1997
@@ -388,8 +388,6 @@
 static int
 ppp_init_dev (struct device *dev)
 {
-	int    indx;
-
 	dev->hard_header_len  = PPP_HARD_HDR_LEN;
 
 	/* device INFO */

--- drivers/scsi/atari_scsi.c.~1~	Mon Nov 11 22:53:16 1996
+++ drivers/scsi/atari_scsi.c	Thu Jan 16 10:33:38 1997
@@ -239,13 +239,18 @@
 static int atari_read_overruns = 0;
 #endif
 
-int setup_can_queue = -1;
-int setup_cmd_per_lun = -1;
-int setup_sg_tablesize = -1;
+static int setup_can_queue = -1;
+MODULE_PARM(setup_can_queue, "i");
+static int setup_cmd_per_lun = -1;
+MODULE_PARM(setup_cmd_per_lun, "i");
+static int setup_sg_tablesize = -1;
+MODULE_PARM(setup_sg_tablesize, "i");
 #ifdef SUPPORT_TAGS
-int setup_use_tagged_queuing = -1;
+static int setup_use_tagged_queuing = -1;
+MODULE_PARM(setup_use_tagged_queuing, "i");
 #endif
-int setup_hostid = -1;
+static int setup_hostid = -1;
+MODULE_PARM(setup_hostid, "i");
 
 
 #if defined(REAL_DMA)
--- include/asm-m68k/processor.h.~1~	Wed Jan 15 17:47:13 1997
+++ include/asm-m68k/processor.h	Fri Jan  3 18:57:57 1997
@@ -18,11 +18,7 @@
 /* This decides where the kernel will search for a free chunk of vm
  * space during mmap's.
  */
-#if 1 /* why? */
-#define TASK_UNMAPPED_BASE	SHM_RANGE_START
-#else
-#define TASK_UNMAPPED_BASE	(TASK_SIZE / 3)
-#endif
+#define TASK_UNMAPPED_BASE	0xC0000000UL
 
 /*
  * Bus types
--- include/asm-m68k/scatterlist.h.~1~	Wed Jan 15 17:47:13 1997
+++ include/asm-m68k/scatterlist.h	Fri Jan  3 21:03:33 1997
@@ -6,12 +6,9 @@
     char * alt_address; /* Location of actual if address is a 
 			 * dma indirect buffer.  NULL otherwise */
     unsigned int length;
-
-#ifdef __sparc__
-    char * dvma_address; /* A place to hang host-specific addresses at. */
-#endif
 };
 
+/* This is bogus and should go away. */
 #define ISA_DMA_THRESHOLD (0x00ffffff)
 
 #endif /* !(_M68K_SCATTERLIST_H) */
--- include/asm-m68k/unistd.h.~1~	Wed Jan 15 17:47:17 1997
+++ include/asm-m68k/unistd.h	Tue Dec 31 02:29:06 1996
@@ -171,7 +171,7 @@
 #define __NR_mremap		163
 #define __NR_setresuid		164
 #define __NR_getresuid		165
-#define __NR_query_module	166
+#define __NR_query_module	167
 
 /* user-visible error numbers are in the range -1 - -122: see
    <asm-m68k/errno.h> */
--- include/asm-m68k/user.h.~1~	Wed Oct  9 23:21:49 1996
+++ include/asm-m68k/user.h	Sun Dec  8 22:09:14 1996
@@ -2,7 +2,7 @@
 #define _M68K_USER_H
 
 #include <asm/page.h>
-#include <linux/ptrace.h>
+
 /* Core file format: The core file is written in such a way that gdb
    can understand it and provide useful information to the user (under
    linux we use the 'trad-core' bfd).  There are quite a number of
@@ -74,7 +74,8 @@
 				   esp register.  */
   long int signal;     		/* Signal that caused the core dump. */
   int reserved;			/* No longer used */
-  struct pt_regs * u_ar0;	/* Used by gdb to help find the values for */
+  struct user_regs_struct *u_ar0;
+				/* Used by gdb to help find the values for */
 				/* the registers. */
   struct user_m68kfp_struct* u_fpstate;	/* Math Co-processor pointer. */
   unsigned long magic;		/* To uniquely identify a core file */
--- init/main.c.~1~	Wed Jan 15 21:36:11 1997
+++ init/main.c	Thu Jan 16 13:25:24 1997
@@ -1025,7 +1025,8 @@
 	 * trying to recover a really broken machine.
 	 */
 
-	execve(execute_command,argv_init,envp_init);
+	if (execute_command)
+		execve(execute_command,argv_init,envp_init);
 	execve("/etc/init",argv_init,envp_init);
 	execve("/bin/init",argv_init,envp_init);
 	execve("/sbin/init",argv_init,envp_init);
--- kernel/module.c.~1~	Wed Jan 15 17:49:08 1997
+++ kernel/module.c	Wed Jan  8 23:01:12 1997
@@ -5,6 +5,7 @@
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/config.h>
+#include <asm/pgtable.h>
 #include <asm/uaccess.h>
 #include <linux/vmalloc.h>
 
@@ -290,6 +291,9 @@
 		error = -EFAULT;
 		goto err3;
 	}
+
+	flush_pages_to_ram((unsigned long)mod,
+			   (mod->size + PAGE_SIZE - 1) / PAGE_SIZE);
 
 	/* Update module references.  */
 	mod->next = mod_tmp.next;
