Linux MIPS Architecture development
 help / color / mirror / Atom feed
* [patch] linux 2.4.5: Make __dbe_table available to modules
@ 2001-08-13 13:38 Maciej W. Rozycki
  2001-08-13 15:50 ` Ralf Baechle
  2001-08-20 13:57 ` [patch] linux 2.4.5: __dbe_table iteration #2 Maciej W. Rozycki
  0 siblings, 2 replies; 20+ messages in thread
From: Maciej W. Rozycki @ 2001-08-13 13:38 UTC (permalink / raw)
  To: Ralf Baechle, Harald Koerfgen, Keith Owens; +Cc: linux-mips, linux-mips

Hi,

 Unlike most architectures which only handle memory faults/privilege
violations via __ex_table, the MIPS port allows to handle bus error
exceptions via __dbe_table. Unfortunately, the latter table is not
exported to modules, so if a modularized driver needs to probe the address
space for a device it's out of luck.

 The following patch implements the kernel part of __dbe_table support.  A
separate patch is needed for modutils.

 A side effect of the patch is a fix to unhandled bus error exceptions
which happen in the kernel mode.  Currently they cause the faulting code
to be reexecuted which results in a hang in an infinite loop.  With the
patch applied, the kernel's response is an "Oops" similar to the one
printed when a memory fault happens.

 I hope it's fine to apply.

  Maciej

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

patch-mips-2.4.5-20010704-dbe-0
diff -up --recursive --new-file linux-mips-2.4.5-20010704.macro/arch/mips/kernel/traps.c linux-mips-2.4.5-20010704/arch/mips/kernel/traps.c
--- linux-mips-2.4.5-20010704.macro/arch/mips/kernel/traps.c	Fri Jun 15 04:27:07 2001
+++ linux-mips-2.4.5-20010704/arch/mips/kernel/traps.c	Sun Aug 12 17:34:55 2001
@@ -14,6 +14,7 @@
 #include <linux/config.h>
 #include <linux/init.h>
 #include <linux/mm.h>
+#include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
@@ -254,23 +255,59 @@ search_one_table(const struct exception_
 	return (first == last && first->insn == value) ? first->nextinsn : 0;
 }
 
-#define search_dbe_table(addr)	\
-	search_one_table(__start___dbe_table, __stop___dbe_table - 1, (addr))
+extern spinlock_t modlist_lock;
+
+static unsigned long
+search_dbe_table(unsigned long addr)
+{
+	unsigned long ret = 0;
+
+#ifndef CONFIG_MODULES
+	/* There is only the kernel to search.  */
+	ret = search_one_table(__start___dbe_table, __stop___dbe_table-1, addr);
+	return ret;
+#else
+	unsigned long flags;
+
+	/* The kernel is the last "module" -- no need to treat it special.  */
+	struct module *mp;
+
+	spin_lock_irqsave(&modlist_lock, flags);
+	for (mp = module_list; mp != NULL; mp = mp->next) {
+		if (mp->dbe_table_start == NULL || !(mp->flags&(MOD_RUNNING|MOD_INITIALIZING)))
+			continue;
+		ret = search_one_table(mp->dbe_table_start,
+				       mp->dbe_table_end - 1, addr);
+		if (ret)
+			break;
+	}
+        spin_unlock_irqrestore(&modlist_lock, flags);
+	return ret;
+#endif
+}
 
 static void default_be_board_handler(struct pt_regs *regs)
 {
 	unsigned long new_epc;
-	unsigned long fixup = search_dbe_table(regs->cp0_epc);
+	unsigned long fixup;
 
-	if (fixup) {
-		new_epc = fixup_exception(dpf_reg, fixup, regs->cp0_epc);
-		regs->cp0_epc = new_epc;
-		return;
+	if (!user_mode(regs)) {
+		fixup = search_dbe_table(regs->cp0_epc);
+		if (fixup) {
+			new_epc = fixup_exception(dpf_reg, fixup,
+						  regs->cp0_epc);
+			regs->cp0_epc = new_epc;
+			return;
+		}
 	}
 
 	/*
 	 * Assume it would be too dangerous to continue ...
 	 */
+	printk(KERN_ALERT "%s bus error, epc == %08lx, ra == %08lx\n",
+	       (regs->cp0_cause & 4) ? "Data" : "Instruction",
+	       regs->cp0_epc, regs->regs[31]);
+	die_if_kernel("Oops", regs);
 	force_sig(SIGBUS, current);
 }
 
diff -up --recursive --new-file linux-mips-2.4.5-20010704.macro/include/linux/module.h linux-mips-2.4.5-20010704/include/linux/module.h
--- linux-mips-2.4.5-20010704.macro/include/linux/module.h	Mon Jul 16 02:13:58 2001
+++ linux-mips-2.4.5-20010704/include/linux/module.h	Sun Aug 12 11:22:09 2001
@@ -75,6 +75,10 @@ struct module
 	void (*cleanup)(void);
 	const struct exception_table_entry *ex_table_start;
 	const struct exception_table_entry *ex_table_end;
+#ifdef __mips__
+	const struct exception_table_entry *dbe_table_start;
+	const struct exception_table_entry *dbe_table_end;
+#endif
 #ifdef __alpha__
 	unsigned long gp;
 #endif
diff -up --recursive --new-file linux-mips-2.4.5-20010704.macro/kernel/module.c linux-mips-2.4.5-20010704/kernel/module.c
--- linux-mips-2.4.5-20010704.macro/kernel/module.c	Thu Jun 14 04:28:48 2001
+++ linux-mips-2.4.5-20010704/kernel/module.c	Sun Aug 12 11:24:53 2001
@@ -36,6 +36,11 @@ extern struct module_symbol __stop___ksy
 extern const struct exception_table_entry __start___ex_table[];
 extern const struct exception_table_entry __stop___ex_table[];
 
+#ifdef __mips__
+extern const struct exception_table_entry __start___dbe_table[];
+extern const struct exception_table_entry __stop___dbe_table[];
+#endif
+
 extern const char __start___kallsyms[] __attribute__ ((weak));
 extern const char __stop___kallsyms[] __attribute__ ((weak));
 
@@ -48,6 +53,10 @@ static struct module kernel_module =
 	syms:			__start___ksymtab,
 	ex_table_start:		__start___ex_table,
 	ex_table_end:		__stop___ex_table,
+#ifdef __mips__
+	dbe_table_start:	__start___dbe_table,
+	dbe_table_end:		__stop___dbe_table,
+#endif
 	kallsyms_start:		__start___kallsyms,
 	kallsyms_end:		__stop___kallsyms,
 };
@@ -436,6 +445,19 @@ sys_init_module(const char *name_user, s
 		printk(KERN_ERR "init_module: mod->ex_table_* invalid.\n");
 		goto err2;
 	}
+#ifdef __mips__
+	if (mod->dbe_table_start > mod->dbe_table_end
+	    || (mod->dbe_table_start &&
+		!((unsigned long)mod->dbe_table_start >= ((unsigned long)mod + mod->size_of_struct)
+		  && ((unsigned long)mod->dbe_table_end
+		      < (unsigned long)mod + mod->size)))
+	    || (((unsigned long)mod->dbe_table_start
+		 - (unsigned long)mod->dbe_table_end)
+		% sizeof(struct exception_table_entry))) {
+		printk(KERN_ERR "init_module: mod->dbe_table_* invalid.\n");
+		goto err2;
+	}
+#endif
 	if (mod->flags & ~MOD_AUTOCLEAN) {
 		printk(KERN_ERR "init_module: mod->flags invalid.\n");
 		goto err2;

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [patch] linux 2.4.5: Make __dbe_table available to modules
  2001-08-13 13:38 [patch] linux 2.4.5: Make __dbe_table available to modules Maciej W. Rozycki
@ 2001-08-13 15:50 ` Ralf Baechle
  2001-08-13 16:24   ` Maciej W. Rozycki
  2001-08-20 13:57 ` [patch] linux 2.4.5: __dbe_table iteration #2 Maciej W. Rozycki
  1 sibling, 1 reply; 20+ messages in thread
From: Ralf Baechle @ 2001-08-13 15:50 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: Harald Koerfgen, Keith Owens, linux-mips, linux-mips

On Mon, Aug 13, 2001 at 03:38:36PM +0200, Maciej W. Rozycki wrote:

>  Unlike most architectures which only handle memory faults/privilege
> violations via __ex_table, the MIPS port allows to handle bus error
> exceptions via __dbe_table. Unfortunately, the latter table is not
> exported to modules, so if a modularized driver needs to probe the address
> space for a device it's out of luck.
> 
>  The following patch implements the kernel part of __dbe_table support.  A
> separate patch is needed for modutils.
> 
>  A side effect of the patch is a fix to unhandled bus error exceptions
> which happen in the kernel mode.  Currently they cause the faulting code
> to be reexecuted which results in a hang in an infinite loop.  With the
> patch applied, the kernel's response is an "Oops" similar to the one
> printed when a memory fault happens.
> 
>  I hope it's fine to apply.

Looks fine at the first view.  I'll apply it but duplicate it for mips64
also.

The whole mechanism has it's problems though.  On the Origin certain
accesses like an attempt to write to a non-existant serial interface
take down the machine though.  I don't have an explanation nor did Kanoj
seem to.

  Ralf

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [patch] linux 2.4.5: Make __dbe_table available to modules
  2001-08-13 15:50 ` Ralf Baechle
@ 2001-08-13 16:24   ` Maciej W. Rozycki
  2001-08-13 18:11     ` Gleb O. Raiko
  0 siblings, 1 reply; 20+ messages in thread
From: Maciej W. Rozycki @ 2001-08-13 16:24 UTC (permalink / raw)
  To: Ralf Baechle; +Cc: Harald Koerfgen, Keith Owens, linux-mips, linux-mips

On Mon, 13 Aug 2001, Ralf Baechle wrote:

> Looks fine at the first view.  I'll apply it but duplicate it for mips64
> also.

 Please wait for a while, until I resolve modutils interoperability as
pointed out by Keith. 

> The whole mechanism has it's problems though.  On the Origin certain
> accesses like an attempt to write to a non-existant serial interface
> take down the machine though.  I don't have an explanation nor did Kanoj
> seem to.

 The MIPS architecture defines the bus error exception event for data
reads and instruction fetches only.  Writes are asynchronous so errors on
them cannot be reported exactly -- some MIPS documentation recommends
using a general-purpose interrupt line for such events.

 Both bus error exceptions and error interrupts are system-specific and
might not work unless designed to.  The Origin might be an example.  Does
it crash for reads/fetches from the affected address space, either? 

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [patch] linux 2.4.5: Make __dbe_table available to modules
  2001-08-13 16:24   ` Maciej W. Rozycki
@ 2001-08-13 18:11     ` Gleb O. Raiko
  2001-08-14 17:34       ` Maciej W. Rozycki
  0 siblings, 1 reply; 20+ messages in thread
From: Gleb O. Raiko @ 2001-08-13 18:11 UTC (permalink / raw)
  To: Maciej W. Rozycki
  Cc: Ralf Baechle, Harald Koerfgen, Keith Owens, linux-mips,
	linux-mips



"Maciej W. Rozycki" wrote:
>  The MIPS architecture defines the bus error exception event for data
> reads and instruction fetches only.  Writes are asynchronous so errors on
> them cannot be reported exactly -- some MIPS documentation recommends
> using a general-purpose interrupt line for such events.
> 

DBE is treated as ACK* on write. Some HW design manuals advise to use
this fact even.

Regards,
Gleb.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [patch] linux 2.4.5: Make __dbe_table available to modules
  2001-08-13 18:11     ` Gleb O. Raiko
@ 2001-08-14 17:34       ` Maciej W. Rozycki
  2001-08-23 11:23         ` Gleb O. Raiko
  0 siblings, 1 reply; 20+ messages in thread
From: Maciej W. Rozycki @ 2001-08-14 17:34 UTC (permalink / raw)
  To: Gleb O. Raiko
  Cc: Ralf Baechle, Harald Koerfgen, Keith Owens, linux-mips,
	linux-mips

On Mon, 13 Aug 2001, Gleb O. Raiko wrote:

> DBE is treated as ACK* on write. Some HW design manuals advise to use
> this fact even.

 And what is the use of ACK*?

 Note that that the state of the CPU at the moment of a write is
completely unrelated to the action that triggered the write.  Therefore
any reporting of a write failure is hardly useful -- possibly as a kind of
an MCE only, i.e. report the event and kill the current process or panic
if none.

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [patch] linux 2.4.5: __dbe_table iteration #2
  2001-08-13 13:38 [patch] linux 2.4.5: Make __dbe_table available to modules Maciej W. Rozycki
  2001-08-13 15:50 ` Ralf Baechle
@ 2001-08-20 13:57 ` Maciej W. Rozycki
  2001-08-23  1:49   ` Keith Owens
  1 sibling, 1 reply; 20+ messages in thread
From: Maciej W. Rozycki @ 2001-08-20 13:57 UTC (permalink / raw)
  To: Ralf Baechle, Keith Owens; +Cc: linux-mips, linux-mips

Hi,

 After a bit of work, I have implemented all the suggestions.  The
following changes have been made to the previous version: 

- default_be_board_handler() in traps.c (mips) only searches __dbe_table
for DBE faults and not IBE ones,

- search_dbe_table() in ip2[27]-berr.c (mips64) is modified to work
similarly to the traps.c (mips) one,

- init_modules() now calls platform-specific arch_init_modules(),

- module_arch_init() and arch_init_modules() are implemented for alpha
(moving the conditional stuff from module.c), mips and mips64.

The patch follows.  It has been rougly tested on mips and has proved to be
harmless on i386 as well.  The alpha and mips64 changes have not been
tested.  I haven't modified DBE handlers for mips64 to make them work like
the mips version since they don't return at all anyway.

 If we agree on the patch I'm going to submit it to mainline since it's
not MIPS-specific anymore.  The patch applies cleanly to 2.4.9. 

  Maciej

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

patch-mips-2.4.5-20010704-dbe-11
diff -up --recursive --new-file linux-mips-2.4.5-20010704.macro/arch/mips/kernel/traps.c linux-mips-2.4.5-20010704/arch/mips/kernel/traps.c
--- linux-mips-2.4.5-20010704.macro/arch/mips/kernel/traps.c	Fri Jun 15 04:27:07 2001
+++ linux-mips-2.4.5-20010704/arch/mips/kernel/traps.c	Mon Aug 20 13:38:05 2001
@@ -14,6 +14,7 @@
 #include <linux/config.h>
 #include <linux/init.h>
 #include <linux/mm.h>
+#include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
@@ -25,6 +26,7 @@
 #include <asm/cachectl.h>
 #include <asm/inst.h>
 #include <asm/jazz.h>
+#include <asm/module.h>
 #include <asm/pgtable.h>
 #include <asm/io.h>
 #include <asm/siginfo.h>
@@ -254,23 +256,67 @@ search_one_table(const struct exception_
 	return (first == last && first->insn == value) ? first->nextinsn : 0;
 }
 
-#define search_dbe_table(addr)	\
-	search_one_table(__start___dbe_table, __stop___dbe_table - 1, (addr))
+extern spinlock_t modlist_lock;
+
+static inline unsigned long
+search_dbe_table(unsigned long addr)
+{
+	unsigned long ret = 0;
+
+#ifndef CONFIG_MODULES
+	/* There is only the kernel to search.  */
+	ret = search_one_table(__start___dbe_table, __stop___dbe_table-1, addr);
+	return ret;
+#else
+	unsigned long flags;
+
+	/* The kernel is the last "module" -- no need to treat it special.  */
+	struct module *mp;
+	struct archdata *ap;
+
+	spin_lock_irqsave(&modlist_lock, flags);
+	for (mp = module_list; mp != NULL; mp = mp->next) {
+		if (!mod_member_present(mp, archdata_start) ||
+		    !mp->archdata_start)
+			continue;
+		ap = (struct archdata *)(mp->archdata_start);
+
+		if (ap->dbe_table_start == NULL ||
+		    !(mp->flags & (MOD_RUNNING | MOD_INITIALIZING)))
+			continue;
+		ret = search_one_table(ap->dbe_table_start,
+				       ap->dbe_table_end - 1, addr);
+		if (ret)
+			break;
+	}
+	spin_unlock_irqrestore(&modlist_lock, flags);
+	return ret;
+#endif
+}
 
 static void default_be_board_handler(struct pt_regs *regs)
 {
 	unsigned long new_epc;
-	unsigned long fixup = search_dbe_table(regs->cp0_epc);
+	unsigned long fixup;
+	int data = regs->cp0_cause & 4;
 
-	if (fixup) {
-		new_epc = fixup_exception(dpf_reg, fixup, regs->cp0_epc);
-		regs->cp0_epc = new_epc;
-		return;
+	if (data && !user_mode(regs)) {
+		fixup = search_dbe_table(regs->cp0_epc);
+		if (fixup) {
+			new_epc = fixup_exception(dpf_reg, fixup,
+						  regs->cp0_epc);
+			regs->cp0_epc = new_epc;
+			return;
+		}
 	}
 
 	/*
 	 * Assume it would be too dangerous to continue ...
 	 */
+	printk(KERN_ALERT "%s bus error, epc == %08lx, ra == %08lx\n",
+	       data ? "Data" : "Instruction",
+	       regs->cp0_epc, regs->regs[31]);
+	die_if_kernel("Oops", regs);
 	force_sig(SIGBUS, current);
 }
 
diff -up --recursive --new-file linux-mips-2.4.5-20010704.macro/arch/mips64/sgi-ip22/ip22-berr.c linux-mips-2.4.5-20010704/arch/mips64/sgi-ip22/ip22-berr.c
--- linux-mips-2.4.5-20010704.macro/arch/mips64/sgi-ip22/ip22-berr.c	Thu Feb 24 05:26:11 2000
+++ linux-mips-2.4.5-20010704/arch/mips64/sgi-ip22/ip22-berr.c	Mon Aug 20 00:25:46 2001
@@ -9,6 +9,9 @@
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <asm/module.h>
 #include <asm/uaccess.h>
 #include <asm/paccess.h>
 #include <asm/addrspace.h>
@@ -41,16 +44,42 @@ search_one_table(const struct exception_
 	return 0;
 }
 
+extern spinlock_t modlist_lock;
+
 static inline unsigned long
 search_dbe_table(unsigned long addr)
 {
-	unsigned long ret;
+	unsigned long ret = 0;
 
+#ifndef CONFIG_MODULES
 	/* There is only the kernel to search.  */
 	ret = search_one_table(__start___dbe_table, __stop___dbe_table-1, addr);
-	if (ret) return ret;
-
-	return 0;
+	return ret;
+#else
+	unsigned long flags;
+
+	/* The kernel is the last "module" -- no need to treat it special.  */
+	struct module *mp;
+	struct archdata *ap;
+
+	spin_lock_irqsave(&modlist_lock, flags);
+	for (mp = module_list; mp != NULL; mp = mp->next) {
+		if (!mod_member_present(mp, archdata_start) ||
+		    !mp->archdata_start)
+			continue;
+		ap = (struct archdata *)(mod->archdata_start);
+
+		if (ap->dbe_table_start == NULL ||
+		    !(mp->flags & (MOD_RUNNING | MOD_INITIALIZING)))
+			continue;
+		ret = search_one_table(ap->dbe_table_start,
+				       ap->dbe_table_end - 1, addr);
+		if (ret)
+			break;
+	}
+	spin_unlock_irqrestore(&modlist_lock, flags);
+	return ret;
+#endif
 }
 
 void do_ibe(struct pt_regs *regs)
diff -up --recursive --new-file linux-mips-2.4.5-20010704.macro/arch/mips64/sgi-ip27/ip27-berr.c linux-mips-2.4.5-20010704/arch/mips64/sgi-ip27/ip27-berr.c
--- linux-mips-2.4.5-20010704.macro/arch/mips64/sgi-ip27/ip27-berr.c	Sat Feb 24 05:26:18 2001
+++ linux-mips-2.4.5-20010704/arch/mips64/sgi-ip27/ip27-berr.c	Mon Aug 20 13:39:45 2001
@@ -8,6 +8,9 @@
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <asm/module.h>
 #include <asm/sn/addrs.h>
 #include <asm/sn/arch.h>
 #include <asm/sn/sn0/hub.h>
@@ -43,16 +46,42 @@ search_one_table(const struct exception_
 	return 0;
 }
 
+extern spinlock_t modlist_lock;
+
 static inline unsigned long
 search_dbe_table(unsigned long addr)
 {
 	unsigned long ret;
 
+#ifndef CONFIG_MODULES
 	/* There is only the kernel to search.  */
 	ret = search_one_table(__start___dbe_table, __stop___dbe_table-1, addr);
-	if (ret) return ret;
-
-	return 0;
+	return ret;
+#else
+	unsigned long flags;
+
+	/* The kernel is the last "module" -- no need to treat it special.  */
+	struct module *mp;
+	struct archdata *ap;
+
+	spin_lock_irqsave(&modlist_lock, flags);
+	for (mp = module_list; mp != NULL; mp = mp->next) {
+		if (!mod_member_present(mp, archdata_start) ||
+		    !mp->archdata_start)
+			continue;
+		ap = (struct archdata *)(mod->archdata_start);
+
+		if (ap->dbe_table_start == NULL ||
+		    !(mp->flags & (MOD_RUNNING | MOD_INITIALIZING)))
+			continue;
+		ret = search_one_table(ap->dbe_table_start,
+				       ap->dbe_table_end - 1, addr);
+		if (ret)
+			break;
+	}
+	spin_unlock_irqrestore(&modlist_lock, flags);
+	return ret;
+#endif
 }
 
 void do_ibe(struct pt_regs *regs)
diff -up --recursive --new-file linux-mips-2.4.5-20010704.macro/include/asm-alpha/module.h linux-mips-2.4.5-20010704/include/asm-alpha/module.h
--- linux-mips-2.4.5-20010704.macro/include/asm-alpha/module.h	Tue Nov 28 03:59:03 2000
+++ linux-mips-2.4.5-20010704/include/asm-alpha/module.h	Sun Aug 19 20:07:45 2001
@@ -6,6 +6,23 @@
 
 #define module_map(x)		vmalloc(x)
 #define module_unmap(x)		vfree(x)
-#define module_arch_init(x)	(0)
+#define module_arch_init(x)	alpha_module_init(x)
+#define arch_init_modules(x)	alpha_init_modules(x)
+
+static inline int
+alpha_module_init(struct module *mod)
+{
+        if (!mod_bound(mod->gp - 0x8000, 0, mod)) {
+                printk(KERN_ERR "arch_init_module: mod->gp out of bounds.\n");
+                return 1;
+        }
+	return 0;
+}
+
+static inline void
+alpha_init_modules(struct module *mod)
+{
+	__asm__("stq $29,%0" : "=m" (mod->gp));
+}
 
 #endif /* _ASM_ALPHA_MODULE_H */
diff -up --recursive --new-file linux-mips-2.4.5-20010704.macro/include/asm-arm/module.h linux-mips-2.4.5-20010704/include/asm-arm/module.h
--- linux-mips-2.4.5-20010704.macro/include/asm-arm/module.h	Tue Nov 28 03:59:03 2000
+++ linux-mips-2.4.5-20010704/include/asm-arm/module.h	Mon Aug 20 01:11:58 2001
@@ -7,5 +7,6 @@
 #define module_map(x)		vmalloc(x)
 #define module_unmap(x)		vfree(x)
 #define module_arch_init(x)	(0)
+#define arch_init_modules(x)	do { } while (0)
 
 #endif /* _ASM_ARM_MODULE_H */
diff -up --recursive --new-file linux-mips-2.4.5-20010704.macro/include/asm-cris/module.h linux-mips-2.4.5-20010704/include/asm-cris/module.h
--- linux-mips-2.4.5-20010704.macro/include/asm-cris/module.h	Fri Mar  9 20:34:43 2001
+++ linux-mips-2.4.5-20010704/include/asm-cris/module.h	Mon Aug 20 01:12:04 2001
@@ -7,5 +7,6 @@
 #define module_map(x)		vmalloc(x)
 #define module_unmap(x)		vfree(x)
 #define module_arch_init(x)	(0)
+#define arch_init_modules(x)	do { } while (0)
 
 #endif /* _ASM_CRIS_MODULE_H */
diff -up --recursive --new-file linux-mips-2.4.5-20010704.macro/include/asm-i386/module.h linux-mips-2.4.5-20010704/include/asm-i386/module.h
--- linux-mips-2.4.5-20010704.macro/include/asm-i386/module.h	Tue Nov 28 03:59:03 2000
+++ linux-mips-2.4.5-20010704/include/asm-i386/module.h	Mon Aug 20 01:12:08 2001
@@ -7,5 +7,6 @@
 #define module_map(x)		vmalloc(x)
 #define module_unmap(x)		vfree(x)
 #define module_arch_init(x)	(0)
+#define arch_init_modules(x)	do { } while (0)
 
 #endif /* _ASM_I386_MODULE_H */
diff -up --recursive --new-file linux-mips-2.4.5-20010704.macro/include/asm-ia64/module.h linux-mips-2.4.5-20010704/include/asm-ia64/module.h
--- linux-mips-2.4.5-20010704.macro/include/asm-ia64/module.h	Thu Jun 14 04:28:30 2001
+++ linux-mips-2.4.5-20010704/include/asm-ia64/module.h	Mon Aug 20 01:12:14 2001
@@ -14,6 +14,7 @@
 #define module_map(x)		vmalloc(x)
 #define module_unmap(x)		ia64_module_unmap(x)
 #define module_arch_init(x)	ia64_module_init(x)
+#define arch_init_modules(x)	do { } while (0)
 
 /*
  * This must match in size and layout the data created by
diff -up --recursive --new-file linux-mips-2.4.5-20010704.macro/include/asm-m68k/module.h linux-mips-2.4.5-20010704/include/asm-m68k/module.h
--- linux-mips-2.4.5-20010704.macro/include/asm-m68k/module.h	Tue Nov 28 03:59:03 2000
+++ linux-mips-2.4.5-20010704/include/asm-m68k/module.h	Mon Aug 20 01:12:18 2001
@@ -7,5 +7,6 @@
 #define module_map(x)		vmalloc(x)
 #define module_unmap(x)		vfree(x)
 #define module_arch_init(x)	(0)
+#define arch_init_modules(x)	do { } while (0)
 
 #endif /* _ASM_M68K_MODULE_H */
diff -up --recursive --new-file linux-mips-2.4.5-20010704.macro/include/asm-mips/module.h linux-mips-2.4.5-20010704/include/asm-mips/module.h
--- linux-mips-2.4.5-20010704.macro/include/asm-mips/module.h	Tue Nov 28 03:59:03 2000
+++ linux-mips-2.4.5-20010704/include/asm-mips/module.h	Mon Aug 20 00:18:19 2001
@@ -4,8 +4,61 @@
  * This file contains the mips architecture specific module code.
  */
 
+#include <linux/module.h>
+#include <asm/uaccess.h>
+
 #define module_map(x)		vmalloc(x)
 #define module_unmap(x)		vfree(x)
-#define module_arch_init(x)	(0)
+#define module_arch_init(x)	mips_module_init(x)
+#define arch_init_modules(x)	mips_init_modules(x)
+
+/*
+ * This must match in size and layout the data created by
+ * modutils/obj/obj-mips.c
+ */
+struct archdata {
+	const struct exception_table_entry *dbe_table_start;
+	const struct exception_table_entry *dbe_table_end;
+};
+
+static inline int
+mips_module_init(struct module *mod)
+{
+	struct archdata *archdata;
+
+	if (!mod_member_present(mod, archdata_start) || !mod->archdata_start)
+		return 0;
+	archdata = (struct archdata *)(mod->archdata_start);
+
+	if (archdata->dbe_table_start > archdata->dbe_table_end ||
+	    (archdata->dbe_table_start &&
+	     !((unsigned long)archdata->dbe_table_start >=
+	       ((unsigned long)mod + mod->size_of_struct) &&
+	       ((unsigned long)archdata->dbe_table_end <
+	        (unsigned long)mod + mod->size))) ||
+            (((unsigned long)archdata->dbe_table_start -
+	      (unsigned long)archdata->dbe_table_end) %
+	     sizeof(struct exception_table_entry))) {
+		printk(KERN_ERR
+			"arch_init_module: archdata->dbe_table_* invalid.\n");
+		return 1;
+	}
+
+	return 0;
+}
+
+static inline void
+mips_init_modules(struct module *mod)
+{
+	extern const struct exception_table_entry __start___dbe_table[];
+	extern const struct exception_table_entry __stop___dbe_table[];
+	static struct archdata archdata = {
+		dbe_table_start:	__start___dbe_table,
+		dbe_table_end:		__stop___dbe_table,
+	};
+
+	mod->archdata_start = (char *)&archdata;
+	mod->archdata_end = mod->archdata_start + sizeof(archdata);
+}
 
 #endif /* _ASM_MIPS_MODULE_H */
diff -up --recursive --new-file linux-mips-2.4.5-20010704.macro/include/asm-mips64/module.h linux-mips-2.4.5-20010704/include/asm-mips64/module.h
--- linux-mips-2.4.5-20010704.macro/include/asm-mips64/module.h	Tue Nov 28 03:59:03 2000
+++ linux-mips-2.4.5-20010704/include/asm-mips64/module.h	Mon Aug 20 00:18:32 2001
@@ -4,8 +4,61 @@
  * This file contains the mips64 architecture specific module code.
  */
 
+#include <linux/module.h>
+#include <asm/uaccess.h>
+
 #define module_map(x)		vmalloc(x)
 #define module_unmap(x)		vfree(x)
-#define module_arch_init(x)	(0)
+#define module_arch_init(x)	mips64_module_init(x)
+#define arch_init_modules(x)	mips64_init_modules(x)
+
+/*
+ * This must match in size and layout the data created by
+ * modutils/obj/obj-mips64.c
+ */
+struct archdata {
+	const struct exception_table_entry *dbe_table_start;
+	const struct exception_table_entry *dbe_table_end;
+};
+
+static inline int
+mips64_module_init(struct module *mod)
+{
+	struct archdata *archdata;
+
+	if (!mod_member_present(mod, archdata_start) || !mod->archdata_start)
+		return 0;
+	archdata = (struct archdata *)(mod->archdata_start);
+
+	if (archdata->dbe_table_start > archdata->dbe_table_end ||
+	    (archdata->dbe_table_start &&
+	     !((unsigned long)archdata->dbe_table_start >=
+	       ((unsigned long)mod + mod->size_of_struct) &&
+	       ((unsigned long)archdata->dbe_table_end <
+	        (unsigned long)mod + mod->size))) ||
+            (((unsigned long)archdata->dbe_table_start -
+	      (unsigned long)archdata->dbe_table_end) %
+	     sizeof(struct exception_table_entry))) {
+		printk(KERN_ERR
+			"arch_init_module: archdata->dbe_table_* invalid.\n");
+		return 1;
+	}
+
+	return 0;
+}
+
+static inline void
+mips64_init_modules(struct module *mod)
+{
+	extern const struct exception_table_entry __start___dbe_table[];
+	extern const struct exception_table_entry __stop___dbe_table[];
+	static struct archdata archdata = {
+		dbe_table_start:	__start___dbe_table,
+		dbe_table_end:		__stop___dbe_table,
+	};
+
+	mod->archdata_start = (char *)&archdata;
+	mod->archdata_end = mod->archdata_start + sizeof(archdata);
+}
 
 #endif /* _ASM_MIPS64_MODULE_H */
diff -up --recursive --new-file linux-mips-2.4.5-20010704.macro/include/asm-ppc/module.h linux-mips-2.4.5-20010704/include/asm-ppc/module.h
--- linux-mips-2.4.5-20010704.macro/include/asm-ppc/module.h	Thu Jun 14 04:28:38 2001
+++ linux-mips-2.4.5-20010704/include/asm-ppc/module.h	Mon Aug 20 01:12:29 2001
@@ -10,5 +10,6 @@
 #define module_map(x)		vmalloc(x)
 #define module_unmap(x)		vfree(x)
 #define module_arch_init(x)	(0)
+#define arch_init_modules(x)	do { } while (0)
 
 #endif /* _ASM_PPC_MODULE_H */
diff -up --recursive --new-file linux-mips-2.4.5-20010704.macro/include/asm-s390/module.h linux-mips-2.4.5-20010704/include/asm-s390/module.h
--- linux-mips-2.4.5-20010704.macro/include/asm-s390/module.h	Tue Nov 28 03:59:03 2000
+++ linux-mips-2.4.5-20010704/include/asm-s390/module.h	Mon Aug 20 01:12:37 2001
@@ -7,5 +7,6 @@
 #define module_map(x)		vmalloc(x)
 #define module_unmap(x)		vfree(x)
 #define module_arch_init(x)	(0)
+#define arch_init_modules(x)	do { } while (0)
 
 #endif /* _ASM_S390_MODULE_H */
diff -up --recursive --new-file linux-mips-2.4.5-20010704.macro/include/asm-s390x/module.h linux-mips-2.4.5-20010704/include/asm-s390x/module.h
--- linux-mips-2.4.5-20010704.macro/include/asm-s390x/module.h	Fri Mar  9 20:34:52 2001
+++ linux-mips-2.4.5-20010704/include/asm-s390x/module.h	Mon Aug 20 01:12:53 2001
@@ -7,5 +7,6 @@
 #define module_map(x)		vmalloc(x)
 #define module_unmap(x)		vfree(x)
 #define module_arch_init(x)	(0)
+#define arch_init_modules(x)	do { } while (0)
 
 #endif /* _ASM_S390_MODULE_H */
diff -up --recursive --new-file linux-mips-2.4.5-20010704.macro/include/asm-sh/module.h linux-mips-2.4.5-20010704/include/asm-sh/module.h
--- linux-mips-2.4.5-20010704.macro/include/asm-sh/module.h	Tue Nov 28 03:59:03 2000
+++ linux-mips-2.4.5-20010704/include/asm-sh/module.h	Mon Aug 20 01:12:58 2001
@@ -7,5 +7,6 @@
 #define module_map(x)		vmalloc(x)
 #define module_unmap(x)		vfree(x)
 #define module_arch_init(x)	(0)
+#define arch_init_modules(x)	do { } while (0)
 
 #endif /* _ASM_SH_MODULE_H */
diff -up --recursive --new-file linux-mips-2.4.5-20010704.macro/include/asm-sparc/module.h linux-mips-2.4.5-20010704/include/asm-sparc/module.h
--- linux-mips-2.4.5-20010704.macro/include/asm-sparc/module.h	Tue Nov 28 03:59:03 2000
+++ linux-mips-2.4.5-20010704/include/asm-sparc/module.h	Mon Aug 20 01:13:03 2001
@@ -7,5 +7,6 @@
 #define module_map(x)		vmalloc(x)
 #define module_unmap(x)		vfree(x)
 #define module_arch_init(x)	(0)
+#define arch_init_modules(x)	do { } while (0)
 
 #endif /* _ASM_SPARC_MODULE_H */
diff -up --recursive --new-file linux-mips-2.4.5-20010704.macro/include/asm-sparc64/module.h linux-mips-2.4.5-20010704/include/asm-sparc64/module.h
--- linux-mips-2.4.5-20010704.macro/include/asm-sparc64/module.h	Tue Nov 28 03:59:03 2000
+++ linux-mips-2.4.5-20010704/include/asm-sparc64/module.h	Mon Aug 20 01:13:19 2001
@@ -7,5 +7,6 @@
 extern void * module_map (unsigned long size);
 extern void module_unmap (void *addr);
 #define module_arch_init(x)	(0)
+#define arch_init_modules(x)	do { } while (0)
 
 #endif /* _ASM_SPARC64_MODULE_H */
diff -up --recursive --new-file linux-mips-2.4.5-20010704.macro/kernel/module.c linux-mips-2.4.5-20010704/kernel/module.c
--- linux-mips-2.4.5-20010704.macro/kernel/module.c	Thu Jun 14 04:28:48 2001
+++ linux-mips-2.4.5-20010704/kernel/module.c	Sun Aug 19 20:10:35 2001
@@ -246,9 +246,7 @@ void __init init_modules(void)
 {
 	kernel_module.nsyms = __stop___ksymtab - __start___ksymtab;
 
-#ifdef __alpha__
-	__asm__("stq $29,%0" : "=m"(kernel_module.gp));
-#endif
+	arch_init_modules(&kernel_module);
 }
 
 /*
@@ -440,12 +438,6 @@ sys_init_module(const char *name_user, s
 		printk(KERN_ERR "init_module: mod->flags invalid.\n");
 		goto err2;
 	}
-#ifdef __alpha__
-	if (!mod_bound(mod->gp - 0x8000, 0, mod)) {
-		printk(KERN_ERR "init_module: mod->gp out of bounds.\n");
-		goto err2;
-	}
-#endif
 	if (mod_member_present(mod, can_unload)
 	    && mod->can_unload && !mod_bound(mod->can_unload, 0, mod)) {
 		printk(KERN_ERR "init_module: mod->can_unload out of bounds.\n");

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [patch] linux 2.4.5: __dbe_table iteration #2
  2001-08-20 13:57 ` [patch] linux 2.4.5: __dbe_table iteration #2 Maciej W. Rozycki
@ 2001-08-23  1:49   ` Keith Owens
  2001-08-23 16:52     ` Maciej W. Rozycki
  0 siblings, 1 reply; 20+ messages in thread
From: Keith Owens @ 2001-08-23  1:49 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: Ralf Baechle, linux-mips, linux-mips

On Mon, 20 Aug 2001 15:57:21 +0200 (MET DST), 
"Maciej W. Rozycki" <macro@ds2.pg.gda.pl> wrote:
>+	for (mp = module_list; mp != NULL; mp = mp->next) {
>+		if (!mod_member_present(mp, archdata_start) ||
>+		    !mp->archdata_start)
>+			continue;
>+		ap = (struct archdata *)(mp->archdata_start);

The definition of struct archdata in kernel and modutils can be
different, a new kernel layout with an old modutils is legal but fatal
unless you code for it.  The correct test for archdata is

if (!mod_member_present(mp, archdata_start) ||
    (mp->archdata_end - mp->archdata_start) <=
     offsetof(struct archdata, dbe_table_end))
	continue;

Do not use archdata unless it is at least large enough to contain
dbe_table_end.  That test also takes care of NULL pointers, end - start
== 0 for NULL.

The rest of the code looks OK, except it needs a global change of
arch_init_module: to module_arch_init: to match the macro name.

Do you have the corresponding modutils patch or shall I do it?

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [patch] linux 2.4.5: Make __dbe_table available to modules
  2001-08-14 17:34       ` Maciej W. Rozycki
@ 2001-08-23 11:23         ` Gleb O. Raiko
  2001-08-23 15:46           ` Maciej W. Rozycki
  0 siblings, 1 reply; 20+ messages in thread
From: Gleb O. Raiko @ 2001-08-23 11:23 UTC (permalink / raw)
  To: Maciej W. Rozycki
  Cc: Ralf Baechle, Harald Koerfgen, Keith Owens, linux-mips,
	linux-mips

"Maciej W. Rozycki" wrote:
> 
> On Mon, 13 Aug 2001, Gleb O. Raiko wrote:
> 
> > DBE is treated as ACK* on write. Some HW design manuals advise to use
> > this fact even.
> 
>  And what is the use of ACK*?

Acknowledge. It's used to indicate current transaction has been
processed successfully. If you are interested in details, I would
suggest you read a MIPS hardware manual, for example, IDT's one.

The most intriguing feature is:
"Write transactions terminated by BusError* do not require the assertion
of Ack*. BusError* can be asserted at at any time the processor is
looking for Ack* to be asserted, up to and including the cycle in which
the memory system does signal Ack*."

> 
>  Note that that the state of the CPU at the moment of a write is
> completely unrelated to the action that triggered the write.  Therefore
> any reporting of a write failure is hardly useful -- possibly as a kind of
> an MCE only, i.e. report the event and kill the current process or panic
> if none.

I consider external signaling of write failures may be useful for kernel
debugging purposes. I agree it's hard (or even impossible) to achieve
proper behaviour on write failures for user space. There is a small
chance to kill another process, for example, write transactions may
delay due to write buffer. So, the kernel may only print something.

Regards,
Gleb.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [patch] linux 2.4.5: Make __dbe_table available to modules
  2001-08-23 11:23         ` Gleb O. Raiko
@ 2001-08-23 15:46           ` Maciej W. Rozycki
  2001-08-23 20:11             ` bus error by write transaction (RE: [patch] linux 2.4.5: Make __dbe_table available to modules) Hiroo Hayashi
  0 siblings, 1 reply; 20+ messages in thread
From: Maciej W. Rozycki @ 2001-08-23 15:46 UTC (permalink / raw)
  To: Gleb O. Raiko; +Cc: linux-mips, linux-mips

On Thu, 23 Aug 2001, Gleb O. Raiko wrote:

> Acknowledge. It's used to indicate current transaction has been
> processed successfully. If you are interested in details, I would
> suggest you read a MIPS hardware manual, for example, IDT's one.

 I see if I can find a suitable onein my archive.  I have an IDT CD-ROM,
but it's quite new -- dated 1997 -- and it lacks a lot of earlier stuff.
There is an R5k hw manual there, though, I think.  Too bad they got rid of
end of line stuff -- there is only ~140MB of space consumed on the CD so
there would be much room for reference docs for older parts...

> The most intriguing feature is:
> "Write transactions terminated by BusError* do not require the assertion
> of Ack*. BusError* can be asserted at at any time the processor is
> looking for Ack* to be asserted, up to and including the cycle in which
> the memory system does signal Ack*."

 Interesting.  So bus errors on write transactions seem to be somehow
supported from the hardware's point of view.  But software can't determine
the type of a bus cycle that triggered an error.  E.g. if you expect a
load instruction to trigger a bus error in some cases and you indeed get
one, you can't tell if the error was due to this instruction or due to a
write cycle triggered by some antecedent code.  I think that's the reason
of the suggestion of not using this kind of reporting -- if you limit bus
errors to read/fetch transactions in the ISA definition, you get rid of
this ambiguity. 

> I consider external signaling of write failures may be useful for kernel
> debugging purposes. I agree it's hard (or even impossible) to achieve
> proper behaviour on write failures for user space. There is a small
> chance to kill another process, for example, write transactions may
> delay due to write buffer. So, the kernel may only print something.

 Or, more severly and importantly, a write-back cache.  We provide such
diagnostics but it's dubious for writes.  You are right, it might be
useful for debugging in some cases, though.

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [patch] linux 2.4.5: __dbe_table iteration #2
  2001-08-23  1:49   ` Keith Owens
@ 2001-08-23 16:52     ` Maciej W. Rozycki
  2001-08-23 23:11       ` Keith Owens
  0 siblings, 1 reply; 20+ messages in thread
From: Maciej W. Rozycki @ 2001-08-23 16:52 UTC (permalink / raw)
  To: Keith Owens; +Cc: Ralf Baechle, linux-mips, linux-mips

On Thu, 23 Aug 2001, Keith Owens wrote:

> The definition of struct archdata in kernel and modutils can be
> different, a new kernel layout with an old modutils is legal but fatal
> unless you code for it.  The correct test for archdata is
> 
> if (!mod_member_present(mp, archdata_start) ||
>     (mp->archdata_end - mp->archdata_start) <=
>      offsetof(struct archdata, dbe_table_end))
> 	continue;
> 
> Do not use archdata unless it is at least large enough to contain
> dbe_table_end.  That test also takes care of NULL pointers, end - start
> == 0 for NULL.

 Hmm, your suggested code checks if the passed struct is long enough for
dbe_table_start only -- what about dbe_table_end?  The following code: 

ap = (struct archdata *)(mod->archdata_start);
if (!mod_member_present(mp, archdata_start) ||
    (mp->archdata_end - mp->archdata_start) <
     offsetof(struct archdata, dbe_table_end) + sizeof(ap->dbe_table_end))
      continue;

should be stricter.  While modutils as released won't ever pass a smaller
struct, someone may modify them or use another program to invoke
init_module(), so we need to protect the kernel against bogus data. 

> The rest of the code looks OK, except it needs a global change of
> arch_init_module: to module_arch_init: to match the macro name.

 OK, I'll do it.  It should have been done for ia64 in the first place.
Or should it be changed into "<arch>_init_module" to match functions' real
names?

> Do you have the corresponding modutils patch or shall I do it? 

 I've send it to you separately just after the kernel patch.  Should I
resend it? 

  Maciej

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

^ permalink raw reply	[flat|nested] 20+ messages in thread

* bus error by write transaction (RE: [patch] linux 2.4.5: Make __dbe_table available to modules)
  2001-08-23 15:46           ` Maciej W. Rozycki
@ 2001-08-23 20:11             ` Hiroo Hayashi
  2001-08-23 20:11               ` Hiroo Hayashi
  2001-08-24 16:18               ` Maciej W. Rozycki
  0 siblings, 2 replies; 20+ messages in thread
From: Hiroo Hayashi @ 2001-08-23 20:11 UTC (permalink / raw)
  To: Maciej W. Rozycki, Gleb O. Raiko; +Cc: linux-mips, linux-mips

Hi,

> > I consider external signaling of write failures may be useful for kernel
> > debugging purposes. I agree it's hard (or even impossible) to achieve
> > proper behaviour on write failures for user space. There is a small
> > chance to kill another process, for example, write transactions may
> > delay due to write buffer. So, the kernel may only print something.
> 
>  Or, more severly and importantly, a write-back cache.  We provide such
> diagnostics but it's dubious for writes.  You are right, it might be
> useful for debugging in some cases, though.

Yes, most MIPS CPU except very old one use writeback cache.

Note that most MIPS documents use word 'load' and 'store' for instruction,
and 'read' and 'write' for bus transaction.  You have to distinguish them.

On a system with writeback cache, a write bus transaction is issued when
a modified cache line is replaced by a cache miss for either load
instruction or store instruction.

(Here I'm ignoring I/O access to make the point clear.)

The data on a write bus transaction may be a data modified by a store
instruction which was issued some years ago :-)  What the OS can do?

Hiro

^ permalink raw reply	[flat|nested] 20+ messages in thread

* bus error by write transaction (RE: [patch] linux 2.4.5: Make __dbe_table available to modules)
  2001-08-23 20:11             ` bus error by write transaction (RE: [patch] linux 2.4.5: Make __dbe_table available to modules) Hiroo Hayashi
@ 2001-08-23 20:11               ` Hiroo Hayashi
  2001-08-24 16:18               ` Maciej W. Rozycki
  1 sibling, 0 replies; 20+ messages in thread
From: Hiroo Hayashi @ 2001-08-23 20:11 UTC (permalink / raw)
  To: Maciej W. Rozycki, Gleb O. Raiko; +Cc: linux-mips, linux-mips

Hi,

> > I consider external signaling of write failures may be useful for kernel
> > debugging purposes. I agree it's hard (or even impossible) to achieve
> > proper behaviour on write failures for user space. There is a small
> > chance to kill another process, for example, write transactions may
> > delay due to write buffer. So, the kernel may only print something.
> 
>  Or, more severly and importantly, a write-back cache.  We provide such
> diagnostics but it's dubious for writes.  You are right, it might be
> useful for debugging in some cases, though.

Yes, most MIPS CPU except very old one use writeback cache.

Note that most MIPS documents use word 'load' and 'store' for instruction,
and 'read' and 'write' for bus transaction.  You have to distinguish them.

On a system with writeback cache, a write bus transaction is issued when
a modified cache line is replaced by a cache miss for either load
instruction or store instruction.

(Here I'm ignoring I/O access to make the point clear.)

The data on a write bus transaction may be a data modified by a store
instruction which was issued some years ago :-)  What the OS can do?

Hiro

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [patch] linux 2.4.5: __dbe_table iteration #2
  2001-08-23 16:52     ` Maciej W. Rozycki
@ 2001-08-23 23:11       ` Keith Owens
  2001-08-24 15:44         ` Maciej W. Rozycki
  2001-08-24 15:49         ` Keith Owens
  0 siblings, 2 replies; 20+ messages in thread
From: Keith Owens @ 2001-08-23 23:11 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: Ralf Baechle, linux-mips, linux-mips

On Thu, 23 Aug 2001 18:52:45 +0200 (MET DST), 
"Maciej W. Rozycki" <macro@ds2.pg.gda.pl> wrote:
>On Thu, 23 Aug 2001, Keith Owens wrote:
>> The definition of struct archdata in kernel and modutils can be
>> different, a new kernel layout with an old modutils is legal but fatal
>> unless you code for it.  The correct test for archdata is
>> 
>> if (!mod_member_present(mp, archdata_start) ||
>>     (mp->archdata_end - mp->archdata_start) <=
>>      offsetof(struct archdata, dbe_table_end))
>> 	continue;
> Hmm, your suggested code checks if the passed struct is long enough for
>dbe_table_start only -- what about dbe_table_end?  The following code: 

If archdata_end-archdata_start <= offsetof(dbe_table_end) then archdata
is too small to contain the first byte of dbe_table_end, skip the
archdata.  If archdata is large enough to contain the first byte of
dbe_table_end, assume that it contains all of dbe_table_end.

>While modutils as released won't ever pass a smaller
>struct, someone may modify them or use another program to invoke
>init_module(), so we need to protect the kernel against bogus data. 

You have to be root to call init_module() or run insmod, root can do a
lot more damage than passing an invalid structure size.  This type of
test is not to catch malicious code, it is to detect that the user is
running an old modutils with a smaller archdata than the kernel can
handle.

You are correct that modutils as released will never pass a smaller
archdata struct for mips so strictly speaking this test is superfluous.
However this type of code gets cut and pasted so I want size checking
on all archdata, when it is copied the developer has to think about
changing the test instead of forgetting to add a test.

Your suggested code works just as well but is less readable.  Go with
either.

>> The rest of the code looks OK, except it needs a global change of
>> arch_init_module: to module_arch_init: to match the macro name.
>
> OK, I'll do it.  It should have been done for ia64 in the first place.
>Or should it be changed into "<arch>_init_module" to match functions' real
>names?

Leave it as module_arch_init, it tells us how the code was called.

>> Do you have the corresponding modutils patch or shall I do it? 
>
> I've send it to you separately just after the kernel patch.  Should I
>resend it? 

No thanks, I found it.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [patch] linux 2.4.5: __dbe_table iteration #2
  2001-08-23 23:11       ` Keith Owens
@ 2001-08-24 15:44         ` Maciej W. Rozycki
  2001-08-27  3:09           ` Keith Owens
  2001-08-24 15:49         ` Keith Owens
  1 sibling, 1 reply; 20+ messages in thread
From: Maciej W. Rozycki @ 2001-08-24 15:44 UTC (permalink / raw)
  To: Keith Owens; +Cc: Ralf Baechle, linux-mips, linux-mips

On Fri, 24 Aug 2001, Keith Owens wrote:

> You have to be root to call init_module() or run insmod, root can do a
> lot more damage than passing an invalid structure size.  This type of
> test is not to catch malicious code, it is to detect that the user is
> running an old modutils with a smaller archdata than the kernel can
> handle.

 I mean it as a test to catch buggy, not malicious code.  For malicious
code run by root there is not much to do.  Besides, the code is not any
longer nor slower.  Adding a case-specific small constant instead of fixed
one is achieved via the same processor's instructions -- only their
operands differ. 

> You are correct that modutils as released will never pass a smaller
> archdata struct for mips so strictly speaking this test is superfluous.
> However this type of code gets cut and pasted so I want size checking
> on all archdata, when it is copied the developer has to think about
> changing the test instead of forgetting to add a test.

 Sure, agreed.  For this reason the ia64 code need a bit of cleanup, too. 

> Your suggested code works just as well but is less readable.  Go with
> either.

 Ok, that's not much readable, indeed.  Thus I've invented a macro.  See
a following patch hiding implementation details.

> Leave it as module_arch_init, it tells us how the code was called.

 OK.

  Maciej

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

patch-mips-2.4.5-20010704-dbe-13
diff -up --recursive --new-file linux-mips-2.4.5-20010704.macro/arch/mips/kernel/traps.c linux-mips-2.4.5-20010704/arch/mips/kernel/traps.c
--- linux-mips-2.4.5-20010704.macro/arch/mips/kernel/traps.c	Fri Jun 15 04:27:07 2001
+++ linux-mips-2.4.5-20010704/arch/mips/kernel/traps.c	Fri Aug 24 00:58:00 2001
@@ -14,6 +14,7 @@
 #include <linux/config.h>
 #include <linux/init.h>
 #include <linux/mm.h>
+#include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
@@ -25,6 +26,7 @@
 #include <asm/cachectl.h>
 #include <asm/inst.h>
 #include <asm/jazz.h>
+#include <asm/module.h>
 #include <asm/pgtable.h>
 #include <asm/io.h>
 #include <asm/siginfo.h>
@@ -254,23 +256,68 @@ search_one_table(const struct exception_
 	return (first == last && first->insn == value) ? first->nextinsn : 0;
 }
 
-#define search_dbe_table(addr)	\
-	search_one_table(__start___dbe_table, __stop___dbe_table - 1, (addr))
+extern spinlock_t modlist_lock;
+
+static inline unsigned long
+search_dbe_table(unsigned long addr)
+{
+	unsigned long ret = 0;
+
+#ifndef CONFIG_MODULES
+	/* There is only the kernel to search.  */
+	ret = search_one_table(__start___dbe_table, __stop___dbe_table-1, addr);
+	return ret;
+#else
+	unsigned long flags;
+
+	/* The kernel is the last "module" -- no need to treat it special.  */
+	struct module *mp;
+	struct archdata *ap;
+
+	spin_lock_irqsave(&modlist_lock, flags);
+	for (mp = module_list; mp != NULL; mp = mp->next) {
+		if (!mod_member_present(mp, archdata_end) ||
+        	    !mod_archdata_member_present(mp, struct archdata,
+						 dbe_table_end))
+			continue;
+		ap = (struct archdata *)(mp->archdata_start);
+
+		if (ap->dbe_table_start == NULL ||
+		    !(mp->flags & (MOD_RUNNING | MOD_INITIALIZING)))
+			continue;
+		ret = search_one_table(ap->dbe_table_start,
+				       ap->dbe_table_end - 1, addr);
+		if (ret)
+			break;
+	}
+	spin_unlock_irqrestore(&modlist_lock, flags);
+	return ret;
+#endif
+}
 
 static void default_be_board_handler(struct pt_regs *regs)
 {
 	unsigned long new_epc;
-	unsigned long fixup = search_dbe_table(regs->cp0_epc);
+	unsigned long fixup;
+	int data = regs->cp0_cause & 4;
 
-	if (fixup) {
-		new_epc = fixup_exception(dpf_reg, fixup, regs->cp0_epc);
-		regs->cp0_epc = new_epc;
-		return;
+	if (data && !user_mode(regs)) {
+		fixup = search_dbe_table(regs->cp0_epc);
+		if (fixup) {
+			new_epc = fixup_exception(dpf_reg, fixup,
+						  regs->cp0_epc);
+			regs->cp0_epc = new_epc;
+			return;
+		}
 	}
 
 	/*
 	 * Assume it would be too dangerous to continue ...
 	 */
+	printk(KERN_ALERT "%s bus error, epc == %08lx, ra == %08lx\n",
+	       data ? "Data" : "Instruction",
+	       regs->cp0_epc, regs->regs[31]);
+	die_if_kernel("Oops", regs);
 	force_sig(SIGBUS, current);
 }
 
diff -up --recursive --new-file linux-mips-2.4.5-20010704.macro/arch/mips64/sgi-ip22/ip22-berr.c linux-mips-2.4.5-20010704/arch/mips64/sgi-ip22/ip22-berr.c
--- linux-mips-2.4.5-20010704.macro/arch/mips64/sgi-ip22/ip22-berr.c	Thu Feb 24 05:26:11 2000
+++ linux-mips-2.4.5-20010704/arch/mips64/sgi-ip22/ip22-berr.c	Fri Aug 24 00:58:38 2001
@@ -9,6 +9,9 @@
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <asm/module.h>
 #include <asm/uaccess.h>
 #include <asm/paccess.h>
 #include <asm/addrspace.h>
@@ -41,16 +44,43 @@ search_one_table(const struct exception_
 	return 0;
 }
 
+extern spinlock_t modlist_lock;
+
 static inline unsigned long
 search_dbe_table(unsigned long addr)
 {
-	unsigned long ret;
+	unsigned long ret = 0;
 
+#ifndef CONFIG_MODULES
 	/* There is only the kernel to search.  */
 	ret = search_one_table(__start___dbe_table, __stop___dbe_table-1, addr);
-	if (ret) return ret;
-
-	return 0;
+	return ret;
+#else
+	unsigned long flags;
+
+	/* The kernel is the last "module" -- no need to treat it special.  */
+	struct module *mp;
+	struct archdata *ap;
+
+	spin_lock_irqsave(&modlist_lock, flags);
+	for (mp = module_list; mp != NULL; mp = mp->next) {
+		if (!mod_member_present(mp, archdata_end) ||
+        	    !mod_archdata_member_present(mp, struct archdata,
+						 dbe_table_end))
+			continue;
+		ap = (struct archdata *)(mod->archdata_start);
+
+		if (ap->dbe_table_start == NULL ||
+		    !(mp->flags & (MOD_RUNNING | MOD_INITIALIZING)))
+			continue;
+		ret = search_one_table(ap->dbe_table_start,
+				       ap->dbe_table_end - 1, addr);
+		if (ret)
+			break;
+	}
+	spin_unlock_irqrestore(&modlist_lock, flags);
+	return ret;
+#endif
 }
 
 void do_ibe(struct pt_regs *regs)
diff -up --recursive --new-file linux-mips-2.4.5-20010704.macro/arch/mips64/sgi-ip27/ip27-berr.c linux-mips-2.4.5-20010704/arch/mips64/sgi-ip27/ip27-berr.c
--- linux-mips-2.4.5-20010704.macro/arch/mips64/sgi-ip27/ip27-berr.c	Sat Feb 24 05:26:18 2001
+++ linux-mips-2.4.5-20010704/arch/mips64/sgi-ip27/ip27-berr.c	Fri Aug 24 00:58:47 2001
@@ -8,6 +8,9 @@
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <asm/module.h>
 #include <asm/sn/addrs.h>
 #include <asm/sn/arch.h>
 #include <asm/sn/sn0/hub.h>
@@ -43,16 +46,43 @@ search_one_table(const struct exception_
 	return 0;
 }
 
+extern spinlock_t modlist_lock;
+
 static inline unsigned long
 search_dbe_table(unsigned long addr)
 {
 	unsigned long ret;
 
+#ifndef CONFIG_MODULES
 	/* There is only the kernel to search.  */
 	ret = search_one_table(__start___dbe_table, __stop___dbe_table-1, addr);
-	if (ret) return ret;
-
-	return 0;
+	return ret;
+#else
+	unsigned long flags;
+
+	/* The kernel is the last "module" -- no need to treat it special.  */
+	struct module *mp;
+	struct archdata *ap;
+
+	spin_lock_irqsave(&modlist_lock, flags);
+	for (mp = module_list; mp != NULL; mp = mp->next) {
+		if (!mod_member_present(mp, archdata_end) ||
+        	    !mod_archdata_member_present(mp, struct archdata,
+						 dbe_table_end))
+			continue;
+		ap = (struct archdata *)(mod->archdata_start);
+
+		if (ap->dbe_table_start == NULL ||
+		    !(mp->flags & (MOD_RUNNING | MOD_INITIALIZING)))
+			continue;
+		ret = search_one_table(ap->dbe_table_start,
+				       ap->dbe_table_end - 1, addr);
+		if (ret)
+			break;
+	}
+	spin_unlock_irqrestore(&modlist_lock, flags);
+	return ret;
+#endif
 }
 
 void do_ibe(struct pt_regs *regs)
diff -up --recursive --new-file linux-mips-2.4.5-20010704.macro/include/asm-alpha/module.h linux-mips-2.4.5-20010704/include/asm-alpha/module.h
--- linux-mips-2.4.5-20010704.macro/include/asm-alpha/module.h	Tue Nov 28 03:59:03 2000
+++ linux-mips-2.4.5-20010704/include/asm-alpha/module.h	Fri Aug 24 00:59:47 2001
@@ -6,6 +6,23 @@
 
 #define module_map(x)		vmalloc(x)
 #define module_unmap(x)		vfree(x)
-#define module_arch_init(x)	(0)
+#define module_arch_init(x)	alpha_module_init(x)
+#define arch_init_modules(x)	alpha_init_modules(x)
+
+static inline int
+alpha_module_init(struct module *mod)
+{
+        if (!mod_bound(mod->gp - 0x8000, 0, mod)) {
+                printk(KERN_ERR "module_arch_init: mod->gp out of bounds.\n");
+                return 1;
+        }
+	return 0;
+}
+
+static inline void
+alpha_init_modules(struct module *mod)
+{
+	__asm__("stq $29,%0" : "=m" (mod->gp));
+}
 
 #endif /* _ASM_ALPHA_MODULE_H */
diff -up --recursive --new-file linux-mips-2.4.5-20010704.macro/include/asm-arm/module.h linux-mips-2.4.5-20010704/include/asm-arm/module.h
--- linux-mips-2.4.5-20010704.macro/include/asm-arm/module.h	Tue Nov 28 03:59:03 2000
+++ linux-mips-2.4.5-20010704/include/asm-arm/module.h	Mon Aug 20 01:11:58 2001
@@ -7,5 +7,6 @@
 #define module_map(x)		vmalloc(x)
 #define module_unmap(x)		vfree(x)
 #define module_arch_init(x)	(0)
+#define arch_init_modules(x)	do { } while (0)
 
 #endif /* _ASM_ARM_MODULE_H */
diff -up --recursive --new-file linux-mips-2.4.5-20010704.macro/include/asm-cris/module.h linux-mips-2.4.5-20010704/include/asm-cris/module.h
--- linux-mips-2.4.5-20010704.macro/include/asm-cris/module.h	Fri Mar  9 20:34:43 2001
+++ linux-mips-2.4.5-20010704/include/asm-cris/module.h	Mon Aug 20 01:12:04 2001
@@ -7,5 +7,6 @@
 #define module_map(x)		vmalloc(x)
 #define module_unmap(x)		vfree(x)
 #define module_arch_init(x)	(0)
+#define arch_init_modules(x)	do { } while (0)
 
 #endif /* _ASM_CRIS_MODULE_H */
diff -up --recursive --new-file linux-mips-2.4.5-20010704.macro/include/asm-i386/module.h linux-mips-2.4.5-20010704/include/asm-i386/module.h
--- linux-mips-2.4.5-20010704.macro/include/asm-i386/module.h	Tue Nov 28 03:59:03 2000
+++ linux-mips-2.4.5-20010704/include/asm-i386/module.h	Mon Aug 20 01:12:08 2001
@@ -7,5 +7,6 @@
 #define module_map(x)		vmalloc(x)
 #define module_unmap(x)		vfree(x)
 #define module_arch_init(x)	(0)
+#define arch_init_modules(x)	do { } while (0)
 
 #endif /* _ASM_I386_MODULE_H */
diff -up --recursive --new-file linux-mips-2.4.5-20010704.macro/include/asm-ia64/module.h linux-mips-2.4.5-20010704/include/asm-ia64/module.h
--- linux-mips-2.4.5-20010704.macro/include/asm-ia64/module.h	Thu Jun 14 04:28:30 2001
+++ linux-mips-2.4.5-20010704/include/asm-ia64/module.h	Fri Aug 24 01:03:17 2001
@@ -14,6 +14,7 @@
 #define module_map(x)		vmalloc(x)
 #define module_unmap(x)		ia64_module_unmap(x)
 #define module_arch_init(x)	ia64_module_init(x)
+#define ia64_module_inits(x)	do { } while (0)
 
 /*
  * This must match in size and layout the data created by
@@ -46,27 +47,27 @@ ia64_module_init(struct module *mod)
 
 	if (archdata->unw_table)
 	{
-		printk(KERN_ERR "arch_init_module: archdata->unw_table must be zero.\n");
+		printk(KERN_ERR "module_arch_init: archdata->unw_table must be zero.\n");
 		return 1;
 	}
 	if (!mod_bound(archdata->gp, 0, mod))
 	{
-		printk(KERN_ERR "arch_init_module: archdata->gp out of bounds.\n");
+		printk(KERN_ERR "module_arch_init: archdata->gp out of bounds.\n");
 		return 1;
 	}
 	if (!mod_bound(archdata->unw_start, 0, mod))
 	{
-		printk(KERN_ERR "arch_init_module: archdata->unw_start out of bounds.\n");
+		printk(KERN_ERR "module_arch_init: archdata->unw_start out of bounds.\n");
 		return 1;
 	}
 	if (!mod_bound(archdata->unw_end, 0, mod))
 	{
-		printk(KERN_ERR "arch_init_module: archdata->unw_end out of bounds.\n");
+		printk(KERN_ERR "module_arch_init: archdata->unw_end out of bounds.\n");
 		return 1;
 	}
 	if (!mod_bound(archdata->segment_base, 0, mod))
 	{
-		printk(KERN_ERR "arch_init_module: archdata->unw_table out of bounds.\n");
+		printk(KERN_ERR "module_arch_init: archdata->unw_table out of bounds.\n");
 		return 1;
 	}
 
diff -up --recursive --new-file linux-mips-2.4.5-20010704.macro/include/asm-m68k/module.h linux-mips-2.4.5-20010704/include/asm-m68k/module.h
--- linux-mips-2.4.5-20010704.macro/include/asm-m68k/module.h	Tue Nov 28 03:59:03 2000
+++ linux-mips-2.4.5-20010704/include/asm-m68k/module.h	Mon Aug 20 01:12:18 2001
@@ -7,5 +7,6 @@
 #define module_map(x)		vmalloc(x)
 #define module_unmap(x)		vfree(x)
 #define module_arch_init(x)	(0)
+#define arch_init_modules(x)	do { } while (0)
 
 #endif /* _ASM_M68K_MODULE_H */
diff -up --recursive --new-file linux-mips-2.4.5-20010704.macro/include/asm-mips/module.h linux-mips-2.4.5-20010704/include/asm-mips/module.h
--- linux-mips-2.4.5-20010704.macro/include/asm-mips/module.h	Tue Nov 28 03:59:03 2000
+++ linux-mips-2.4.5-20010704/include/asm-mips/module.h	Fri Aug 24 00:54:50 2001
@@ -4,8 +4,64 @@
  * This file contains the mips architecture specific module code.
  */
 
+#include <linux/module.h>
+#include <asm/uaccess.h>
+
 #define module_map(x)		vmalloc(x)
 #define module_unmap(x)		vfree(x)
-#define module_arch_init(x)	(0)
+#define module_arch_init(x)	mips_module_init(x)
+#define arch_init_modules(x)	mips_init_modules(x)
+
+/*
+ * This must match in size and layout the data created by
+ * modutils/obj/obj-mips.c
+ */
+struct archdata {
+	const struct exception_table_entry *dbe_table_start;
+	const struct exception_table_entry *dbe_table_end;
+};
+
+static inline int
+mips_module_init(struct module *mod)
+{
+	struct archdata *archdata;
+
+	if (!mod_member_present(mod, archdata_end))
+		return 0;
+
+	archdata = (struct archdata *)(mod->archdata_start);
+	if (!mod_archdata_member_present(mod, struct archdata, dbe_table_end))
+		return 0;
+
+	if (archdata->dbe_table_start > archdata->dbe_table_end ||
+	    (archdata->dbe_table_start &&
+	     !((unsigned long)archdata->dbe_table_start >=
+	       ((unsigned long)mod + mod->size_of_struct) &&
+	       ((unsigned long)archdata->dbe_table_end <
+	        (unsigned long)mod + mod->size))) ||
+            (((unsigned long)archdata->dbe_table_start -
+	      (unsigned long)archdata->dbe_table_end) %
+	     sizeof(struct exception_table_entry))) {
+		printk(KERN_ERR
+			"module_arch_init: archdata->dbe_table_* invalid.\n");
+		return 1;
+	}
+
+	return 0;
+}
+
+static inline void
+mips_init_modules(struct module *mod)
+{
+	extern const struct exception_table_entry __start___dbe_table[];
+	extern const struct exception_table_entry __stop___dbe_table[];
+	static struct archdata archdata = {
+		dbe_table_start:	__start___dbe_table,
+		dbe_table_end:		__stop___dbe_table,
+	};
+
+	mod->archdata_start = (char *)&archdata;
+	mod->archdata_end = mod->archdata_start + sizeof(archdata);
+}
 
 #endif /* _ASM_MIPS_MODULE_H */
diff -up --recursive --new-file linux-mips-2.4.5-20010704.macro/include/asm-mips64/module.h linux-mips-2.4.5-20010704/include/asm-mips64/module.h
--- linux-mips-2.4.5-20010704.macro/include/asm-mips64/module.h	Tue Nov 28 03:59:03 2000
+++ linux-mips-2.4.5-20010704/include/asm-mips64/module.h	Fri Aug 24 00:55:00 2001
@@ -4,8 +4,64 @@
  * This file contains the mips64 architecture specific module code.
  */
 
+#include <linux/module.h>
+#include <asm/uaccess.h>
+
 #define module_map(x)		vmalloc(x)
 #define module_unmap(x)		vfree(x)
-#define module_arch_init(x)	(0)
+#define module_arch_init(x)	mips64_module_init(x)
+#define arch_init_modules(x)	mips64_init_modules(x)
+
+/*
+ * This must match in size and layout the data created by
+ * modutils/obj/obj-mips64.c
+ */
+struct archdata {
+	const struct exception_table_entry *dbe_table_start;
+	const struct exception_table_entry *dbe_table_end;
+};
+
+static inline int
+mips64_module_init(struct module *mod)
+{
+	struct archdata *archdata;
+
+	if (!mod_member_present(mod, archdata_end))
+		return 0;
+
+	archdata = (struct archdata *)(mod->archdata_start);
+	if (!mod_archdata_member_present(mod, struct archdata, dbe_table_end))
+		return 0;
+
+	if (archdata->dbe_table_start > archdata->dbe_table_end ||
+	    (archdata->dbe_table_start &&
+	     !((unsigned long)archdata->dbe_table_start >=
+	       ((unsigned long)mod + mod->size_of_struct) &&
+	       ((unsigned long)archdata->dbe_table_end <
+	        (unsigned long)mod + mod->size))) ||
+            (((unsigned long)archdata->dbe_table_start -
+	      (unsigned long)archdata->dbe_table_end) %
+	     sizeof(struct exception_table_entry))) {
+		printk(KERN_ERR
+			"module_arch_init: archdata->dbe_table_* invalid.\n");
+		return 1;
+	}
+
+	return 0;
+}
+
+static inline void
+mips64_init_modules(struct module *mod)
+{
+	extern const struct exception_table_entry __start___dbe_table[];
+	extern const struct exception_table_entry __stop___dbe_table[];
+	static struct archdata archdata = {
+		dbe_table_start:	__start___dbe_table,
+		dbe_table_end:		__stop___dbe_table,
+	};
+
+	mod->archdata_start = (char *)&archdata;
+	mod->archdata_end = mod->archdata_start + sizeof(archdata);
+}
 
 #endif /* _ASM_MIPS64_MODULE_H */
diff -up --recursive --new-file linux-mips-2.4.5-20010704.macro/include/asm-ppc/module.h linux-mips-2.4.5-20010704/include/asm-ppc/module.h
--- linux-mips-2.4.5-20010704.macro/include/asm-ppc/module.h	Thu Jun 14 04:28:38 2001
+++ linux-mips-2.4.5-20010704/include/asm-ppc/module.h	Mon Aug 20 01:12:29 2001
@@ -10,5 +10,6 @@
 #define module_map(x)		vmalloc(x)
 #define module_unmap(x)		vfree(x)
 #define module_arch_init(x)	(0)
+#define arch_init_modules(x)	do { } while (0)
 
 #endif /* _ASM_PPC_MODULE_H */
diff -up --recursive --new-file linux-mips-2.4.5-20010704.macro/include/asm-s390/module.h linux-mips-2.4.5-20010704/include/asm-s390/module.h
--- linux-mips-2.4.5-20010704.macro/include/asm-s390/module.h	Tue Nov 28 03:59:03 2000
+++ linux-mips-2.4.5-20010704/include/asm-s390/module.h	Mon Aug 20 01:12:37 2001
@@ -7,5 +7,6 @@
 #define module_map(x)		vmalloc(x)
 #define module_unmap(x)		vfree(x)
 #define module_arch_init(x)	(0)
+#define arch_init_modules(x)	do { } while (0)
 
 #endif /* _ASM_S390_MODULE_H */
diff -up --recursive --new-file linux-mips-2.4.5-20010704.macro/include/asm-s390x/module.h linux-mips-2.4.5-20010704/include/asm-s390x/module.h
--- linux-mips-2.4.5-20010704.macro/include/asm-s390x/module.h	Fri Mar  9 20:34:52 2001
+++ linux-mips-2.4.5-20010704/include/asm-s390x/module.h	Mon Aug 20 01:12:53 2001
@@ -7,5 +7,6 @@
 #define module_map(x)		vmalloc(x)
 #define module_unmap(x)		vfree(x)
 #define module_arch_init(x)	(0)
+#define arch_init_modules(x)	do { } while (0)
 
 #endif /* _ASM_S390_MODULE_H */
diff -up --recursive --new-file linux-mips-2.4.5-20010704.macro/include/asm-sh/module.h linux-mips-2.4.5-20010704/include/asm-sh/module.h
--- linux-mips-2.4.5-20010704.macro/include/asm-sh/module.h	Tue Nov 28 03:59:03 2000
+++ linux-mips-2.4.5-20010704/include/asm-sh/module.h	Mon Aug 20 01:12:58 2001
@@ -7,5 +7,6 @@
 #define module_map(x)		vmalloc(x)
 #define module_unmap(x)		vfree(x)
 #define module_arch_init(x)	(0)
+#define arch_init_modules(x)	do { } while (0)
 
 #endif /* _ASM_SH_MODULE_H */
diff -up --recursive --new-file linux-mips-2.4.5-20010704.macro/include/asm-sparc/module.h linux-mips-2.4.5-20010704/include/asm-sparc/module.h
--- linux-mips-2.4.5-20010704.macro/include/asm-sparc/module.h	Tue Nov 28 03:59:03 2000
+++ linux-mips-2.4.5-20010704/include/asm-sparc/module.h	Mon Aug 20 01:13:03 2001
@@ -7,5 +7,6 @@
 #define module_map(x)		vmalloc(x)
 #define module_unmap(x)		vfree(x)
 #define module_arch_init(x)	(0)
+#define arch_init_modules(x)	do { } while (0)
 
 #endif /* _ASM_SPARC_MODULE_H */
diff -up --recursive --new-file linux-mips-2.4.5-20010704.macro/include/asm-sparc64/module.h linux-mips-2.4.5-20010704/include/asm-sparc64/module.h
--- linux-mips-2.4.5-20010704.macro/include/asm-sparc64/module.h	Tue Nov 28 03:59:03 2000
+++ linux-mips-2.4.5-20010704/include/asm-sparc64/module.h	Mon Aug 20 01:13:19 2001
@@ -7,5 +7,6 @@
 extern void * module_map (unsigned long size);
 extern void module_unmap (void *addr);
 #define module_arch_init(x)	(0)
+#define arch_init_modules(x)	do { } while (0)
 
 #endif /* _ASM_SPARC64_MODULE_H */
diff -up --recursive --new-file linux-mips-2.4.5-20010704.macro/include/linux/module.h linux-mips-2.4.5-20010704/include/linux/module.h
--- linux-mips-2.4.5-20010704.macro/include/linux/module.h	Mon Jul 16 02:13:58 2001
+++ linux-mips-2.4.5-20010704/include/linux/module.h	Fri Aug 24 00:50:22 2001
@@ -130,6 +130,16 @@ struct module_info
 	((unsigned long)(&((struct module *)0L)->member + 1)		\
 	 <= (mod)->size_of_struct)
 
+/*
+ * Ditto for archdata.  Assumes mod->archdata_start and mod->archdata_end
+ * are validated elsewhere.
+ */
+#define mod_archdata_member_present(mod, type, member)			\
+	(((unsigned long)(&((type *)0L)->member) +			\
+	  sizeof(((type *)0L)->member)) <=				\
+	 ((mod)->archdata_end - (mod)->archdata_start))
+	 
+
 /* Check if an address p with number of entries n is within the body of module m */
 #define mod_bound(p, n, m) ((unsigned long)(p) >= ((unsigned long)(m) + ((m)->size_of_struct)) && \
 	         (unsigned long)((p)+(n)) <= (unsigned long)(m) + (m)->size)
diff -up --recursive --new-file linux-mips-2.4.5-20010704.macro/kernel/module.c linux-mips-2.4.5-20010704/kernel/module.c
--- linux-mips-2.4.5-20010704.macro/kernel/module.c	Thu Jun 14 04:28:48 2001
+++ linux-mips-2.4.5-20010704/kernel/module.c	Sun Aug 19 20:10:35 2001
@@ -246,9 +246,7 @@ void __init init_modules(void)
 {
 	kernel_module.nsyms = __stop___ksymtab - __start___ksymtab;
 
-#ifdef __alpha__
-	__asm__("stq $29,%0" : "=m"(kernel_module.gp));
-#endif
+	arch_init_modules(&kernel_module);
 }
 
 /*
@@ -440,12 +438,6 @@ sys_init_module(const char *name_user, s
 		printk(KERN_ERR "init_module: mod->flags invalid.\n");
 		goto err2;
 	}
-#ifdef __alpha__
-	if (!mod_bound(mod->gp - 0x8000, 0, mod)) {
-		printk(KERN_ERR "init_module: mod->gp out of bounds.\n");
-		goto err2;
-	}
-#endif
 	if (mod_member_present(mod, can_unload)
 	    && mod->can_unload && !mod_bound(mod->can_unload, 0, mod)) {
 		printk(KERN_ERR "init_module: mod->can_unload out of bounds.\n");

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [patch] linux 2.4.5: __dbe_table iteration #2
  2001-08-23 23:11       ` Keith Owens
  2001-08-24 15:44         ` Maciej W. Rozycki
@ 2001-08-24 15:49         ` Keith Owens
  1 sibling, 0 replies; 20+ messages in thread
From: Keith Owens @ 2001-08-24 15:49 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: Ralf Baechle, linux-mips, linux-mips

On Thu, 23 Aug 2001 18:52:45 +0200 (MET DST), 
"Maciej W. Rozycki" <macro@ds2.pg.gda.pl> wrote:
>On Thu, 23 Aug 2001, Keith Owens wrote:
>> The definition of struct archdata in kernel and modutils can be
>> different, a new kernel layout with an old modutils is legal but fatal
>> unless you code for it.  The correct test for archdata is
>> 
>> if (!mod_member_present(mp, archdata_start) ||
>>     (mp->archdata_end - mp->archdata_start) <=
>>      offsetof(struct archdata, dbe_table_end))
>> 	continue;
> Hmm, your suggested code checks if the passed struct is long enough for
>dbe_table_start only -- what about dbe_table_end?  The following code: 

If archdata_end-archdata_start <= offsetof(dbe_table_end) then archdata
is too small to contain the first byte of dbe_table_end, skip the
archdata.  If archdata is large enough to contain the first byte of
dbe_table_end, assume that it contains all of dbe_table_end.

>While modutils as released won't ever pass a smaller
>struct, someone may modify them or use another program to invoke
>init_module(), so we need to protect the kernel against bogus data. 

You have to be root to call init_module() or run insmod, root can do a
lot more damage than passing an invalid structure size.  This type of
test is not to catch malicious code, it is to detect that the user is
running an old modutils with a smaller archdata than the kernel can
handle.

You are correct that modutils as released will never pass a smaller
archdata struct for mips so strictly speaking this test is superfluous.
However this type of code gets cut and pasted so I want size checking
on all archdata, when it is copied the developer has to think about
changing the test instead of forgetting to add a test.

Your suggested code works just as well but is less readable.  Go with
either.

>> The rest of the code looks OK, except it needs a global change of
>> arch_init_module: to module_arch_init: to match the macro name.
>
> OK, I'll do it.  It should have been done for ia64 in the first place.
>Or should it be changed into "<arch>_init_module" to match functions' real
>names?

Leave it as module_arch_init, it tells us how the code was called.

>> Do you have the corresponding modutils patch or shall I do it? 
>
> I've send it to you separately just after the kernel patch.  Should I
>resend it? 

No thanks, I found it.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: bus error by write transaction (RE: [patch] linux 2.4.5: Make __dbe_table available to modules)
  2001-08-23 20:11             ` bus error by write transaction (RE: [patch] linux 2.4.5: Make __dbe_table available to modules) Hiroo Hayashi
  2001-08-23 20:11               ` Hiroo Hayashi
@ 2001-08-24 16:18               ` Maciej W. Rozycki
  2001-08-27 16:49                 ` Hiroo Hayashi
  1 sibling, 1 reply; 20+ messages in thread
From: Maciej W. Rozycki @ 2001-08-24 16:18 UTC (permalink / raw)
  To: Hiroo Hayashi; +Cc: linux-mips, linux-mips

On Thu, 23 Aug 2001, Hiroo Hayashi wrote:

> Note that most MIPS documents use word 'load' and 'store' for instruction,
> and 'read' and 'write' for bus transaction.  You have to distinguish them.

 Don't I?

> (Here I'm ignoring I/O access to make the point clear.)

 How do you define an I/O access for MIPS?

> The data on a write bus transaction may be a data modified by a store
> instruction which was issued some years ago :-)  What the OS can do?

 Report it and panic.  The problem with bus errors on MIPS is that one
can't distinguish between errors on reads and writes.  The former are
exact and are not fatal -- i.e. you can terminate if there is a guilty
process and try to continue; otherwise panic.  The latter are always fatal
as they are inexact and a panic is the most reasonable way to recover. 
With no way to distinguish between the two cases, it's hard to decide if
to go the strict way and panic in all cases or to hope a possible failing
write will not make the system inconsistent. 

  Maciej

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [patch] linux 2.4.5: __dbe_table iteration #2
  2001-08-24 15:44         ` Maciej W. Rozycki
@ 2001-08-27  3:09           ` Keith Owens
  2001-08-27  6:20             ` Ralf Baechle
  0 siblings, 1 reply; 20+ messages in thread
From: Keith Owens @ 2001-08-27  3:09 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: Ralf Baechle, linux-mips, linux-mips

On Fri, 24 Aug 2001 17:44:08 +0200 (MET DST), 
"Maciej W. Rozycki" <macro@ds2.pg.gda.pl> wrote:
> Ok, that's not much readable, indeed.  Thus I've invented a macro.  See
>a following patch hiding implementation details.

Patch looks good, please send it to Alan Cox.  2.4.8-ac12 introduced
another case of arch specific module data, this time for PPC.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [patch] linux 2.4.5: __dbe_table iteration #2
  2001-08-27  3:09           ` Keith Owens
@ 2001-08-27  6:20             ` Ralf Baechle
  0 siblings, 0 replies; 20+ messages in thread
From: Ralf Baechle @ 2001-08-27  6:20 UTC (permalink / raw)
  To: Keith Owens; +Cc: Maciej W. Rozycki, linux-mips, linux-mips

On Mon, Aug 27, 2001 at 01:09:08PM +1000, Keith Owens wrote:

> Patch looks good, please send it to Alan Cox.  2.4.8-ac12 introduced
> another case of arch specific module data, this time for PPC.

Maciej, jfyi - yesterday I've sent a large pile of patches to Alan so the
MIPS bits are already in.

  Ralf

^ permalink raw reply	[flat|nested] 20+ messages in thread

* RE: bus error by write transaction (RE: [patch] linux 2.4.5: Make __dbe_table available to modules)
  2001-08-24 16:18               ` Maciej W. Rozycki
@ 2001-08-27 16:49                 ` Hiroo Hayashi
  2001-08-27 16:49                   ` Hiroo Hayashi
  0 siblings, 1 reply; 20+ messages in thread
From: Hiroo Hayashi @ 2001-08-27 16:49 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: linux-mips, linux-mips

Hi,

> > Note that most MIPS documents use word 'load' and 'store' for instruction,
> > and 'read' and 'write' for bus transaction.  You have to distinguish them.
> 
>  Don't I?

I understood that (singular) you distinguish them.
I thought someone misunderstood in this thread.

> > (Here I'm ignoring I/O access to make the point clear.)
> 
>  How do you define an I/O access for MIPS?
uncached access.  Off cource there can be exception.

> > The data on a write bus transaction may be a data modified by a store
> > instruction which was issued some years ago :-)  What the OS can do?
> 
>  Report it and panic.

I agree with you.

>   The problem with bus errors on MIPS is that one
> can't distinguish between errors on reads and writes.

But I did not understand that there is MIPS CPU which cause Bus Error Exception
as a result of  a bus error for a write bus transaction or a read bus transaction
which caused by cache miss for a store instruction.  It's messy...

Hiroo

^ permalink raw reply	[flat|nested] 20+ messages in thread

* RE: bus error by write transaction (RE: [patch] linux 2.4.5: Make __dbe_table available to modules)
  2001-08-27 16:49                 ` Hiroo Hayashi
@ 2001-08-27 16:49                   ` Hiroo Hayashi
  0 siblings, 0 replies; 20+ messages in thread
From: Hiroo Hayashi @ 2001-08-27 16:49 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: linux-mips, linux-mips

Hi,

> > Note that most MIPS documents use word 'load' and 'store' for instruction,
> > and 'read' and 'write' for bus transaction.  You have to distinguish them.
> 
>  Don't I?

I understood that (singular) you distinguish them.
I thought someone misunderstood in this thread.

> > (Here I'm ignoring I/O access to make the point clear.)
> 
>  How do you define an I/O access for MIPS?
uncached access.  Off cource there can be exception.

> > The data on a write bus transaction may be a data modified by a store
> > instruction which was issued some years ago :-)  What the OS can do?
> 
>  Report it and panic.

I agree with you.

>   The problem with bus errors on MIPS is that one
> can't distinguish between errors on reads and writes.

But I did not understand that there is MIPS CPU which cause Bus Error Exception
as a result of  a bus error for a write bus transaction or a read bus transaction
which caused by cache miss for a store instruction.  It's messy...

Hiroo

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2001-08-27 16:51 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2001-08-13 13:38 [patch] linux 2.4.5: Make __dbe_table available to modules Maciej W. Rozycki
2001-08-13 15:50 ` Ralf Baechle
2001-08-13 16:24   ` Maciej W. Rozycki
2001-08-13 18:11     ` Gleb O. Raiko
2001-08-14 17:34       ` Maciej W. Rozycki
2001-08-23 11:23         ` Gleb O. Raiko
2001-08-23 15:46           ` Maciej W. Rozycki
2001-08-23 20:11             ` bus error by write transaction (RE: [patch] linux 2.4.5: Make __dbe_table available to modules) Hiroo Hayashi
2001-08-23 20:11               ` Hiroo Hayashi
2001-08-24 16:18               ` Maciej W. Rozycki
2001-08-27 16:49                 ` Hiroo Hayashi
2001-08-27 16:49                   ` Hiroo Hayashi
2001-08-20 13:57 ` [patch] linux 2.4.5: __dbe_table iteration #2 Maciej W. Rozycki
2001-08-23  1:49   ` Keith Owens
2001-08-23 16:52     ` Maciej W. Rozycki
2001-08-23 23:11       ` Keith Owens
2001-08-24 15:44         ` Maciej W. Rozycki
2001-08-27  3:09           ` Keith Owens
2001-08-27  6:20             ` Ralf Baechle
2001-08-24 15:49         ` Keith Owens

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox